|
32837
|
1255
|
24
|
2026-05-13T09:39:11.369632+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665151369_m2.jpg...
|
PhpStorm
|
faVsco.js – ActivityController.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.034242023,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
5252240045865077800
|
-8204424741936591930
|
visual_change
|
hybrid
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
PhostormProiectVIeWINavigareCodeLaravelKeractorJOOISWindowFV faVsco.js°9 master ~(C ActivityController.pnp|aravel.l0gA SF (jiminny@localhost]4 HS_local [jiminny@localhost]& console (PROD] X A console [EU]D Teaminsights, m Themesv D UserAutomatedRep -007final class ActivityController extends Controller implements CommentContextInterfaceA console [STAGING]v Dv2c) ACuviLyvzconuroAskAnythingCorLL0/() AskJiminnyRepc© DealsV2Controll 410%(C) OnDemandV2Cc€ PlavlistControlleC) PlavlistSharecorC PlavlistTrackCor111131114(C) UoloadControlleC) [EMAIL]) AiCrmNotesControl(c) Racecontroller nhn@ ClientTokenControl 1157(e) CrmController.pnp11158© DealLevelPromptsC 115$c) DealRiskcontroller.@ InctantMeetinaCont 11611164C) Languagecontrolle© LayoutManagemen 1163Ca) livoCoodControllor1164 9© MeetingsController 1192© MessageController. 1193 l >C) MotadntoControllor L214© MobileSettingsCont 1212 (g >© MomentController.r 125g1256 09>c) Nudgecontroller.phNumberAllocatorCc 12/e11271OraanizationMembi 1212C) OraanizationRetentC) OraanizationSvnce@ PartnerController.o1276 1g) PlavbackController1133480 PlavlictController pl 1335g ScimController.nhn9) SidekickController , 13379a) SoftnhoneControlle© SsoController.php() CnbccrintionGontrae ToamAiAutamation6) ToamAiContovtCar0 ToamContrallor nhr 1343 (Q9 >public function ListActivitySearch(Request Srequest, SearchTransformer SsearchTransformer): JsonResponses: 569— 571* Deletes a saved search— 573* @param Request $request* apanam Search $search575* achrows except1or* drecurn Jsonkesponse578579— 586pubLic tunccion deleteActivicysearch kequest srequest, search ssearch: Jsonkesponse.582oubunc tunction uivelrequest srequest, clastcactIvirvkedosirory srepostrory: usonkesponse....* dparam Activitu Sactivitu*Gthrows_AuthorizationExcent.zon589* Greturn mixedpublic function show(Activity Sactivity, ActivityService $activityService): JsonResponse{...}public function createRecording(Activity Sactivity)1...597593594public function updateRecording(Request Srequest, Activity $activity)i...h~ 596public function stopRecording(Activity Sactivity)(...}60€* Add activity to this user's favorites playlist_ 601=602* athrows AuthorizationException604public function favorite(Activitv Sactivitv. PlavlistActivitvRepository SolavlistActivitvRepositorv): J501605606=607* Remove activitu from this user's favorites plaulist60S•Goarom Actvatu sactvitu*athrowsAuthorizationExcent.ion* Greturn mixednublic function unfavorite Activity Sactivitv ?Tx: AutovCONCAT(u.id, CASE WHEN U.id = t.owner_id THEN ' (owner)' ELSE"' END) AS user_id,sa.*t.owner_id FROM social_accounts saNolN usens u on u.id e sa.sociabile idiJOIN teams t .n<->l: on t.id = u.team_icWHERE u.team_id = 581 and sa.provider = 'salesforce';SELECT * FROM automated_report_results order by id desc;select * from features;select * from team_features where feature_id = 40;select * from teams where id = 556:select * from automated_reports:where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044"pat", "podcast"]SELECT * FROM automated report results WHERE uuid to bin( '822fa41b-afd3-43a9-a248-86b0e36f3131') = vuid:select * from automated_report_results order by za desc;SELECT * FROM automated report resultsWHEKE 10 =144select * from automated report results WHERE report id = 54:select * from opportunities where 1d = 7594549ªSELE * FROM teams WHERE name LIKE "%Les%': # 711, 692. 16067 - Timinnvintearationdlesmils.comselect * from playbooks where team id = 711: # event 226147SELEd * FROM Davbook catedonies WHERE DLavbook 10 = 55151SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_typeSELECT * EROM eom fields WHERE 1d = 226147÷SELECT * EROM eom field values WHERE com field 1d = 226147.SELECT * FROM crm_configurations WHERE id = 692;SEISCTCONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE "' END) AS user_id,nemailiSa.xt.owner id FROM social accounts saJOIN users u on u.id = sa.sociable idJOIN teams t 1..n<->1: on t.id = u.team idWHERE U.team id = 711 and sa.provider = 'salesforce':SELECT * FROM crm profiles co JOIN users u 1..n<->1: on u.id = co.user id WHERE u.team_id = 711:select * from leads:select * from calendars:SELECTcascadeNew Cascade50 lihi7 # Support Daily - in 2h 21 m100% L2• Wed 13 May 12:39:11AskJiminnyReportActivityServiceTest v+0 ..So jiminny040 A1 A40 V 64 ^Cascade Code x .Kick off a new project. Make changes@, Event Serialization Requirement The user wants to determine if the SerializesModels trait is necessary in the Automat... 22hc Fixing Automated Report Job Failure Due to Missing PDF URI© Planhat Event Playback InvestigationAsk anvthina (84L)« Code SWF-1.6WN Windsurf Toams 1120-1UTF.8io 4 spaces...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
32838
|
1255
|
25
|
2026-05-13T09:39:22.047562+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665162047_m2.jpg...
|
PhpStorm
|
faVsco.js – ActivityController.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use Carbon\Carbon;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\In;
use Illuminate\Validation\ValidationException;
use InvalidArgumentException;
use Jiminny\Component\ActivityAnalytics;
use Jiminny\Component\ActivitySearch;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Queue\Constants;
use Jiminny\Contracts\ES\Events\UpdateSingleEntity;
use Jiminny\Contracts\ES\UpdateTargetEnum;
use Jiminny\Contracts\Nudge\NudgeFactoryInterface;
use Jiminny\Contracts\Playlist\PlaylistTrackFactoryInterface;
use Jiminny\Contracts\Repositories\PlaylistActivityRepository;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Enums\TeamSetting;
use Jiminny\Events\Activities\AiAutomation\ActivityProspectAdded;
use Jiminny\Events\Activities\Coaching\Coached;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Controllers\CommentContextInterface;
use Jiminny\Http\Responses\Api\AbstractResponse;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\ActivityCommentTransformer;
use Jiminny\Http\Transformers\ActivityTopicTriggerTransformer;
use Jiminny\Http\Transformers\ActivityTransformer;
use Jiminny\Http\Transformers\AvailabilityNotificationTransformer;
use Jiminny\Http\Transformers\CoachingFeedbackTransformer;
use Jiminny\Http\Transformers\CoachingSectionsTransformer;
use Jiminny\Http\Transformers\SearchTransformer;
use Jiminny\Http\Transformers\StatsTransformer;
use Jiminny\Jobs\Crm\SaveActivity;
use Jiminny\Jobs\Crm\UpdateStage;
use Jiminny\Jobs\Telephony\StartRecording;
use Jiminny\Jobs\Telephony\StopRecording;
use Jiminny\Jobs\Telephony\ToggleRecording;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\CoachingFeedback;
use Jiminny\Models\CoachingSection;
use Jiminny\Models\CoachingSectionCriterion;
use Jiminny\Models\CoachingSectionFeedback;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\LanguageDialect;
use Jiminny\Models\Lead;
use Jiminny\Models\Nudge;
use Jiminny\Models\PlaybookCategory;
use Jiminny\Models\Playlist;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\Track;
use Jiminny\Models\User;
use Jiminny\Repositories\CoachingFeedbackRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Rules\CrmReference;
use Jiminny\Rules\MultidimensionalArrayMaxCharRule;
use Jiminny\Services\ActivityService;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Services\PlaybackService;
use Jiminny\Services\UserService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
use Ramsey\Uuid\Uuid;
use Sentry;
use Symfony\Component\HttpFoundation;
final class ActivityController extends Controller implements CommentContextInterface
{
// Number of minutes to look back on activities. i.e. a timeout on activity duration.
private const int LOOK_BACK = 180;
public function __construct(
private ProviderRegistry $providerRegistry,
private ActivityService $activityService,
Response $response,
private UserService $userService,
private ActivitySearch\Service\ActivitySearch $activitySearch,
private NudgeFactoryInterface $nudgeFactory,
private ActivityCommentService $activityCommentService,
private LoggerInterface $logger,
private readonly CoachingFeedbackRepository $coachingFeedbackRepository,
private readonly TeamRepository $teamRepository,
) {
parent::__construct($response);
}
public static function getCommentImplementation(): string
{
return Comment::class;
}
public function delete()
{
$this->request->validate([
'*' => 'uuid:activities',
]);
$deletedIds = [];
foreach ($this->request->all() as $activityId) {
$activity = Activity::idOrUuId($activityId);
try {
if ($this->authorize('delete', $activity)) {
$activity->delete();
$deletedIds[] = $activityId;
\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);
}
} catch (AuthorizationException $authorizationException) {
// They didn't have permission.
}
}
return $this->response->withArray($deletedIds);
}
public function update(Request $request, Activity $activity)
{
$this->authorize('updateMetadata', $activity);
$request->validate([
'title' => 'string|max:250',
'category_id' => 'uuid:playbook_categories',
'language' => [
new In(
LanguageDialect::query()
->with('language')
->cursor()
->map(static function (LanguageDialect $languageDialect): string {
return $languageDialect->getLanguageLocale();
})
->all()
),
],
]);
if ($request->has('title')) {
$activity->title = $request->input('title');
}
if ($request->has('category_id')) {
$category = PlaybookCategory::uuid($request->input('category_id'));
if ($category->playbook->team_id !== $request->user()->team_id) {
return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
if ($request->has('language')) {
if (! $activity->isInProgress()) {
return $this->response->withError(
'Activity language can only be set while the meeting is in progress.',
400
);
}
$activity->setLanguageCode($request->input('language'));
}
$activity->save();
return $this->response->withOk();
}
// XXX: This should be merged with the update method.
/**
* @param Activity $activity
*
* @throws AuthorizationException
* @throws SocialAccountTokenInvalidException
*
* @return mixed
*/
public function summarize(Activity $activity): mixed
{
$this->logger->info('[Log Activity] Summarizing activity ', [
'activityId' => $activity->getUuid(),
'payload' => $this->request->all(),
]);
$this->authorize('update', $activity);
$this->logger->info('[Log Activity] Validating summary');
// Validate the payload.
$this->validateSummary($activity);
// All objects must belong to this team.
/** @var User $user */
$user = $this->request->user();
$team = $user->getTeam();
$crmService = $this->providerRegistry->get($team->crm->provider);
try {
$crmUser = $user;
if ($user->isCrmRequired() === false) {
$crmUser = $team->owner;
}
$crmService->setUser($crmUser);
} catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());
}
$rawEntities = $this->request->input('entities');
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid(
$this->request->input('layout_id')
);
// Delay execution of CRM jobs to avoid locking issues.
$jobDelay = 0;
// If we have arrived from a notification, mark it as read.
$notificationId = $this->request->input('nId');
if ($notificationId) {
$notification = $user->unreadNotifications->where('id', $notificationId)->first();
if ($notification) {
$notification->markAsRead();
}
}
$title = $this->request->input('title');
$prospects = $this->request->input('prospects');
$opportunityId = $this->request->input('opportunity_id');
$stageId = $this->request->input('stage_id');
$categoryId = $this->request->input('category_id');
$summary = $this->request->input('summary');
$crmProviderId = $this->request->input('crm_id');
$isInternal = $this->request->input('is_internal') ?? false;
$lead = null;
$category = null;
$account = null;
$contact = null;
$opportunity = null;
$stage = null;
$callStage = null;
foreach ($prospects as $prospectData) {
$objectId = $prospectData['id'];
if ($objectId === null) {
continue;
}
$objectType = $prospectData['type'];
$this->logger->info('debug', ['prospect_data' => $prospectData]);
try {
if ($objectType === null) {
$this->logger->info('no object type');
if ($crmService instanceof SupportsObjectTypeParseInterface) {
$objectType = $crmService->parseObjectType($objectId);
}
}
switch ($objectType) {
case 'lead':
$this->logger->info('Processing lead');
/** @var Lead|null $lead */
$lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();
// Lead does not exist locally, import it.
if ($lead === null) {
$this->logger->info('Lead does not exist locally');
/** @var Lead $lead */
$lead = $crmService->syncLead($objectId);
}
$this->logger->info('Lead found', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
if ($stageId === null) {
$this->logger->info('Stage ID is null');
// If it was not provided, just assume it is the current stage.
$callStage = $lead->stage;
break;
}
$this->logger->info('Looking for stage');
// Determine if they have changed the stage.
/** @var Stage $stage */
$stage = $team->crm->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_LEAD)
->firstOrFail();
$this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);
if ($lead->stage_id && $lead->stage_id !== $stage->id) {
$this->logger->info('Stage has changed');
// Storage current stage on activity.
$callStage = $lead->stage;
// The stage has changed, update in remote CRM.
dispatch(new UpdateStage($activity, $lead, $callStage, $stage));
$this->logger->info(
sprintf(
'[%s] User changing lead stage from %s to %s',
$crmService->getDisplayName(),
$callStage->getName(),
$stage->getName()
),
[
'user' => $user->getUuid(),
'lead' => $lead->getUuid(),
]
);
} else {
$this->logger->info('Stage has not changed');
// Stage remains as current.
$callStage = $stage;
}
break;
case 'account':
$this->logger->info('Processing account');
// If the object is not a lead, it should be an account.
$account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();
// Account does not exist locally, import it.
if ($account === null) {
$this->logger->info('Account does not exist locally');
$account = $crmService->syncAccount($objectId);
}
$this->logger->info('Account found', ['accountId' => $account->id]);
break;
case 'contact':
$this->logger->info('processing contact');
$contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$this->logger->info('contact does not exist locally');
$contact = $crmService->syncContact($objectId);
}
$this->logger->info('resolving account');
$account = $this->resolveAccount($team, $contact, $crmService, $prospects);
break;
}
// If they have specified an opportunity, retrieve this with stage.
if ($opportunityId) {
$this->logger->info('opportunity id is set');
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if ($opportunity === null) {
$this->logger->info('opportunity does not exist locally');
$opportunity = $crmService->syncOpportunity($opportunityId);
}
if ($stageId === null) {
$this->logger->info('stage id is null');
// If it was not provided, just assume it is the current stage.
$callStage = $opportunity->stage ?? null;
} else {
$this->logger->info('looking for stage');
/** @var ?Stage $opportunityStage */
$opportunityStage = $team->crm
->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
// There is a chance we still cannot import this opportunity.
if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {
$this->logger->info('opportunity stage has changed');
// Storage current stage on activity.
$callStage = $opportunity->stage;
dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));
$this->logger->info(
sprintf(
'[%s] User changing opportunity stage from %s to %s',
$crmService->getDisplayName(),
$callStage->name,
$opportunityStage->name
),
[
'userId' => $user->id_string,
'opportunityId' => $opportunity->id_string,
]
);
} else {
$this->logger->info('opportunity stage has not changed');
// Stage remains as current.
$callStage = $opportunityStage;
}
}
}
if ($crmProviderId) {
// Cast $crmProviderId to string otherwise it won't use database index for some records
$linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();
// Check if this activity has already been assigned to a different activity.
if ($linkedActivity && $linkedActivity->id !== $activity->id) {
throw new InvalidArgumentException(
'Sorry, the linked task has already been logged under a different call. '
. 'Please choose another linked task.'
);
}
}
} catch (InvalidArgumentException $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($exception->getMessage());
} catch (Exception $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorInternalError(
'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'
);
}
}
if ($categoryId) {
$category = PlaybookCategory::uuid($categoryId);
if ($category->playbook->team_id !== $team->id) {
throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
$this->logger->info('Prospect data', [
'lead_id' => $lead?->getId(),
'account_id' => $account?->getId(),
'contact_id' => $contact?->getId(),
'opportunity_id' => $opportunity?->getId(),
'stage_id' => $stage?->getId(),
]);
if ($title) {
$activity->title = $title;
}
if ($summary) {
$activity->summary = $summary;
}
if ($crmProviderId) {
$activity->crm_provider_id = $crmProviderId;
}
if ($callStage) {
$this->logger->info('Setting stage id', ['stageId' => $callStage->id]);
$activity->stage_id = $callStage->id;
}
if ($lead) {
$this->logger->info('Setting lead id', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
// If we are changed from an account > lead, unset the account data.
$this->logger->info('Unsetting account id, opportunity id, contact id, value');
$activity->account_id = null;
$activity->opportunity_id = null;
$activity->contact_id = null;
$activity->value = null;
}
if ($account) {
$this->logger->info('Setting account id', ['accountId' => $account->id]);
$activity->account_id = $account->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('unsetting lead id');
$activity->lead_id = null;
// Unset the contact if switching different accounts. Will be set up below if still applicable.
if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {
$this->logger->info('Unsetting contact id');
$activity->contact_id = null;
}
}
if ($opportunity) {
$this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);
$this->logger->info('unsetting lead id');
$activity->opportunity_id = $opportunity->id;
$activity->value = $opportunity->value;
// If we are changed from an lead > account, unset the lead data.
$activity->lead_id = null;
}
if ($contact) {
$this->logger->info('setting contact id', ['contactId' => $contact->id]);
$activity->contact_id = $contact->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('Unsetting lead id');
$activity->lead_id = null;
}
$activity->is_internal = $isInternal;
$activity->save();
$activity->refresh();
$this->logger->notice('Activity saved', [
'activity_id' => $activity->getId(),
'lead_id' => $activity->lead_id,
'account_id' => $activity->account_id,
'contact_id' => $activity->contact_id,
'opportunity_id' => $activity->opportunity_id,
'stage_id' => $activity->stage_id,
'crm_provider_id' => $activity->getCrmProviderId(),
]);
// Store entities as field data on the activity.
$updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);
if ($activity->isLoggable()) {
// Follow-up Task or Event data.
$followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);
$this->logger->info('CRM LOG manual log triggered', [
'activityId' => $activity->getUuid(),
'followupData' => $followupData,
'userId' => $user->getUuid(),
]);
// Store data in the CRM.
// ++add check for crm_required
$job = new SaveActivity($activity, $followupData);
if ($updatedData) {
$job->delay(Carbon::now()->addMinutes($jobDelay));
}
dispatch($job);
// Manually dispatch log for Opportunity or Prospect added
if ($activity->hasOpportunity() || $activity->hasProspect()) {
event(new ActivityProspectAdded(
activity: $activity,
eventSource: 'manually-log-crm-data'
));
}
}
return $this->response->withOk();
}
/**
* Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.
*
* @param ServiceInterface $service
* @param Activity $activity
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array
{
$updatedData = [];
$existingData = $activity->data()->get();
// We need to delete any existing data to overwrite with latest values.
$activity->data()->delete();
$layoutEntities = $layout->entities()
->with('field', 'parent')
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->get();
/** @var LayoutEntity $entity */
foreach ($layoutEntities as $entity) {
// If the user has provided a value for this entity
if (array_key_exists($entity->id_string, $entities)) {
$value = $entities[$entity->id_string];
// Convert raw data into values that the CRM can consume.
if ($value) {
$value = $service->normalizeValue($entity->field->type, $value);
}
// Check the field is part of the activity-summary section.
if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {
// This is the internal database ID, not the external CRM ID.
$objectId = null;
switch ($entity->field->object_type) {
case Field::OBJECT_ACCOUNT:
$objectId = $activity->account_id;
break;
case Field::OBJECT_CONTACT:
$objectId = $activity->contact_id;
break;
case Field::OBJECT_OPPORTUNITY:
$objectId = $activity->opportunity_id;
break;
case Field::OBJECT_LEAD:
$objectId = $activity->lead_id;
break;
case Field::OBJECT_TASK:
case Field::OBJECT_EVENT:
$objectId = $activity->id;
break;
}
if ($objectId) {
/** @var FieldData $data */
$data = $activity->data()->create([
'crm_layout_entity_id' => $entity->id,
'crm_field_id' => $entity->crm_field_id,
'object_type' => $entity->field->object_type,
'object_id' => $objectId,
'value' => $value,
]);
// Never send read-only field data to the CRM.
if ($entity->read_only === false && $entity->is_visible) {
$existingValue = $existingData
->where('crm_layout_entity_id', $entity->id)
->where('crm_field_id', $entity->crm_field_id)
->where('object_type', $entity->field->object_type)
->where('object_id', $objectId)
->first();
// If the field was actually changed, we need to reflect this in the CRM too.
if ($existingValue === null || $existingValue->value !== $value) {
$updatedData[] = $data->id;
}
}
}
}
}
}
return $updatedData;
}
/**
* Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.
*
* @param ServiceInterface $crmService
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array
{
$fieldData = [];
foreach ($entities as $entityId => $value) {
// Only bother with fields that have a value.
if ($value) {
// Extract the entity from the UUID. Check the field is valid and part of the follow-up section.
$entity = $layout->entities()
->uuid($entityId, false)
->whereHas('parent', function ($query) {
$query->where('label', 'follow-up');
})
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->first();
if ($entity) {
// Convert raw data into values that the CRM can consume.
$value = $crmService->normalizeValue($entity->field->type, $value);
// Add the field and value to the payload.
$fieldData += [
$entity->field->crm_provider_id => $value,
];
}
}
}
return $fieldData;
}
/**
* @param Activity $activity
*/
private function validateSummary(Activity $activity): void
{
$team = $activity->user->team;
$crmProvider = $team->crm->provider;
$attributes = [];
$rules = [
'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,
'title' => 'string|max:250',
'prospects' => 'required|array',
'opportunity_id' => new CrmReference($crmProvider),
'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',
'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator
'summary' => 'max:50000',
'nId' => 'exists:notifications,id',
'crm_id' => new CrmReference($crmProvider),
'entities' => 'array',
'is_internal' => 'boolean',
];
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));
// Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.
$entities = $layout->entities()
->where('read_only', 0)
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->whereHas('parent', function ($query) use ($activity) {
if ($activity->isLoggable() === false) {
$query->where('label', '<>', 'follow-up');
}
});
$isInternal = $this->request->input('is_internal', false);
foreach ($entities->get() as $entity) {
$rules += $this->buildFieldValidator($entity, $isInternal);
$attributes += $this->buildFieldMessage($entity);
}
$this->request->validate($rules, [], $attributes);
}
private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array
{
return [
'entities.' . $entity->id_string => $entity->getValidator($isInternal),
];
}
/**
* @param LayoutEntity $entity
*
* @return array
*/
private function buildFieldMessage(LayoutEntity $entity): array
{
$label = $entity->label;
if ($label === null) {
$label = $entity->field->label;
}
return [
'entities.' . $entity->id_string => $label,
];
}
public function search(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->debugLog(
$user,
'User extracted from request',
['user' => $user->getId(), 'tz' => $user->getTimezone()]
);
$searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());
$this->debugLog(
$user,
'ActivitySearch criteria built',
['searchCriteria' => $searchCriteria]
);
$filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);
$this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);
$this->validateSearch($request, $filterSet);
$this->debugLog($user, 'Request validated');
$searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);
/** @var Collection<Activity> $activities */
$activities = $searchResponse['results'];
$this->debugLog($user, 'Activities ES response extracted');
$hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(
$user->getTeamId(),
TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),
);
if ($hideInternalMeetingsSetting?->getValue() === '1') {
$activities = $activities->filter(function (Activity $activity) {
if ($activity->is_internal && empty($activity->actual_start_time)) {
return false;
}
return true;
});
}
$this->debugLog($user, 'Internal meetings (?!) filtered');
$this->response->getManager()
->parseIncludes([
'category',
'organizer.group',
'prospect',
'stage',
'opportunity',
'stats',
'scorecards',
'masterTrack',
'activeParticipants',
'notification',
])
->setSerializer(new JsonSerializer());
$transformerExcludes = $this->request->input('exclude');
if ($transformerExcludes) {
$this->response->getManager()->parseExcludes($transformerExcludes);
}
$this->debugLog($user, 'Response Manager (?!) applied');
$transformer = new ActivityTransformer();
$transformer->setConsumer($user);
$this->debugLog($user, 'Activity Transformer added');
$resource = new \League\Fractal\Resource\Collection($activities, $transformer);
$page = $searchCriteria->getPageNumber();
$this->debugLog($user, 'Search criteria page number called', ['page' => $page]);
$histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');
$this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);
return $this->response->withArray([
'pagination' => [
'total' => $searchResponse['totalHits'],
'current' => $page,
'prev' => max($page - 1, 1),
'next' => $page + 1,
],
'results' => $this->response->getManager()->createData($resource)->toArray(),
'histogram' => $histogram,
]);
}
private function debugLog(User $user, string $logMessage, ?array $context = []): void
{
// Debug for Learning People Only
if ($user->getTeamId() !== 260) {
return;
}
Log::notice(
sprintf('[activity-search-controller] %s', $logMessage),
$context
);
}
/** @throws ValidationException */
private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void
{
$rules = [
'exclude' => 'array',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
];
if ($prefix !== null && mb_strpos($prefix, '.') !== false) {
$rules[rtrim($prefix, '.')] = sprintf(
'required|array|max:%d',
$filterSet->count()
);
}
$validationRules = $filterSet->getValidationRules($prefix)
->merge($rules)
->all();
$request->validate($validationRules);
}
public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$search = $this->updateOrCreateActivitySearch($request);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function updateActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('update', $search);
$this->updateOrCreateActivitySearch($request, $search);
return $this->response->withOk();
}
private function storeNamedSearchFilters(
Collection $request,
Search $search,
FilterDefinitionCollection $filterSet,
?string $prefix = null,
): self {
$arrayTypeProperties = $filterSet
->getPropertyTypes([
FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,
])
->all();
$supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);
foreach ($supportedRequestProperties as $requestPropertyName) {
if (! array_has($request, $requestPropertyName)) {
continue;
}
/** @var string|string[] $propertyValue */
$propertyValue = array_get($request, $requestPropertyName);
$propertyName = $prefix === null
? $requestPropertyName
: mb_substr($requestPropertyName, mb_strlen($prefix));
$isArrayType = array_has($arrayTypeProperties, $propertyName);
if (! $isArrayType) {
/** @var string $requestPropertyValue */
$search->filters()->updateOrCreate(
[
'filter' => $propertyName,
],
[
'value' => $propertyValue,
]
);
continue;
}
/** @var string[] $requestPropertyValue */
/** @var SearchFilter[]|Collection $existingFilterValues */
$existingFilterValuesKeyed = $search->filters()
->where('filter', $propertyName)
->get()
->keyBy('id');
// Iterate over values provided as request parameters
foreach ($propertyValue as $value) {
/** @var SearchFilter|null $valueFilter */
$valueFilter = $search->filters()
->where(
[
'filter' => $propertyName,
'value' => $value,
]
)
->first();
if ($valueFilter !== null) {
// Remove filter value pair from list to be deleted
$existingFilterValuesKeyed->forget($valueFilter->id);
} else {
// Add new filter/value pair
$search->filters()->updateOrCreate([
'filter' => $propertyName,
'value' => $value,
]);
}
}
// Delete filter value pairs for this filter that no longer exist in request parameters
foreach ($existingFilterValuesKeyed as $existingFilter) {
$existingFilter->delete();
}
}
/** @var Collection<int, SearchFilter> $filtersKeyed */
$filtersKeyed = $search->filters()->get()->keyBy('filter');
// wipe removed filters from this search
foreach ($filtersKeyed as $filterName => $filter) {
if (array_has($request, $prefix . $filterName)) {
continue;
}
// Remove all filter values for this filter
$search->filters()->where('filter', $filterName)->delete();
}
return $this;
}
/**
* @throws AuthorizationException
*/
public function fetchActivitySearch(
Search $search,
Request $request,
SearchTransformer $searchTransformer,
): JsonResponse {
$this->authorize('view', $search);
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withCollection(
$user->searches()->get(),
$searchTransformer
->withConsumer($user)
);
}
/**
* Deletes a saved search
*
* @param Request $request
* @param Search $search
*
* @throws Exception
*
* @return JsonResponse
*/
public function deleteActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('delete', $search);
// Orphan any AutomatedReports that use this search
$search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);
// Delete filters and the search itself
$search->filters()->delete();
$search->delete();
return $this->response->withOk();
}
public function live(Request $request, ElasticActivityRepository $repository): JsonResponse
{
$user = $this->getUserFromRequest($request);
$this->request->validate([
'sort_direction' => 'in:asc,desc',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
]);
$activities = $repository->getLiveCoachingEligibleActivities(
user: $user,
lookBackMinutes: self::LOOK_BACK,
limit: (int) $this->request->input('limit', 25),
page: (int) $this->request->input('page', 1),
sortBy: ['actual_start_time', 'scheduled_start_time'],
sortDirection: (string) $this->request->input('sort_direction', 'asc'),
);
$this->response
->getManager()
->parseIncludes(['organizer.group', 'prospect'])
->setSerializer(new JsonSerializer());
return $this->response->withCollection($activities, new ActivityTransformer());
}
/**
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function show(Activity $activity, ActivityService $activityService): JsonResponse
{
$this->authorize('show', $activity);
$user = $activity->getUser();
$team = $user->getTeam();
// Sync the opportunity with the latest data if possible.
if ($activity->opportunity_id) {
try {
$crmService = $this->providerRegistry->get($team->crm->provider);
if (! $user->isCrmRequired()) {
$crmService->setUser($team->getOwner());
} else {
$crmService->setUser($user);
}
$crmService->syncOpportunity($activity->opportunity->crm_provider_id);
} catch (Exception $exception) {
// Move on.
}
}
$activityData = $activityService->getActivityData($this->request->user(), $activity);
return response()->json($activityData);
}
public function createRecording(Activity $activity)
{
$this->authorize('record', $activity);
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Tell Twilio to start recording this activity.
if ($activity->recording_state === Activity::RECORDING_OFF) {
$job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withCreated();
}
return $this->response->errorGone('Activity is already recording.');
}
public function updateRecording(Request $request, Activity $activity)
{
$this->authorize('record', $activity);
$request->validate([
'preference' => 'boolean',
'state' => [
'string',
Rule::in([
Activity::RECORDING_IN_PROGRESS,
Activity::RECORDING_PAUSED,
]),
],
]);
if ($request->has('state')) {
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Toggle the recording state between paused and resumed.
if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {
$job = (new ToggleRecording($activity, $request->input('state')))
->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Recording is not toggleable.');
}
if ($request->has('preference')) {
$activity->update([
'recording_preference' => $request->input('preference') ? 1 : 0,
]);
return $this->response->withOk();
}
return $this->response->errorWrongArgs('Something went wrong');
}
public function stopRecording(Activity $activity)
{
$this->authorize('stopRecord', $activity);
// Tell Twilio to stop recording this activity.
if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {
$job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Activity is not recording.');
}
/**
* Add activity to this user's favorites playlist
*
* @throws AuthorizationException
*/
public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse
{
$this->authorize('favorite', $activity);
$user = $this->getUserFromRequest($this->request);
$favorite = $activity->wasFavoritedBy($user);
$name = $activity->activity_title ?? '';
// It needs to check at least one record.
if (! $favorite) {
$favoritePlaylist = $user->favoritePlaylist();
$playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(
$activity,
$user,
$favoritePlaylist
);
if ($playlistActivity !== null) {
$playlistActivity->update(
// Just update, don't sort.
['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],
);
} else {
$playlistActivity = $activity->playlistActivities()->create([
'playlist_id' => $favoritePlaylist->getId(),
'user_id' => $user->getId(),
'start_time' => 0,
'name' => mb_strimwidth($name, 0, 100),
]);
// Sort it on top.
$playlistActivity->update(
[
'sort' => $playlistActivityRepository->calculateNewSortOrder(
null,
$playlistActivity,
),
],
);
}
$playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);
return new JsonResponse([], JsonResponse::HTTP_CREATED);
}
return new JsonResponse(
[
'error' => [
'code' => AbstractResponse::CODE_CONFLICT,
'http_code' => JsonResponse::HTTP_CONFLICT,
'message' => 'Resource Already Exists',
],
],
JsonResponse::HTTP_CONFLICT,
);
}
/**
* Remove activity from this user's favorites playlist
*
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function unfavorite(Activity $activity)
{
$user = $t...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.034242023,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Analyzing…","depth":4,"bounds":{"left":0.37200797,"top":0.07581804,"width":0.019946808,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.39361703,"top":0.074221864,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.40093085,"top":0.074221864,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Http\\Controllers\\API;\n\nuse Carbon\\Carbon;\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Exception;\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Validation\\Rule;\nuse Illuminate\\Validation\\Rules\\In;\nuse Illuminate\\Validation\\ValidationException;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ActivityAnalytics;\nuse Jiminny\\Component\\ActivitySearch;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Contracts\\ES\\Events\\UpdateSingleEntity;\nuse Jiminny\\Contracts\\ES\\UpdateTargetEnum;\nuse Jiminny\\Contracts\\Nudge\\NudgeFactoryInterface;\nuse Jiminny\\Contracts\\Playlist\\PlaylistTrackFactoryInterface;\nuse Jiminny\\Contracts\\Repositories\\PlaylistActivityRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Enums\\TeamSetting;\nuse Jiminny\\Events\\Activities\\AiAutomation\\ActivityProspectAdded;\nuse Jiminny\\Events\\Activities\\Coaching\\Coached;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Controllers\\CommentContextInterface;\nuse Jiminny\\Http\\Responses\\Api\\AbstractResponse;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\ActivityCommentTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTopicTriggerTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTransformer;\nuse Jiminny\\Http\\Transformers\\AvailabilityNotificationTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingFeedbackTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingSectionsTransformer;\nuse Jiminny\\Http\\Transformers\\SearchTransformer;\nuse Jiminny\\Http\\Transformers\\StatsTransformer;\nuse Jiminny\\Jobs\\Crm\\SaveActivity;\nuse Jiminny\\Jobs\\Crm\\UpdateStage;\nuse Jiminny\\Jobs\\Telephony\\StartRecording;\nuse Jiminny\\Jobs\\Telephony\\StopRecording;\nuse Jiminny\\Jobs\\Telephony\\ToggleRecording;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\CoachingFeedback;\nuse Jiminny\\Models\\CoachingSection;\nuse Jiminny\\Models\\CoachingSectionCriterion;\nuse Jiminny\\Models\\CoachingSectionFeedback;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\LanguageDialect;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Nudge;\nuse Jiminny\\Models\\PlaybookCategory;\nuse Jiminny\\Models\\Playlist;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\Track;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\CoachingFeedbackRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Rules\\MultidimensionalArrayMaxCharRule;\nuse Jiminny\\Services\\ActivityService;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Services\\PlaybackService;\nuse Jiminny\\Services\\UserService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\nuse Ramsey\\Uuid\\Uuid;\nuse Sentry;\nuse Symfony\\Component\\HttpFoundation;\n\nfinal class ActivityController extends Controller implements CommentContextInterface\n{\n // Number of minutes to look back on activities. i.e. a timeout on activity duration.\n private const int LOOK_BACK = 180;\n\n public function __construct(\n private ProviderRegistry $providerRegistry,\n private ActivityService $activityService,\n Response $response,\n private UserService $userService,\n private ActivitySearch\\Service\\ActivitySearch $activitySearch,\n private NudgeFactoryInterface $nudgeFactory,\n private ActivityCommentService $activityCommentService,\n private LoggerInterface $logger,\n private readonly CoachingFeedbackRepository $coachingFeedbackRepository,\n private readonly TeamRepository $teamRepository,\n ) {\n parent::__construct($response);\n }\n\n public static function getCommentImplementation(): string\n {\n return Comment::class;\n }\n\n public function delete()\n {\n $this->request->validate([\n '*' => 'uuid:activities',\n ]);\n\n $deletedIds = [];\n foreach ($this->request->all() as $activityId) {\n $activity = Activity::idOrUuId($activityId);\n\n try {\n if ($this->authorize('delete', $activity)) {\n $activity->delete();\n $deletedIds[] = $activityId;\n\n \\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n }\n } catch (AuthorizationException $authorizationException) {\n // They didn't have permission.\n }\n }\n\n return $this->response->withArray($deletedIds);\n }\n\n public function update(Request $request, Activity $activity)\n {\n $this->authorize('updateMetadata', $activity);\n\n $request->validate([\n 'title' => 'string|max:250',\n 'category_id' => 'uuid:playbook_categories',\n 'language' => [\n new In(\n LanguageDialect::query()\n ->with('language')\n ->cursor()\n ->map(static function (LanguageDialect $languageDialect): string {\n return $languageDialect->getLanguageLocale();\n })\n ->all()\n ),\n ],\n ]);\n\n if ($request->has('title')) {\n $activity->title = $request->input('title');\n }\n\n if ($request->has('category_id')) {\n $category = PlaybookCategory::uuid($request->input('category_id'));\n\n if ($category->playbook->team_id !== $request->user()->team_id) {\n return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n if ($request->has('language')) {\n if (! $activity->isInProgress()) {\n return $this->response->withError(\n 'Activity language can only be set while the meeting is in progress.',\n 400\n );\n }\n\n $activity->setLanguageCode($request->input('language'));\n }\n\n $activity->save();\n\n return $this->response->withOk();\n }\n\n // XXX: This should be merged with the update method.\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws SocialAccountTokenInvalidException\n *\n * @return mixed\n */\n public function summarize(Activity $activity): mixed\n {\n $this->logger->info('[Log Activity] Summarizing activity ', [\n 'activityId' => $activity->getUuid(),\n 'payload' => $this->request->all(),\n ]);\n $this->authorize('update', $activity);\n\n $this->logger->info('[Log Activity] Validating summary');\n // Validate the payload.\n $this->validateSummary($activity);\n\n // All objects must belong to this team.\n /** @var User $user */\n $user = $this->request->user();\n $team = $user->getTeam();\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n try {\n $crmUser = $user;\n if ($user->isCrmRequired() === false) {\n $crmUser = $team->owner;\n }\n $crmService->setUser($crmUser);\n } catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());\n }\n\n $rawEntities = $this->request->input('entities');\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid(\n $this->request->input('layout_id')\n );\n\n // Delay execution of CRM jobs to avoid locking issues.\n $jobDelay = 0;\n\n // If we have arrived from a notification, mark it as read.\n $notificationId = $this->request->input('nId');\n if ($notificationId) {\n $notification = $user->unreadNotifications->where('id', $notificationId)->first();\n\n if ($notification) {\n $notification->markAsRead();\n }\n }\n\n $title = $this->request->input('title');\n $prospects = $this->request->input('prospects');\n $opportunityId = $this->request->input('opportunity_id');\n $stageId = $this->request->input('stage_id');\n $categoryId = $this->request->input('category_id');\n $summary = $this->request->input('summary');\n $crmProviderId = $this->request->input('crm_id');\n $isInternal = $this->request->input('is_internal') ?? false;\n\n $lead = null;\n $category = null;\n $account = null;\n $contact = null;\n $opportunity = null;\n $stage = null;\n $callStage = null;\n\n foreach ($prospects as $prospectData) {\n $objectId = $prospectData['id'];\n\n if ($objectId === null) {\n continue;\n }\n\n $objectType = $prospectData['type'];\n $this->logger->info('debug', ['prospect_data' => $prospectData]);\n\n try {\n if ($objectType === null) {\n $this->logger->info('no object type');\n if ($crmService instanceof SupportsObjectTypeParseInterface) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n }\n\n switch ($objectType) {\n case 'lead':\n $this->logger->info('Processing lead');\n /** @var Lead|null $lead */\n $lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();\n\n // Lead does not exist locally, import it.\n if ($lead === null) {\n $this->logger->info('Lead does not exist locally');\n /** @var Lead $lead */\n $lead = $crmService->syncLead($objectId);\n }\n\n $this->logger->info('Lead found', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n if ($stageId === null) {\n $this->logger->info('Stage ID is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $lead->stage;\n\n break;\n }\n\n $this->logger->info('Looking for stage');\n // Determine if they have changed the stage.\n /** @var Stage $stage */\n $stage = $team->crm->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_LEAD)\n ->firstOrFail();\n\n $this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);\n if ($lead->stage_id && $lead->stage_id !== $stage->id) {\n $this->logger->info('Stage has changed');\n // Storage current stage on activity.\n $callStage = $lead->stage;\n\n // The stage has changed, update in remote CRM.\n dispatch(new UpdateStage($activity, $lead, $callStage, $stage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing lead stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->getName(),\n $stage->getName()\n ),\n [\n 'user' => $user->getUuid(),\n 'lead' => $lead->getUuid(),\n ]\n );\n } else {\n $this->logger->info('Stage has not changed');\n // Stage remains as current.\n $callStage = $stage;\n }\n\n break;\n\n case 'account':\n $this->logger->info('Processing account');\n // If the object is not a lead, it should be an account.\n $account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();\n\n // Account does not exist locally, import it.\n if ($account === null) {\n $this->logger->info('Account does not exist locally');\n $account = $crmService->syncAccount($objectId);\n }\n\n $this->logger->info('Account found', ['accountId' => $account->id]);\n\n break;\n case 'contact':\n $this->logger->info('processing contact');\n $contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $this->logger->info('contact does not exist locally');\n $contact = $crmService->syncContact($objectId);\n }\n\n $this->logger->info('resolving account');\n $account = $this->resolveAccount($team, $contact, $crmService, $prospects);\n\n break;\n }\n\n // If they have specified an opportunity, retrieve this with stage.\n if ($opportunityId) {\n $this->logger->info('opportunity id is set');\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if ($opportunity === null) {\n $this->logger->info('opportunity does not exist locally');\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n if ($stageId === null) {\n $this->logger->info('stage id is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $opportunity->stage ?? null;\n } else {\n $this->logger->info('looking for stage');\n /** @var ?Stage $opportunityStage */\n $opportunityStage = $team->crm\n ->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n // There is a chance we still cannot import this opportunity.\n if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {\n $this->logger->info('opportunity stage has changed');\n // Storage current stage on activity.\n $callStage = $opportunity->stage;\n\n dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing opportunity stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->name,\n $opportunityStage->name\n ),\n [\n 'userId' => $user->id_string,\n 'opportunityId' => $opportunity->id_string,\n ]\n );\n } else {\n $this->logger->info('opportunity stage has not changed');\n // Stage remains as current.\n $callStage = $opportunityStage;\n }\n }\n }\n\n if ($crmProviderId) {\n // Cast $crmProviderId to string otherwise it won't use database index for some records\n $linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();\n\n // Check if this activity has already been assigned to a different activity.\n if ($linkedActivity && $linkedActivity->id !== $activity->id) {\n throw new InvalidArgumentException(\n 'Sorry, the linked task has already been logged under a different call. '\n . 'Please choose another linked task.'\n );\n }\n }\n } catch (InvalidArgumentException $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($exception->getMessage());\n } catch (Exception $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorInternalError(\n 'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'\n );\n }\n }\n\n if ($categoryId) {\n $category = PlaybookCategory::uuid($categoryId);\n\n if ($category->playbook->team_id !== $team->id) {\n throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n $this->logger->info('Prospect data', [\n 'lead_id' => $lead?->getId(),\n 'account_id' => $account?->getId(),\n 'contact_id' => $contact?->getId(),\n 'opportunity_id' => $opportunity?->getId(),\n 'stage_id' => $stage?->getId(),\n ]);\n\n if ($title) {\n $activity->title = $title;\n }\n\n if ($summary) {\n $activity->summary = $summary;\n }\n\n if ($crmProviderId) {\n $activity->crm_provider_id = $crmProviderId;\n }\n\n if ($callStage) {\n $this->logger->info('Setting stage id', ['stageId' => $callStage->id]);\n $activity->stage_id = $callStage->id;\n }\n\n if ($lead) {\n $this->logger->info('Setting lead id', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n // If we are changed from an account > lead, unset the account data.\n $this->logger->info('Unsetting account id, opportunity id, contact id, value');\n $activity->account_id = null;\n $activity->opportunity_id = null;\n $activity->contact_id = null;\n $activity->value = null;\n }\n\n if ($account) {\n $this->logger->info('Setting account id', ['accountId' => $account->id]);\n $activity->account_id = $account->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('unsetting lead id');\n $activity->lead_id = null;\n\n // Unset the contact if switching different accounts. Will be set up below if still applicable.\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {\n $this->logger->info('Unsetting contact id');\n $activity->contact_id = null;\n }\n }\n\n if ($opportunity) {\n $this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);\n $this->logger->info('unsetting lead id');\n $activity->opportunity_id = $opportunity->id;\n $activity->value = $opportunity->value;\n\n // If we are changed from an lead > account, unset the lead data.\n $activity->lead_id = null;\n }\n\n if ($contact) {\n $this->logger->info('setting contact id', ['contactId' => $contact->id]);\n $activity->contact_id = $contact->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('Unsetting lead id');\n $activity->lead_id = null;\n }\n\n $activity->is_internal = $isInternal;\n $activity->save();\n $activity->refresh();\n\n $this->logger->notice('Activity saved', [\n 'activity_id' => $activity->getId(),\n 'lead_id' => $activity->lead_id,\n 'account_id' => $activity->account_id,\n 'contact_id' => $activity->contact_id,\n 'opportunity_id' => $activity->opportunity_id,\n 'stage_id' => $activity->stage_id,\n 'crm_provider_id' => $activity->getCrmProviderId(),\n ]);\n\n // Store entities as field data on the activity.\n $updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);\n\n if ($activity->isLoggable()) {\n // Follow-up Task or Event data.\n $followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);\n\n $this->logger->info('CRM LOG manual log triggered', [\n 'activityId' => $activity->getUuid(),\n 'followupData' => $followupData,\n 'userId' => $user->getUuid(),\n ]);\n\n // Store data in the CRM.\n // ++add check for crm_required\n $job = new SaveActivity($activity, $followupData);\n\n if ($updatedData) {\n $job->delay(Carbon::now()->addMinutes($jobDelay));\n }\n\n dispatch($job);\n\n // Manually dispatch log for Opportunity or Prospect added\n if ($activity->hasOpportunity() || $activity->hasProspect()) {\n event(new ActivityProspectAdded(\n activity: $activity,\n eventSource: 'manually-log-crm-data'\n ));\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.\n *\n * @param ServiceInterface $service\n * @param Activity $activity\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array\n {\n $updatedData = [];\n $existingData = $activity->data()->get();\n\n // We need to delete any existing data to overwrite with latest values.\n $activity->data()->delete();\n\n $layoutEntities = $layout->entities()\n ->with('field', 'parent')\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->get();\n\n /** @var LayoutEntity $entity */\n foreach ($layoutEntities as $entity) {\n // If the user has provided a value for this entity\n if (array_key_exists($entity->id_string, $entities)) {\n $value = $entities[$entity->id_string];\n\n // Convert raw data into values that the CRM can consume.\n if ($value) {\n $value = $service->normalizeValue($entity->field->type, $value);\n }\n\n // Check the field is part of the activity-summary section.\n if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {\n // This is the internal database ID, not the external CRM ID.\n $objectId = null;\n\n switch ($entity->field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $objectId = $activity->account_id;\n\n break;\n\n case Field::OBJECT_CONTACT:\n $objectId = $activity->contact_id;\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n $objectId = $activity->opportunity_id;\n\n break;\n\n case Field::OBJECT_LEAD:\n $objectId = $activity->lead_id;\n\n break;\n\n case Field::OBJECT_TASK:\n case Field::OBJECT_EVENT:\n $objectId = $activity->id;\n\n break;\n }\n\n if ($objectId) {\n /** @var FieldData $data */\n $data = $activity->data()->create([\n 'crm_layout_entity_id' => $entity->id,\n 'crm_field_id' => $entity->crm_field_id,\n 'object_type' => $entity->field->object_type,\n 'object_id' => $objectId,\n 'value' => $value,\n ]);\n\n // Never send read-only field data to the CRM.\n if ($entity->read_only === false && $entity->is_visible) {\n $existingValue = $existingData\n ->where('crm_layout_entity_id', $entity->id)\n ->where('crm_field_id', $entity->crm_field_id)\n ->where('object_type', $entity->field->object_type)\n ->where('object_id', $objectId)\n ->first();\n\n // If the field was actually changed, we need to reflect this in the CRM too.\n if ($existingValue === null || $existingValue->value !== $value) {\n $updatedData[] = $data->id;\n }\n }\n }\n }\n }\n }\n\n return $updatedData;\n }\n\n /**\n * Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.\n *\n * @param ServiceInterface $crmService\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array\n {\n $fieldData = [];\n foreach ($entities as $entityId => $value) {\n // Only bother with fields that have a value.\n if ($value) {\n // Extract the entity from the UUID. Check the field is valid and part of the follow-up section.\n $entity = $layout->entities()\n ->uuid($entityId, false)\n ->whereHas('parent', function ($query) {\n $query->where('label', 'follow-up');\n })\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->first();\n\n if ($entity) {\n // Convert raw data into values that the CRM can consume.\n $value = $crmService->normalizeValue($entity->field->type, $value);\n\n // Add the field and value to the payload.\n $fieldData += [\n $entity->field->crm_provider_id => $value,\n ];\n }\n }\n }\n\n return $fieldData;\n }\n\n /**\n * @param Activity $activity\n */\n private function validateSummary(Activity $activity): void\n {\n $team = $activity->user->team;\n $crmProvider = $team->crm->provider;\n $attributes = [];\n\n $rules = [\n 'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,\n 'title' => 'string|max:250',\n 'prospects' => 'required|array',\n 'opportunity_id' => new CrmReference($crmProvider),\n 'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',\n 'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator\n 'summary' => 'max:50000',\n 'nId' => 'exists:notifications,id',\n 'crm_id' => new CrmReference($crmProvider),\n 'entities' => 'array',\n 'is_internal' => 'boolean',\n ];\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));\n\n // Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.\n $entities = $layout->entities()\n ->where('read_only', 0)\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->whereHas('parent', function ($query) use ($activity) {\n if ($activity->isLoggable() === false) {\n $query->where('label', '<>', 'follow-up');\n }\n });\n\n $isInternal = $this->request->input('is_internal', false);\n\n foreach ($entities->get() as $entity) {\n $rules += $this->buildFieldValidator($entity, $isInternal);\n $attributes += $this->buildFieldMessage($entity);\n }\n\n $this->request->validate($rules, [], $attributes);\n }\n\n private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array\n {\n return [\n 'entities.' . $entity->id_string => $entity->getValidator($isInternal),\n ];\n }\n\n /**\n * @param LayoutEntity $entity\n *\n * @return array\n */\n private function buildFieldMessage(LayoutEntity $entity): array\n {\n $label = $entity->label;\n if ($label === null) {\n $label = $entity->field->label;\n }\n\n return [\n 'entities.' . $entity->id_string => $label,\n ];\n }\n\n public function search(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->debugLog(\n $user,\n 'User extracted from request',\n ['user' => $user->getId(), 'tz' => $user->getTimezone()]\n );\n\n $searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());\n\n $this->debugLog(\n $user,\n 'ActivitySearch criteria built',\n ['searchCriteria' => $searchCriteria]\n );\n\n $filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);\n\n $this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);\n\n $this->validateSearch($request, $filterSet);\n\n $this->debugLog($user, 'Request validated');\n\n $searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);\n\n /** @var Collection<Activity> $activities */\n $activities = $searchResponse['results'];\n\n $this->debugLog($user, 'Activities ES response extracted');\n\n $hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(\n $user->getTeamId(),\n TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),\n );\n\n if ($hideInternalMeetingsSetting?->getValue() === '1') {\n $activities = $activities->filter(function (Activity $activity) {\n if ($activity->is_internal && empty($activity->actual_start_time)) {\n return false;\n }\n\n return true;\n });\n }\n\n $this->debugLog($user, 'Internal meetings (?!) filtered');\n\n $this->response->getManager()\n ->parseIncludes([\n 'category',\n 'organizer.group',\n 'prospect',\n 'stage',\n 'opportunity',\n 'stats',\n 'scorecards',\n 'masterTrack',\n 'activeParticipants',\n 'notification',\n ])\n ->setSerializer(new JsonSerializer());\n\n $transformerExcludes = $this->request->input('exclude');\n if ($transformerExcludes) {\n $this->response->getManager()->parseExcludes($transformerExcludes);\n }\n\n $this->debugLog($user, 'Response Manager (?!) applied');\n\n $transformer = new ActivityTransformer();\n $transformer->setConsumer($user);\n\n $this->debugLog($user, 'Activity Transformer added');\n\n $resource = new \\League\\Fractal\\Resource\\Collection($activities, $transformer);\n $page = $searchCriteria->getPageNumber();\n\n $this->debugLog($user, 'Search criteria page number called', ['page' => $page]);\n\n $histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');\n\n $this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);\n\n return $this->response->withArray([\n 'pagination' => [\n 'total' => $searchResponse['totalHits'],\n 'current' => $page,\n 'prev' => max($page - 1, 1),\n 'next' => $page + 1,\n ],\n 'results' => $this->response->getManager()->createData($resource)->toArray(),\n 'histogram' => $histogram,\n ]);\n }\n\n private function debugLog(User $user, string $logMessage, ?array $context = []): void\n {\n // Debug for Learning People Only\n if ($user->getTeamId() !== 260) {\n return;\n }\n\n Log::notice(\n sprintf('[activity-search-controller] %s', $logMessage),\n $context\n );\n }\n\n /** @throws ValidationException */\n private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void\n {\n $rules = [\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ];\n\n if ($prefix !== null && mb_strpos($prefix, '.') !== false) {\n $rules[rtrim($prefix, '.')] = sprintf(\n 'required|array|max:%d',\n $filterSet->count()\n );\n }\n\n $validationRules = $filterSet->getValidationRules($prefix)\n ->merge($rules)\n ->all();\n\n $request->validate($validationRules);\n }\n\n public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $search = $this->updateOrCreateActivitySearch($request);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function updateActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('update', $search);\n\n $this->updateOrCreateActivitySearch($request, $search);\n\n return $this->response->withOk();\n }\n\n private function storeNamedSearchFilters(\n Collection $request,\n Search $search,\n FilterDefinitionCollection $filterSet,\n ?string $prefix = null,\n ): self {\n $arrayTypeProperties = $filterSet\n ->getPropertyTypes([\n FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,\n ])\n ->all();\n\n $supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);\n\n foreach ($supportedRequestProperties as $requestPropertyName) {\n if (! array_has($request, $requestPropertyName)) {\n continue;\n }\n\n /** @var string|string[] $propertyValue */\n $propertyValue = array_get($request, $requestPropertyName);\n $propertyName = $prefix === null\n ? $requestPropertyName\n : mb_substr($requestPropertyName, mb_strlen($prefix));\n\n $isArrayType = array_has($arrayTypeProperties, $propertyName);\n\n if (! $isArrayType) {\n /** @var string $requestPropertyValue */\n\n $search->filters()->updateOrCreate(\n [\n 'filter' => $propertyName,\n ],\n [\n 'value' => $propertyValue,\n ]\n );\n\n continue;\n }\n\n /** @var string[] $requestPropertyValue */\n\n /** @var SearchFilter[]|Collection $existingFilterValues */\n $existingFilterValuesKeyed = $search->filters()\n ->where('filter', $propertyName)\n ->get()\n ->keyBy('id');\n\n // Iterate over values provided as request parameters\n foreach ($propertyValue as $value) {\n /** @var SearchFilter|null $valueFilter */\n $valueFilter = $search->filters()\n ->where(\n [\n 'filter' => $propertyName,\n 'value' => $value,\n ]\n )\n ->first();\n\n if ($valueFilter !== null) {\n // Remove filter value pair from list to be deleted\n $existingFilterValuesKeyed->forget($valueFilter->id);\n } else {\n // Add new filter/value pair\n $search->filters()->updateOrCreate([\n 'filter' => $propertyName,\n 'value' => $value,\n ]);\n }\n }\n\n // Delete filter value pairs for this filter that no longer exist in request parameters\n foreach ($existingFilterValuesKeyed as $existingFilter) {\n $existingFilter->delete();\n }\n }\n\n /** @var Collection<int, SearchFilter> $filtersKeyed */\n $filtersKeyed = $search->filters()->get()->keyBy('filter');\n\n // wipe removed filters from this search\n foreach ($filtersKeyed as $filterName => $filter) {\n if (array_has($request, $prefix . $filterName)) {\n continue;\n }\n\n // Remove all filter values for this filter\n $search->filters()->where('filter', $filterName)->delete();\n }\n\n return $this;\n }\n\n /**\n * @throws AuthorizationException\n */\n public function fetchActivitySearch(\n Search $search,\n Request $request,\n SearchTransformer $searchTransformer,\n ): JsonResponse {\n $this->authorize('view', $search);\n\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection(\n $user->searches()->get(),\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n /**\n * Deletes a saved search\n *\n * @param Request $request\n * @param Search $search\n *\n * @throws Exception\n *\n * @return JsonResponse\n */\n public function deleteActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('delete', $search);\n\n // Orphan any AutomatedReports that use this search\n $search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);\n\n // Delete filters and the search itself\n $search->filters()->delete();\n $search->delete();\n\n return $this->response->withOk();\n }\n\n public function live(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n $user = $this->getUserFromRequest($request);\n\n $this->request->validate([\n 'sort_direction' => 'in:asc,desc',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ]);\n\n $activities = $repository->getLiveCoachingEligibleActivities(\n user: $user,\n lookBackMinutes: self::LOOK_BACK,\n limit: (int) $this->request->input('limit', 25),\n page: (int) $this->request->input('page', 1),\n sortBy: ['actual_start_time', 'scheduled_start_time'],\n sortDirection: (string) $this->request->input('sort_direction', 'asc'),\n );\n\n $this->response\n ->getManager()\n ->parseIncludes(['organizer.group', 'prospect'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($activities, new ActivityTransformer());\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function show(Activity $activity, ActivityService $activityService): JsonResponse\n {\n $this->authorize('show', $activity);\n\n $user = $activity->getUser();\n $team = $user->getTeam();\n\n // Sync the opportunity with the latest data if possible.\n if ($activity->opportunity_id) {\n try {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n if (! $user->isCrmRequired()) {\n $crmService->setUser($team->getOwner());\n } else {\n $crmService->setUser($user);\n }\n\n $crmService->syncOpportunity($activity->opportunity->crm_provider_id);\n } catch (Exception $exception) {\n // Move on.\n }\n }\n\n $activityData = $activityService->getActivityData($this->request->user(), $activity);\n\n return response()->json($activityData);\n }\n\n public function createRecording(Activity $activity)\n {\n $this->authorize('record', $activity);\n\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Tell Twilio to start recording this activity.\n if ($activity->recording_state === Activity::RECORDING_OFF) {\n $job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withCreated();\n }\n\n return $this->response->errorGone('Activity is already recording.');\n }\n\n public function updateRecording(Request $request, Activity $activity)\n {\n $this->authorize('record', $activity);\n\n $request->validate([\n 'preference' => 'boolean',\n 'state' => [\n 'string',\n Rule::in([\n Activity::RECORDING_IN_PROGRESS,\n Activity::RECORDING_PAUSED,\n ]),\n ],\n ]);\n\n if ($request->has('state')) {\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Toggle the recording state between paused and resumed.\n if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {\n $job = (new ToggleRecording($activity, $request->input('state')))\n ->onQueue(Constants::QUEUE_CONFERENCES);\n\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Recording is not toggleable.');\n }\n\n if ($request->has('preference')) {\n $activity->update([\n 'recording_preference' => $request->input('preference') ? 1 : 0,\n ]);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorWrongArgs('Something went wrong');\n }\n\n public function stopRecording(Activity $activity)\n {\n $this->authorize('stopRecord', $activity);\n\n // Tell Twilio to stop recording this activity.\n if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {\n $job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Activity is not recording.');\n }\n\n /**\n * Add activity to this user's favorites playlist\n *\n * @throws AuthorizationException\n */\n public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse\n {\n $this->authorize('favorite', $activity);\n\n $user = $this->getUserFromRequest($this->request);\n $favorite = $activity->wasFavoritedBy($user);\n $name = $activity->activity_title ?? '';\n\n // It needs to check at least one record.\n if (! $favorite) {\n $favoritePlaylist = $user->favoritePlaylist();\n\n $playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(\n $activity,\n $user,\n $favoritePlaylist\n );\n\n if ($playlistActivity !== null) {\n $playlistActivity->update(\n // Just update, don't sort.\n ['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],\n );\n } else {\n $playlistActivity = $activity->playlistActivities()->create([\n 'playlist_id' => $favoritePlaylist->getId(),\n 'user_id' => $user->getId(),\n 'start_time' => 0,\n 'name' => mb_strimwidth($name, 0, 100),\n ]);\n // Sort it on top.\n $playlistActivity->update(\n [\n 'sort' => $playlistActivityRepository->calculateNewSortOrder(\n null,\n $playlistActivity,\n ),\n ],\n );\n }\n\n $playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);\n\n return new JsonResponse([], JsonResponse::HTTP_CREATED);\n }\n\n return new JsonResponse(\n [\n 'error' => [\n 'code' => AbstractResponse::CODE_CONFLICT,\n 'http_code' => JsonResponse::HTTP_CONFLICT,\n 'message' => 'Resource Already Exists',\n ],\n ],\n JsonResponse::HTTP_CONFLICT,\n );\n }\n\n /**\n * Remove activity from this user's favorites playlist\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unfavorite(Activity $activity)\n {\n $user = $this->request->user();\n\n $favorites = $activity->favoritedBy($user);\n\n if ($favorites && $favorites->isEmpty()) {\n return $this->response->errorNotFound('Favorite not found.');\n }\n\n $this->authorize('unfavorite', [$activity, $favorites]);\n\n // When you unfavorite an activity,\n // it should remove all the activities in it, including snippets.\n $isDeleted = $favorites->each(function ($favorite) {\n $favorite->forceDelete();\n });\n\n if ($isDeleted) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not remove favorite.');\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function notify(Activity $activity)\n {\n $this->authorize('notify', $activity);\n\n $user = $this->request->user();\n\n $existingNotification = $activity->availabilityNotifications()\n ->where('user_id', $user->id)\n ->exists();\n\n if ($existingNotification) {\n return $this->response->errorWrongArgs('Notification is already configured.');\n }\n\n $notification = Activity\\AvailabilityNotification::create([\n 'user_id' => $user->id,\n 'activity_id' => $activity->id,\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($notification, new AvailabilityNotificationTransformer());\n }\n\n /**\n * @param Activity $activity\n * @param Activity\\AvailabilityNotification $notification\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unnotify(Activity $activity, Activity\\AvailabilityNotification $notification)\n {\n $this->authorize('unnotify', [$activity, $notification]);\n\n if ($notification->sent_at || $notification->delete()) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not delete notification.');\n }\n\n public function play(Request $request, Activity $activity)\n {\n $this->authorize('stream', $activity);\n\n $request->validate([\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $activity->plays()->create([\n 'user_id' => $user->getId(),\n 'start_time' => $request->input('start_time'),\n ]);\n\n return $this->response->withCreated();\n }\n\n /**\n * @param Activity $activity\n *\n * @return mixed\n */\n public function comment(Activity $activity)\n {\n return $this->newComment($activity);\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @return mixed\n */\n public function replyComment(Activity $activity, Comment $comment)\n {\n return $this->newComment($activity, $comment);\n }\n\n /**\n * @param Activity $activity\n * @param Comment|null $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n protected function newComment(Activity $activity, ?Comment $comment = null)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n 'type' => 'integer|between:0,3',\n 'visibility' => sprintf('nullable|integer|between:1,%d', count(Comment::getVisibilityLevels())),\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n $threadStartId = null;\n if ($comment) {\n $threadStartId = $comment->thread_start_id ?: $comment->id;\n }\n\n try {\n $newComment = Comment::create([\n 'parent_comment_id' => $comment->id ?? null,\n 'thread_start_id' => $threadStartId,\n 'activity_id' => $activity->id,\n 'user_id' => $this->request->user()->id,\n 'comment' => trim($this->request->input('comment')),\n 'start_time' => $this->request->input('start_time', 0),\n 'end_time' => $this->request->input('end_time', 0),\n 'type' => $this->request->input('type', Comment::TYPE_NEUTRAL),\n 'visibility' => $this->request->input('visibility', Comment::VISIBILITY_PUBLIC),\n ]);\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($newComment, new ActivityCommentTransformer());\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not create comment.' . $exception->getMessage());\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function updateComment(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n try {\n $comment->update([\n 'comment' => trim($this->request->input('comment')),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment.');\n }\n }\n\n public function updateCommentVisibility(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'visibility' => sprintf('integer|between:1,%d', count(Comment::getVisibilityLevels())),\n ]);\n\n $visibility = $this->request->input('visibility');\n\n if ($comment->parent !== null) {\n return $this->response->errorWrongArgs('Comment visibility can only be updated on top level comments.');\n }\n\n try {\n $this->activityCommentService->updateCommentVisibility($comment, $visibility);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment\\'s visibility.');\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function deleteComment(Activity $activity, Comment $comment)\n {\n $this->authorize('deleteComment', [$activity, $comment]);\n\n // Delete comment and any children.\n $comment->delete();\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function fetchComments()\n {\n $user = $this->request->user();\n $this->request->validate([\n 'forUserId' => 'uuid:users,team_id,' . $user->team_id,\n 'types' => 'array',\n 'types.*' => 'integer|between:0,3',\n ]);\n $forUser = null;\n\n $types = [Comment::TYPE_NEUTRAL, Comment::TYPE_GAME_CHANGER, Comment::TYPE_POSITIVE];\n $user = $this->request->user();\n if ($this->request->has('forUserId')) {\n $forUser = $user->team->users()->uuid($this->request->input('forUserId'));\n }\n\n $comments = Comment::query()\n ->whereHas('activity', static function (Builder $builder) use ($user, $forUser): void {\n $builder\n // I left feedback on my own activity; or\n ->where('activities.user_id', $user->getId());\n if ($forUser) {\n // I left feedback on any activity for this user.\n $builder->orWhere([\n 'user_id' => $user->getId(),\n 'activities.user_id' => $forUser->getId(),\n ]);\n }\n })\n ->whereIn('type', $this->request->input('types', $types))\n ->orderBy('created_at', 'desc')\n ->get();\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity', 'user'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($comments, new ActivityCommentTransformer());\n }\n\n public function deleteCoachingFeedback(Activity $activity, CoachingFeedback $coachingFeedback)\n {\n $this->authorize('deleteCoachingFeedback', [$activity, $coachingFeedback]);\n $activity = $coachingFeedback->getActivity();\n\n if ($coachingFeedback->delete()) {\n event(new UpdateSingleEntity(\n entityId: $activity->getId(),\n updateTarget: UpdateTargetEnum::ACTIVITY,\n purpose: 'delete-coaching-feedback',\n ));\n\n return $this->response->withOk();\n }\n\n return $this->response->withError('Delete operation failed. Contact support.', 500);\n }\n\n /**\n * Add new or update Coaching feedback\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws \\Illuminate\\Validation\\ValidationException\n *\n * @return mixed\n */\n public function putCoachingFeedback(Request $request, Activity $activity)\n {\n $user = $request->user();\n\n if (! $user instanceof User) {\n abort(403);\n }\n $teamId = $user->getTeamId();\n\n $this->authorize('coach', $activity);\n\n $this->request->validate([\n 'coach_id' => 'required|uuid:users,team_id,' . $teamId,\n 'coachee_id' => 'required|uuid:users,team_id,' . $teamId,\n 'visibility' => ['required', Rule::in(CoachingFeedback::VISIBILITIES)],\n 'coaching_sections.*.uuid' => 'required|uuid:coaching_sections',\n 'coaching_sections.*.score' => ['required', Rule::in(CoachingSectionFeedback::SCORES)],\n 'coaching_sections.*.summary' => 'string|max:10000',\n 'coaching_sections.*.criteria.*.uuid' => 'required|uuid:coaching_section_criteria',\n 'coaching_sections.*.criteria.*.note' => 'required|string|max:10000',\n 'sharedWithUsers' => [\n 'required_if:visibility,' . CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS,\n 'array',\n ],\n 'sharedWithUsers.*' => [\n 'uuid:users,team_id,' . $teamId,\n ],\n ]);\n\n /** @var User $coach */\n $coach = User::uuid($this->request->input('coach_id'));\n /** @var User $coachee */\n $coachee = User::uuid($this->request->input('coachee_id'));\n $coachingSectionFeedbacks = $this->request->input('coaching_sections');\n\n $previousRecord = $this->coachingFeedbackRepository->getOneForActivityByCoacheeAndCoach(\n $coachee->getId(),\n $coach->getId(),\n $activity->getId()\n );\n $recordIsNew = false;\n if ($previousRecord === null) {\n $recordIsNew = true;\n }\n\n if (! $coachee->isSameTeamId($coach)) {\n return $this->response->errorForbidden('User not member of your team.');\n }\n\n if (! is_array($coachingSectionFeedbacks) || count($coachingSectionFeedbacks) < 1) {\n return $this->response->withError('At least one Coaching Framework Section shall be scored.', 422);\n }\n\n if (! $activity->participants()->where('participants.user_id', $coachee->id)->exists()) {\n return $this->response->withError('Coached user did not participate activity.', 422);\n }\n\n $visibility = $this->request->input('visibility');\n\n $shouldSendNotification = $recordIsNew;\n if ($recordIsNew === false && $visibility !== $previousRecord->getVisibility()) {\n $shouldSendNotification = true;\n }\n\n /**\n * Create CoachingFeedback\n *\n * @var CoachingFeedback $coachingFeedback\n */\n $coachingFeedback = $activity->coachingFeedbacks()->updateOrCreate(\n [\n 'coach_id' => $coach->id,\n 'coachee_id' => $coachee->id,\n ],\n [\n 'framework_id' => $activity->category->id,\n 'visibility' => $visibility,\n ]\n );\n\n $sharedUserIds = [];\n if ($visibility === CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS) {\n foreach ($this->request->input('sharedWithUsers') as $sharedWithUserUuid) {\n /** @var User $user */\n $user = User::uuid($sharedWithUserUuid);\n $sharedUserIds[] = $user->getId();\n }\n }\n\n $syncResult = $coachingFeedback->customAccessUsers()->sync($sharedUserIds);\n\n $scores = [];\n\n\n /**\n * Create CoachingSectionsFeedbacks.\n *\n * @var CoachingSectionFeedback $coachingSectionFeedback\n */\n foreach ($coachingSectionFeedbacks as $coachingSectionFeedbackInput) {\n $coachingSection = CoachingSection::uuid($coachingSectionFeedbackInput['uuid']);\n $coachingSectionFeedback = $coachingFeedback->sectionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_id' => $coachingSection->id,\n ],\n [\n 'score' => array_get($coachingSectionFeedbackInput, 'score'),\n 'summary' => array_get($coachingSectionFeedbackInput, 'summary') ?? '',\n ]\n );\n\n $scores[] = array_get($coachingSectionFeedbackInput, 'score');\n\n $criteria = array_get($coachingSectionFeedbackInput, 'criteria');\n if (is_array($criteria) && ! empty($criteria)) {\n foreach ($criteria as $criteriaFeedbackInput) {\n $coachingSectionFeedback->criterionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_criterion_id' => CoachingSectionCriterion::uuid(array_get($criteriaFeedbackInput, 'uuid'))\n ->id,\n ],\n ['note' => array_get($criteriaFeedbackInput, 'note')],\n );\n }\n }\n }\n\n $coachingFeedback->average_score = array_sum($scores) / count($scores);\n\n if ($recordIsNew === false && $coachingFeedback->getAverageScore() !== $previousRecord->getAverageScore()) {\n $shouldSendNotification = true;\n }\n if (! empty($syncResult['attached']) || ! empty($syncResult['detached']) || ! empty($syncResult['updated'])) {\n $shouldSendNotification = true;\n }\n\n $coachingFeedback->save();\n // ensure updated at for coaching feedback on section feedback summary added.\n $coachingFeedback->touch();\n\n if ($shouldSendNotification) {\n event(new Coached($coachingFeedback));\n }\n\n Datadog::increment('jiminny.activity.score.update', 1, ['company' => $activity->user->team->slug]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n $coachingFeedbackTransformer = new CoachingFeedbackTransformer();\n $coachingFeedbackTransformer->setConsumer($this->getUserFromRequest($request));\n\n return $this->response->withItem($coachingFeedback, $coachingFeedbackTransformer);\n }\n\n\n /**\n * Retrieve category criteria for coaching.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachingSections(Activity $activity)\n {\n $this->authorize('coach', $activity);\n\n if ($activity->category === null) {\n return $this->response->errorUnprocessable('Category has not yet been assigned.');\n }\n\n $criteria = $activity\n ->category\n ->coachingSections()\n ->where('is_enabled', 1)\n ->orderBy('sequence', 'asc');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($criteria->get(), new CoachingSectionsTransformer());\n }\n\n /**\n * @throws AuthorizationException\n * @throws ValidationException\n *\n * @return mixed\n */\n public function addToPlaylist(Activity $activity, PlaylistTrackFactoryInterface $playlistTrackFactory)\n {\n $this->request->validate([\n 'playlists' => 'required|array',\n 'playlists.*' => 'uuid:playlists',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'name' => 'required|max:100',\n ]);\n\n $this->authorize('addToPlaylist', [$activity, $this->request->input('playlists')]);\n\n $startTime = $this->request->input('start_time');\n $endTime = $this->request->input('end_time');\n $name = $this->request->input('name');\n /** @var User $user */\n $user = $this->request->user();\n\n // Get playlist by uuid.\n foreach ($this->request->input('playlists') as $playlistId) {\n // Pull out the playlist model.\n $playlist = Playlist::uuid($playlistId);\n\n $playlistTrackFactory->createTrack($playlist, $user, [\n 'name' => $name,\n 'activity' => $activity,\n 'start_time' => $startTime,\n 'end_time' => $endTime,\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function share(Request $request, Activity $activity): JsonResponse\n {\n $this->authorize('share', $activity);\n\n $request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'recipients.*.type' => 'in:user,group',\n 'recipients.*.id' => 'string|max:40',\n 'share' => 'string|max:255',\n ]);\n\n $user = $request->user();\n\n $recipients = $request->get('recipients');\n $users = $this->userService->convertRecipientsToUsers($user, $recipients);\n\n $shareData = [\n 'from_user_id' => $user->id,\n 'note' => $request->input('note'),\n 'start_time' => $request->input('start_time'),\n 'end_time' => $request->input('end_time'),\n ];\n\n // Create a share object against a notification provider channel\n if ($request->input('share')) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'notification_provider_channel' => $request->input('share'),\n ]\n )\n );\n\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n\n // Create a share object against each recipient\n foreach ($users as $recipient) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'to_user_id' => $recipient->id,\n ]\n )\n );\n\n // If parent_share_id has been selected yet\n if (! isset($shareData['parent_share_id'])) {\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachRequest(Activity $activity)\n {\n $this->authorize('coachRequest', $activity);\n\n $this->request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'coachers.*.type' => 'required|in:user',\n 'coachers.*.id' => 'required',\n ]);\n\n $coachers = $this->request->get('coachers');\n $user = $this->request->user();\n $users = $this->userService->convertRecipientsToUsers($user, $coachers);\n\n foreach ($users as $coacher) {\n CoachRequest::create([\n 'user_id' => $coacher->id,\n 'activity_id' => $activity->id,\n 'note' => $this->request->get('note'),\n 'start_time' => $this->request->get('start_time'),\n 'end_time' => $this->request->get('end_time'),\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function createActivityTopicTriggers(Activity $activity, LoggerInterface $logger): HttpFoundation\\JsonResponse\n {\n $this->authorize('analyzeTopicTriggers', $activity);\n\n if (! $activity->hasTranscription()) {\n return new HttpFoundation\\JsonResponse(\n [\n 'error' => 'Transcription not found.',\n ],\n JsonResponse::HTTP_NOT_FOUND\n );\n }\n\n $logger->info(__METHOD__ . ': queued for analysis', [\n 'activity' => $activity->id_string,\n ]);\n\n dispatch(new ActivityAnalytics\\Job\\AnalyzeActivityTopicTriggers($activity));\n\n return new HttpFoundation\\JsonResponse(null, JsonResponse::HTTP_CREATED);\n }\n\n public function fetchActivityTopicTriggers(\n Activity $activity,\n LoggerInterface $logger,\n ActivityTopicTriggerTransformer $transformer\n ): HttpFoundation\\JsonResponse {\n $this->authorize('fetchTopicTriggers', $activity);\n\n $logger->debug(__METHOD__, [\n 'activity' => $activity->id_string,\n ]);\n\n if (! $activity->isProcessed()) {\n return new HttpFoundation\\JsonResponse([]);\n }\n\n $payload = [];\n\n if ($activity->hasTopicTriggers()) {\n $payload = $activity->getTopicTriggersSorted()\n ->map(\n static fn (Activity\\TopicTrigger $activityTopicTrigger): array\n => $transformer->transform($activityTopicTrigger)\n )\n ->values()\n ->all();\n }\n\n return new HttpFoundation\\JsonResponse($payload);\n }\n\n /**\n * @param Activity $activity\n * @param StatsTransformer $statsTransformer\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function stats(Activity $activity, StatsTransformer $statsTransformer)\n {\n $this->authorize('stream', $activity);\n\n if (! $activity->hasTranscription()) {\n return $this->response->errorNotFound('Waveform data is not yet generated.');\n }\n\n $this->response\n ->getManager()\n ->parseIncludes(['wavedata'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($activity, $statsTransformer);\n }\n\n public function destroy(Activity $activity)\n {\n $this->authorize('delete', $activity);\n\n $activity->delete();\n\n \\Log::info('Soft delete activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n\n return $this->response->withNoContent();\n }\n\n public function note(Activity $activity)\n {\n $this->authorize('note', $activity);\n\n $this->request->validate([\n 'note' => 'required|min:1|max:2000',\n 'time' => 'required|numeric|min:0|max:86400',\n ]);\n\n $note = $this->request->input('note');\n $time = $this->request->input('time');\n\n $this->activityService->setActivity($activity);\n $this->activityService->takeNote($this->getUser(), $note, $time);\n\n return $this->response->withCreated();\n }\n\n /**\n * Mark an activity as private.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPrivate(Activity $activity)\n {\n $this->authorize('markAsPrivate', $activity);\n\n if ($activity->is_private === false) {\n $activity->is_private = true;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * Mark an activity as public.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPublic(Activity $activity)\n {\n $this->authorize('markAsPublic', $activity);\n\n if ($activity->is_private) {\n $activity->is_private = false;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws LogicException\n */\n public function fetchCloudFrontS3MediaKeys(Activity $activity, PlaybackService $playbackService): JsonResponse\n {\n $masterTrack = $activity->masterTrack()->first();\n\n if (! $masterTrack instanceof Track) {\n throw new LogicException(sprintf('Master track not found for activity \"%s\"', $activity->getUuid()));\n }\n\n return $this->response->withArray(\n $playbackService->generateCookies(\n $masterTrack,\n $this->request->ip(),\n ),\n );\n }\n\n /**\n * @throws ValidationException\n */\n private function updateOrCreateActivitySearch(Request $request, ?Search $search = null): Search\n {\n $request->validate([\n 'name' => 'required|string|min:2|max:100',\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $searchName = $request->input('name');\n\n if ($search !== null) {\n $search->update([\n 'name' => $searchName,\n ]);\n\n return $search;\n }\n\n $request->validate([\n 'filters' => ['required', 'array', new MultidimensionalArrayMaxCharRule(limit: 255)],\n 'nudges' => 'array|max:' . count(Nudge::MAP_CHANNEL),\n 'nudges.*.channel' => 'required|in:' . implode(',', Nudge::MAP_CHANNEL),\n 'nudges.*.frequency' => 'required|in:' . implode(',', Nudge::MAP_FREQUENCY),\n 'nudges.*.expiresAt' => [\n 'required',\n 'date',\n 'after:today',\n 'before_or_equal:' . now()->addYear()->format('Y-m-d'),\n ],\n ]);\n\n $searchCriteria = Criteria::createFromRequest(\n Collection::make($request->input('filters', []))->all(),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($searchCriteria, $user);\n $this->validateSearch($request, $filterSet, 'filters.');\n\n /** @var Search $search */\n $search = Search::create([\n 'name' => $searchName,\n 'uuid' => Uuid::uuid4()->toString(),\n 'user_id' => $user->getId(),\n ]);\n\n Collection::make($request->input('nudges', []))\n ->each(fn (array $attributes): Nudge => $this->nudgeFactory->createNudge($search, $attributes));\n\n $this->storeNamedSearchFilters(Collection::make($request->all()), $search, $filterSet, 'filters.');\n\n return $search;\n }\n\n private function resolveAccount(\n Team $team,\n Contact $contact,\n ServiceInterface $crmService,\n array $prospects,\n ): ?Account {\n $this->logger->info('Resolving account from contact');\n $account = $contact->getAccount();\n\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS)) {\n $this->logger->info('Team does not have feature to link activity to multiple prospects');\n\n return $account;\n }\n\n $this->logger->info('Resolving account from prospect data');\n $accountData = array_filter(\n $prospects,\n static fn (array $prospectData): bool => $prospectData['type'] === 'account'\n );\n\n if (! empty($accountData)) {\n $this->logger->info('Found account data in prospects');\n $accountData = reset($accountData);\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountData['id'])->first();\n\n if (! $account instanceof Account) {\n $this->logger->info('Account not found in database, syncing from CRM');\n $account = $crmService->syncAccount($accountData['id']);\n }\n }\n\n $this->logger->info('Resolved account', ['account' => $account->getId()]);\n\n return $account;\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Http\\Controllers\\API;\n\nuse Carbon\\Carbon;\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Exception;\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Validation\\Rule;\nuse Illuminate\\Validation\\Rules\\In;\nuse Illuminate\\Validation\\ValidationException;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ActivityAnalytics;\nuse Jiminny\\Component\\ActivitySearch;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Contracts\\ES\\Events\\UpdateSingleEntity;\nuse Jiminny\\Contracts\\ES\\UpdateTargetEnum;\nuse Jiminny\\Contracts\\Nudge\\NudgeFactoryInterface;\nuse Jiminny\\Contracts\\Playlist\\PlaylistTrackFactoryInterface;\nuse Jiminny\\Contracts\\Repositories\\PlaylistActivityRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Enums\\TeamSetting;\nuse Jiminny\\Events\\Activities\\AiAutomation\\ActivityProspectAdded;\nuse Jiminny\\Events\\Activities\\Coaching\\Coached;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Controllers\\CommentContextInterface;\nuse Jiminny\\Http\\Responses\\Api\\AbstractResponse;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\ActivityCommentTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTopicTriggerTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTransformer;\nuse Jiminny\\Http\\Transformers\\AvailabilityNotificationTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingFeedbackTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingSectionsTransformer;\nuse Jiminny\\Http\\Transformers\\SearchTransformer;\nuse Jiminny\\Http\\Transformers\\StatsTransformer;\nuse Jiminny\\Jobs\\Crm\\SaveActivity;\nuse Jiminny\\Jobs\\Crm\\UpdateStage;\nuse Jiminny\\Jobs\\Telephony\\StartRecording;\nuse Jiminny\\Jobs\\Telephony\\StopRecording;\nuse Jiminny\\Jobs\\Telephony\\ToggleRecording;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\CoachingFeedback;\nuse Jiminny\\Models\\CoachingSection;\nuse Jiminny\\Models\\CoachingSectionCriterion;\nuse Jiminny\\Models\\CoachingSectionFeedback;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\LanguageDialect;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Nudge;\nuse Jiminny\\Models\\PlaybookCategory;\nuse Jiminny\\Models\\Playlist;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\Track;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\CoachingFeedbackRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Rules\\MultidimensionalArrayMaxCharRule;\nuse Jiminny\\Services\\ActivityService;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Services\\PlaybackService;\nuse Jiminny\\Services\\UserService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\nuse Ramsey\\Uuid\\Uuid;\nuse Sentry;\nuse Symfony\\Component\\HttpFoundation;\n\nfinal class ActivityController extends Controller implements CommentContextInterface\n{\n // Number of minutes to look back on activities. i.e. a timeout on activity duration.\n private const int LOOK_BACK = 180;\n\n public function __construct(\n private ProviderRegistry $providerRegistry,\n private ActivityService $activityService,\n Response $response,\n private UserService $userService,\n private ActivitySearch\\Service\\ActivitySearch $activitySearch,\n private NudgeFactoryInterface $nudgeFactory,\n private ActivityCommentService $activityCommentService,\n private LoggerInterface $logger,\n private readonly CoachingFeedbackRepository $coachingFeedbackRepository,\n private readonly TeamRepository $teamRepository,\n ) {\n parent::__construct($response);\n }\n\n public static function getCommentImplementation(): string\n {\n return Comment::class;\n }\n\n public function delete()\n {\n $this->request->validate([\n '*' => 'uuid:activities',\n ]);\n\n $deletedIds = [];\n foreach ($this->request->all() as $activityId) {\n $activity = Activity::idOrUuId($activityId);\n\n try {\n if ($this->authorize('delete', $activity)) {\n $activity->delete();\n $deletedIds[] = $activityId;\n\n \\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n }\n } catch (AuthorizationException $authorizationException) {\n // They didn't have permission.\n }\n }\n\n return $this->response->withArray($deletedIds);\n }\n\n public function update(Request $request, Activity $activity)\n {\n $this->authorize('updateMetadata', $activity);\n\n $request->validate([\n 'title' => 'string|max:250',\n 'category_id' => 'uuid:playbook_categories',\n 'language' => [\n new In(\n LanguageDialect::query()\n ->with('language')\n ->cursor()\n ->map(static function (LanguageDialect $languageDialect): string {\n return $languageDialect->getLanguageLocale();\n })\n ->all()\n ),\n ],\n ]);\n\n if ($request->has('title')) {\n $activity->title = $request->input('title');\n }\n\n if ($request->has('category_id')) {\n $category = PlaybookCategory::uuid($request->input('category_id'));\n\n if ($category->playbook->team_id !== $request->user()->team_id) {\n return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n if ($request->has('language')) {\n if (! $activity->isInProgress()) {\n return $this->response->withError(\n 'Activity language can only be set while the meeting is in progress.',\n 400\n );\n }\n\n $activity->setLanguageCode($request->input('language'));\n }\n\n $activity->save();\n\n return $this->response->withOk();\n }\n\n // XXX: This should be merged with the update method.\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws SocialAccountTokenInvalidException\n *\n * @return mixed\n */\n public function summarize(Activity $activity): mixed\n {\n $this->logger->info('[Log Activity] Summarizing activity ', [\n 'activityId' => $activity->getUuid(),\n 'payload' => $this->request->all(),\n ]);\n $this->authorize('update', $activity);\n\n $this->logger->info('[Log Activity] Validating summary');\n // Validate the payload.\n $this->validateSummary($activity);\n\n // All objects must belong to this team.\n /** @var User $user */\n $user = $this->request->user();\n $team = $user->getTeam();\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n try {\n $crmUser = $user;\n if ($user->isCrmRequired() === false) {\n $crmUser = $team->owner;\n }\n $crmService->setUser($crmUser);\n } catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());\n }\n\n $rawEntities = $this->request->input('entities');\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid(\n $this->request->input('layout_id')\n );\n\n // Delay execution of CRM jobs to avoid locking issues.\n $jobDelay = 0;\n\n // If we have arrived from a notification, mark it as read.\n $notificationId = $this->request->input('nId');\n if ($notificationId) {\n $notification = $user->unreadNotifications->where('id', $notificationId)->first();\n\n if ($notification) {\n $notification->markAsRead();\n }\n }\n\n $title = $this->request->input('title');\n $prospects = $this->request->input('prospects');\n $opportunityId = $this->request->input('opportunity_id');\n $stageId = $this->request->input('stage_id');\n $categoryId = $this->request->input('category_id');\n $summary = $this->request->input('summary');\n $crmProviderId = $this->request->input('crm_id');\n $isInternal = $this->request->input('is_internal') ?? false;\n\n $lead = null;\n $category = null;\n $account = null;\n $contact = null;\n $opportunity = null;\n $stage = null;\n $callStage = null;\n\n foreach ($prospects as $prospectData) {\n $objectId = $prospectData['id'];\n\n if ($objectId === null) {\n continue;\n }\n\n $objectType = $prospectData['type'];\n $this->logger->info('debug', ['prospect_data' => $prospectData]);\n\n try {\n if ($objectType === null) {\n $this->logger->info('no object type');\n if ($crmService instanceof SupportsObjectTypeParseInterface) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n }\n\n switch ($objectType) {\n case 'lead':\n $this->logger->info('Processing lead');\n /** @var Lead|null $lead */\n $lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();\n\n // Lead does not exist locally, import it.\n if ($lead === null) {\n $this->logger->info('Lead does not exist locally');\n /** @var Lead $lead */\n $lead = $crmService->syncLead($objectId);\n }\n\n $this->logger->info('Lead found', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n if ($stageId === null) {\n $this->logger->info('Stage ID is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $lead->stage;\n\n break;\n }\n\n $this->logger->info('Looking for stage');\n // Determine if they have changed the stage.\n /** @var Stage $stage */\n $stage = $team->crm->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_LEAD)\n ->firstOrFail();\n\n $this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);\n if ($lead->stage_id && $lead->stage_id !== $stage->id) {\n $this->logger->info('Stage has changed');\n // Storage current stage on activity.\n $callStage = $lead->stage;\n\n // The stage has changed, update in remote CRM.\n dispatch(new UpdateStage($activity, $lead, $callStage, $stage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing lead stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->getName(),\n $stage->getName()\n ),\n [\n 'user' => $user->getUuid(),\n 'lead' => $lead->getUuid(),\n ]\n );\n } else {\n $this->logger->info('Stage has not changed');\n // Stage remains as current.\n $callStage = $stage;\n }\n\n break;\n\n case 'account':\n $this->logger->info('Processing account');\n // If the object is not a lead, it should be an account.\n $account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();\n\n // Account does not exist locally, import it.\n if ($account === null) {\n $this->logger->info('Account does not exist locally');\n $account = $crmService->syncAccount($objectId);\n }\n\n $this->logger->info('Account found', ['accountId' => $account->id]);\n\n break;\n case 'contact':\n $this->logger->info('processing contact');\n $contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $this->logger->info('contact does not exist locally');\n $contact = $crmService->syncContact($objectId);\n }\n\n $this->logger->info('resolving account');\n $account = $this->resolveAccount($team, $contact, $crmService, $prospects);\n\n break;\n }\n\n // If they have specified an opportunity, retrieve this with stage.\n if ($opportunityId) {\n $this->logger->info('opportunity id is set');\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if ($opportunity === null) {\n $this->logger->info('opportunity does not exist locally');\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n if ($stageId === null) {\n $this->logger->info('stage id is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $opportunity->stage ?? null;\n } else {\n $this->logger->info('looking for stage');\n /** @var ?Stage $opportunityStage */\n $opportunityStage = $team->crm\n ->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n // There is a chance we still cannot import this opportunity.\n if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {\n $this->logger->info('opportunity stage has changed');\n // Storage current stage on activity.\n $callStage = $opportunity->stage;\n\n dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing opportunity stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->name,\n $opportunityStage->name\n ),\n [\n 'userId' => $user->id_string,\n 'opportunityId' => $opportunity->id_string,\n ]\n );\n } else {\n $this->logger->info('opportunity stage has not changed');\n // Stage remains as current.\n $callStage = $opportunityStage;\n }\n }\n }\n\n if ($crmProviderId) {\n // Cast $crmProviderId to string otherwise it won't use database index for some records\n $linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();\n\n // Check if this activity has already been assigned to a different activity.\n if ($linkedActivity && $linkedActivity->id !== $activity->id) {\n throw new InvalidArgumentException(\n 'Sorry, the linked task has already been logged under a different call. '\n . 'Please choose another linked task.'\n );\n }\n }\n } catch (InvalidArgumentException $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($exception->getMessage());\n } catch (Exception $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorInternalError(\n 'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'\n );\n }\n }\n\n if ($categoryId) {\n $category = PlaybookCategory::uuid($categoryId);\n\n if ($category->playbook->team_id !== $team->id) {\n throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n $this->logger->info('Prospect data', [\n 'lead_id' => $lead?->getId(),\n 'account_id' => $account?->getId(),\n 'contact_id' => $contact?->getId(),\n 'opportunity_id' => $opportunity?->getId(),\n 'stage_id' => $stage?->getId(),\n ]);\n\n if ($title) {\n $activity->title = $title;\n }\n\n if ($summary) {\n $activity->summary = $summary;\n }\n\n if ($crmProviderId) {\n $activity->crm_provider_id = $crmProviderId;\n }\n\n if ($callStage) {\n $this->logger->info('Setting stage id', ['stageId' => $callStage->id]);\n $activity->stage_id = $callStage->id;\n }\n\n if ($lead) {\n $this->logger->info('Setting lead id', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n // If we are changed from an account > lead, unset the account data.\n $this->logger->info('Unsetting account id, opportunity id, contact id, value');\n $activity->account_id = null;\n $activity->opportunity_id = null;\n $activity->contact_id = null;\n $activity->value = null;\n }\n\n if ($account) {\n $this->logger->info('Setting account id', ['accountId' => $account->id]);\n $activity->account_id = $account->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('unsetting lead id');\n $activity->lead_id = null;\n\n // Unset the contact if switching different accounts. Will be set up below if still applicable.\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {\n $this->logger->info('Unsetting contact id');\n $activity->contact_id = null;\n }\n }\n\n if ($opportunity) {\n $this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);\n $this->logger->info('unsetting lead id');\n $activity->opportunity_id = $opportunity->id;\n $activity->value = $opportunity->value;\n\n // If we are changed from an lead > account, unset the lead data.\n $activity->lead_id = null;\n }\n\n if ($contact) {\n $this->logger->info('setting contact id', ['contactId' => $contact->id]);\n $activity->contact_id = $contact->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('Unsetting lead id');\n $activity->lead_id = null;\n }\n\n $activity->is_internal = $isInternal;\n $activity->save();\n $activity->refresh();\n\n $this->logger->notice('Activity saved', [\n 'activity_id' => $activity->getId(),\n 'lead_id' => $activity->lead_id,\n 'account_id' => $activity->account_id,\n 'contact_id' => $activity->contact_id,\n 'opportunity_id' => $activity->opportunity_id,\n 'stage_id' => $activity->stage_id,\n 'crm_provider_id' => $activity->getCrmProviderId(),\n ]);\n\n // Store entities as field data on the activity.\n $updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);\n\n if ($activity->isLoggable()) {\n // Follow-up Task or Event data.\n $followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);\n\n $this->logger->info('CRM LOG manual log triggered', [\n 'activityId' => $activity->getUuid(),\n 'followupData' => $followupData,\n 'userId' => $user->getUuid(),\n ]);\n\n // Store data in the CRM.\n // ++add check for crm_required\n $job = new SaveActivity($activity, $followupData);\n\n if ($updatedData) {\n $job->delay(Carbon::now()->addMinutes($jobDelay));\n }\n\n dispatch($job);\n\n // Manually dispatch log for Opportunity or Prospect added\n if ($activity->hasOpportunity() || $activity->hasProspect()) {\n event(new ActivityProspectAdded(\n activity: $activity,\n eventSource: 'manually-log-crm-data'\n ));\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.\n *\n * @param ServiceInterface $service\n * @param Activity $activity\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array\n {\n $updatedData = [];\n $existingData = $activity->data()->get();\n\n // We need to delete any existing data to overwrite with latest values.\n $activity->data()->delete();\n\n $layoutEntities = $layout->entities()\n ->with('field', 'parent')\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->get();\n\n /** @var LayoutEntity $entity */\n foreach ($layoutEntities as $entity) {\n // If the user has provided a value for this entity\n if (array_key_exists($entity->id_string, $entities)) {\n $value = $entities[$entity->id_string];\n\n // Convert raw data into values that the CRM can consume.\n if ($value) {\n $value = $service->normalizeValue($entity->field->type, $value);\n }\n\n // Check the field is part of the activity-summary section.\n if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {\n // This is the internal database ID, not the external CRM ID.\n $objectId = null;\n\n switch ($entity->field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $objectId = $activity->account_id;\n\n break;\n\n case Field::OBJECT_CONTACT:\n $objectId = $activity->contact_id;\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n $objectId = $activity->opportunity_id;\n\n break;\n\n case Field::OBJECT_LEAD:\n $objectId = $activity->lead_id;\n\n break;\n\n case Field::OBJECT_TASK:\n case Field::OBJECT_EVENT:\n $objectId = $activity->id;\n\n break;\n }\n\n if ($objectId) {\n /** @var FieldData $data */\n $data = $activity->data()->create([\n 'crm_layout_entity_id' => $entity->id,\n 'crm_field_id' => $entity->crm_field_id,\n 'object_type' => $entity->field->object_type,\n 'object_id' => $objectId,\n 'value' => $value,\n ]);\n\n // Never send read-only field data to the CRM.\n if ($entity->read_only === false && $entity->is_visible) {\n $existingValue = $existingData\n ->where('crm_layout_entity_id', $entity->id)\n ->where('crm_field_id', $entity->crm_field_id)\n ->where('object_type', $entity->field->object_type)\n ->where('object_id', $objectId)\n ->first();\n\n // If the field was actually changed, we need to reflect this in the CRM too.\n if ($existingValue === null || $existingValue->value !== $value) {\n $updatedData[] = $data->id;\n }\n }\n }\n }\n }\n }\n\n return $updatedData;\n }\n\n /**\n * Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.\n *\n * @param ServiceInterface $crmService\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array\n {\n $fieldData = [];\n foreach ($entities as $entityId => $value) {\n // Only bother with fields that have a value.\n if ($value) {\n // Extract the entity from the UUID. Check the field is valid and part of the follow-up section.\n $entity = $layout->entities()\n ->uuid($entityId, false)\n ->whereHas('parent', function ($query) {\n $query->where('label', 'follow-up');\n })\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->first();\n\n if ($entity) {\n // Convert raw data into values that the CRM can consume.\n $value = $crmService->normalizeValue($entity->field->type, $value);\n\n // Add the field and value to the payload.\n $fieldData += [\n $entity->field->crm_provider_id => $value,\n ];\n }\n }\n }\n\n return $fieldData;\n }\n\n /**\n * @param Activity $activity\n */\n private function validateSummary(Activity $activity): void\n {\n $team = $activity->user->team;\n $crmProvider = $team->crm->provider;\n $attributes = [];\n\n $rules = [\n 'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,\n 'title' => 'string|max:250',\n 'prospects' => 'required|array',\n 'opportunity_id' => new CrmReference($crmProvider),\n 'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',\n 'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator\n 'summary' => 'max:50000',\n 'nId' => 'exists:notifications,id',\n 'crm_id' => new CrmReference($crmProvider),\n 'entities' => 'array',\n 'is_internal' => 'boolean',\n ];\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));\n\n // Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.\n $entities = $layout->entities()\n ->where('read_only', 0)\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->whereHas('parent', function ($query) use ($activity) {\n if ($activity->isLoggable() === false) {\n $query->where('label', '<>', 'follow-up');\n }\n });\n\n $isInternal = $this->request->input('is_internal', false);\n\n foreach ($entities->get() as $entity) {\n $rules += $this->buildFieldValidator($entity, $isInternal);\n $attributes += $this->buildFieldMessage($entity);\n }\n\n $this->request->validate($rules, [], $attributes);\n }\n\n private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array\n {\n return [\n 'entities.' . $entity->id_string => $entity->getValidator($isInternal),\n ];\n }\n\n /**\n * @param LayoutEntity $entity\n *\n * @return array\n */\n private function buildFieldMessage(LayoutEntity $entity): array\n {\n $label = $entity->label;\n if ($label === null) {\n $label = $entity->field->label;\n }\n\n return [\n 'entities.' . $entity->id_string => $label,\n ];\n }\n\n public function search(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->debugLog(\n $user,\n 'User extracted from request',\n ['user' => $user->getId(), 'tz' => $user->getTimezone()]\n );\n\n $searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());\n\n $this->debugLog(\n $user,\n 'ActivitySearch criteria built',\n ['searchCriteria' => $searchCriteria]\n );\n\n $filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);\n\n $this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);\n\n $this->validateSearch($request, $filterSet);\n\n $this->debugLog($user, 'Request validated');\n\n $searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);\n\n /** @var Collection<Activity> $activities */\n $activities = $searchResponse['results'];\n\n $this->debugLog($user, 'Activities ES response extracted');\n\n $hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(\n $user->getTeamId(),\n TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),\n );\n\n if ($hideInternalMeetingsSetting?->getValue() === '1') {\n $activities = $activities->filter(function (Activity $activity) {\n if ($activity->is_internal && empty($activity->actual_start_time)) {\n return false;\n }\n\n return true;\n });\n }\n\n $this->debugLog($user, 'Internal meetings (?!) filtered');\n\n $this->response->getManager()\n ->parseIncludes([\n 'category',\n 'organizer.group',\n 'prospect',\n 'stage',\n 'opportunity',\n 'stats',\n 'scorecards',\n 'masterTrack',\n 'activeParticipants',\n 'notification',\n ])\n ->setSerializer(new JsonSerializer());\n\n $transformerExcludes = $this->request->input('exclude');\n if ($transformerExcludes) {\n $this->response->getManager()->parseExcludes($transformerExcludes);\n }\n\n $this->debugLog($user, 'Response Manager (?!) applied');\n\n $transformer = new ActivityTransformer();\n $transformer->setConsumer($user);\n\n $this->debugLog($user, 'Activity Transformer added');\n\n $resource = new \\League\\Fractal\\Resource\\Collection($activities, $transformer);\n $page = $searchCriteria->getPageNumber();\n\n $this->debugLog($user, 'Search criteria page number called', ['page' => $page]);\n\n $histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');\n\n $this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);\n\n return $this->response->withArray([\n 'pagination' => [\n 'total' => $searchResponse['totalHits'],\n 'current' => $page,\n 'prev' => max($page - 1, 1),\n 'next' => $page + 1,\n ],\n 'results' => $this->response->getManager()->createData($resource)->toArray(),\n 'histogram' => $histogram,\n ]);\n }\n\n private function debugLog(User $user, string $logMessage, ?array $context = []): void\n {\n // Debug for Learning People Only\n if ($user->getTeamId() !== 260) {\n return;\n }\n\n Log::notice(\n sprintf('[activity-search-controller] %s', $logMessage),\n $context\n );\n }\n\n /** @throws ValidationException */\n private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void\n {\n $rules = [\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ];\n\n if ($prefix !== null && mb_strpos($prefix, '.') !== false) {\n $rules[rtrim($prefix, '.')] = sprintf(\n 'required|array|max:%d',\n $filterSet->count()\n );\n }\n\n $validationRules = $filterSet->getValidationRules($prefix)\n ->merge($rules)\n ->all();\n\n $request->validate($validationRules);\n }\n\n public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $search = $this->updateOrCreateActivitySearch($request);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function updateActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('update', $search);\n\n $this->updateOrCreateActivitySearch($request, $search);\n\n return $this->response->withOk();\n }\n\n private function storeNamedSearchFilters(\n Collection $request,\n Search $search,\n FilterDefinitionCollection $filterSet,\n ?string $prefix = null,\n ): self {\n $arrayTypeProperties = $filterSet\n ->getPropertyTypes([\n FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,\n ])\n ->all();\n\n $supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);\n\n foreach ($supportedRequestProperties as $requestPropertyName) {\n if (! array_has($request, $requestPropertyName)) {\n continue;\n }\n\n /** @var string|string[] $propertyValue */\n $propertyValue = array_get($request, $requestPropertyName);\n $propertyName = $prefix === null\n ? $requestPropertyName\n : mb_substr($requestPropertyName, mb_strlen($prefix));\n\n $isArrayType = array_has($arrayTypeProperties, $propertyName);\n\n if (! $isArrayType) {\n /** @var string $requestPropertyValue */\n\n $search->filters()->updateOrCreate(\n [\n 'filter' => $propertyName,\n ],\n [\n 'value' => $propertyValue,\n ]\n );\n\n continue;\n }\n\n /** @var string[] $requestPropertyValue */\n\n /** @var SearchFilter[]|Collection $existingFilterValues */\n $existingFilterValuesKeyed = $search->filters()\n ->where('filter', $propertyName)\n ->get()\n ->keyBy('id');\n\n // Iterate over values provided as request parameters\n foreach ($propertyValue as $value) {\n /** @var SearchFilter|null $valueFilter */\n $valueFilter = $search->filters()\n ->where(\n [\n 'filter' => $propertyName,\n 'value' => $value,\n ]\n )\n ->first();\n\n if ($valueFilter !== null) {\n // Remove filter value pair from list to be deleted\n $existingFilterValuesKeyed->forget($valueFilter->id);\n } else {\n // Add new filter/value pair\n $search->filters()->updateOrCreate([\n 'filter' => $propertyName,\n 'value' => $value,\n ]);\n }\n }\n\n // Delete filter value pairs for this filter that no longer exist in request parameters\n foreach ($existingFilterValuesKeyed as $existingFilter) {\n $existingFilter->delete();\n }\n }\n\n /** @var Collection<int, SearchFilter> $filtersKeyed */\n $filtersKeyed = $search->filters()->get()->keyBy('filter');\n\n // wipe removed filters from this search\n foreach ($filtersKeyed as $filterName => $filter) {\n if (array_has($request, $prefix . $filterName)) {\n continue;\n }\n\n // Remove all filter values for this filter\n $search->filters()->where('filter', $filterName)->delete();\n }\n\n return $this;\n }\n\n /**\n * @throws AuthorizationException\n */\n public function fetchActivitySearch(\n Search $search,\n Request $request,\n SearchTransformer $searchTransformer,\n ): JsonResponse {\n $this->authorize('view', $search);\n\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection(\n $user->searches()->get(),\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n /**\n * Deletes a saved search\n *\n * @param Request $request\n * @param Search $search\n *\n * @throws Exception\n *\n * @return JsonResponse\n */\n public function deleteActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('delete', $search);\n\n // Orphan any AutomatedReports that use this search\n $search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);\n\n // Delete filters and the search itself\n $search->filters()->delete();\n $search->delete();\n\n return $this->response->withOk();\n }\n\n public function live(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n $user = $this->getUserFromRequest($request);\n\n $this->request->validate([\n 'sort_direction' => 'in:asc,desc',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ]);\n\n $activities = $repository->getLiveCoachingEligibleActivities(\n user: $user,\n lookBackMinutes: self::LOOK_BACK,\n limit: (int) $this->request->input('limit', 25),\n page: (int) $this->request->input('page', 1),\n sortBy: ['actual_start_time', 'scheduled_start_time'],\n sortDirection: (string) $this->request->input('sort_direction', 'asc'),\n );\n\n $this->response\n ->getManager()\n ->parseIncludes(['organizer.group', 'prospect'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($activities, new ActivityTransformer());\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function show(Activity $activity, ActivityService $activityService): JsonResponse\n {\n $this->authorize('show', $activity);\n\n $user = $activity->getUser();\n $team = $user->getTeam();\n\n // Sync the opportunity with the latest data if possible.\n if ($activity->opportunity_id) {\n try {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n if (! $user->isCrmRequired()) {\n $crmService->setUser($team->getOwner());\n } else {\n $crmService->setUser($user);\n }\n\n $crmService->syncOpportunity($activity->opportunity->crm_provider_id);\n } catch (Exception $exception) {\n // Move on.\n }\n }\n\n $activityData = $activityService->getActivityData($this->request->user(), $activity);\n\n return response()->json($activityData);\n }\n\n public function createRecording(Activity $activity)\n {\n $this->authorize('record', $activity);\n\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Tell Twilio to start recording this activity.\n if ($activity->recording_state === Activity::RECORDING_OFF) {\n $job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withCreated();\n }\n\n return $this->response->errorGone('Activity is already recording.');\n }\n\n public function updateRecording(Request $request, Activity $activity)\n {\n $this->authorize('record', $activity);\n\n $request->validate([\n 'preference' => 'boolean',\n 'state' => [\n 'string',\n Rule::in([\n Activity::RECORDING_IN_PROGRESS,\n Activity::RECORDING_PAUSED,\n ]),\n ],\n ]);\n\n if ($request->has('state')) {\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Toggle the recording state between paused and resumed.\n if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {\n $job = (new ToggleRecording($activity, $request->input('state')))\n ->onQueue(Constants::QUEUE_CONFERENCES);\n\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Recording is not toggleable.');\n }\n\n if ($request->has('preference')) {\n $activity->update([\n 'recording_preference' => $request->input('preference') ? 1 : 0,\n ]);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorWrongArgs('Something went wrong');\n }\n\n public function stopRecording(Activity $activity)\n {\n $this->authorize('stopRecord', $activity);\n\n // Tell Twilio to stop recording this activity.\n if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {\n $job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Activity is not recording.');\n }\n\n /**\n * Add activity to this user's favorites playlist\n *\n * @throws AuthorizationException\n */\n public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse\n {\n $this->authorize('favorite', $activity);\n\n $user = $this->getUserFromRequest($this->request);\n $favorite = $activity->wasFavoritedBy($user);\n $name = $activity->activity_title ?? '';\n\n // It needs to check at least one record.\n if (! $favorite) {\n $favoritePlaylist = $user->favoritePlaylist();\n\n $playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(\n $activity,\n $user,\n $favoritePlaylist\n );\n\n if ($playlistActivity !== null) {\n $playlistActivity->update(\n // Just update, don't sort.\n ['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],\n );\n } else {\n $playlistActivity = $activity->playlistActivities()->create([\n 'playlist_id' => $favoritePlaylist->getId(),\n 'user_id' => $user->getId(),\n 'start_time' => 0,\n 'name' => mb_strimwidth($name, 0, 100),\n ]);\n // Sort it on top.\n $playlistActivity->update(\n [\n 'sort' => $playlistActivityRepository->calculateNewSortOrder(\n null,\n $playlistActivity,\n ),\n ],\n );\n }\n\n $playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);\n\n return new JsonResponse([], JsonResponse::HTTP_CREATED);\n }\n\n return new JsonResponse(\n [\n 'error' => [\n 'code' => AbstractResponse::CODE_CONFLICT,\n 'http_code' => JsonResponse::HTTP_CONFLICT,\n 'message' => 'Resource Already Exists',\n ],\n ],\n JsonResponse::HTTP_CONFLICT,\n );\n }\n\n /**\n * Remove activity from this user's favorites playlist\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unfavorite(Activity $activity)\n {\n $user = $this->request->user();\n\n $favorites = $activity->favoritedBy($user);\n\n if ($favorites && $favorites->isEmpty()) {\n return $this->response->errorNotFound('Favorite not found.');\n }\n\n $this->authorize('unfavorite', [$activity, $favorites]);\n\n // When you unfavorite an activity,\n // it should remove all the activities in it, including snippets.\n $isDeleted = $favorites->each(function ($favorite) {\n $favorite->forceDelete();\n });\n\n if ($isDeleted) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not remove favorite.');\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function notify(Activity $activity)\n {\n $this->authorize('notify', $activity);\n\n $user = $this->request->user();\n\n $existingNotification = $activity->availabilityNotifications()\n ->where('user_id', $user->id)\n ->exists();\n\n if ($existingNotification) {\n return $this->response->errorWrongArgs('Notification is already configured.');\n }\n\n $notification = Activity\\AvailabilityNotification::create([\n 'user_id' => $user->id,\n 'activity_id' => $activity->id,\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($notification, new AvailabilityNotificationTransformer());\n }\n\n /**\n * @param Activity $activity\n * @param Activity\\AvailabilityNotification $notification\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unnotify(Activity $activity, Activity\\AvailabilityNotification $notification)\n {\n $this->authorize('unnotify', [$activity, $notification]);\n\n if ($notification->sent_at || $notification->delete()) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not delete notification.');\n }\n\n public function play(Request $request, Activity $activity)\n {\n $this->authorize('stream', $activity);\n\n $request->validate([\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $activity->plays()->create([\n 'user_id' => $user->getId(),\n 'start_time' => $request->input('start_time'),\n ]);\n\n return $this->response->withCreated();\n }\n\n /**\n * @param Activity $activity\n *\n * @return mixed\n */\n public function comment(Activity $activity)\n {\n return $this->newComment($activity);\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @return mixed\n */\n public function replyComment(Activity $activity, Comment $comment)\n {\n return $this->newComment($activity, $comment);\n }\n\n /**\n * @param Activity $activity\n * @param Comment|null $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n protected function newComment(Activity $activity, ?Comment $comment = null)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n 'type' => 'integer|between:0,3',\n 'visibility' => sprintf('nullable|integer|between:1,%d', count(Comment::getVisibilityLevels())),\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n $threadStartId = null;\n if ($comment) {\n $threadStartId = $comment->thread_start_id ?: $comment->id;\n }\n\n try {\n $newComment = Comment::create([\n 'parent_comment_id' => $comment->id ?? null,\n 'thread_start_id' => $threadStartId,\n 'activity_id' => $activity->id,\n 'user_id' => $this->request->user()->id,\n 'comment' => trim($this->request->input('comment')),\n 'start_time' => $this->request->input('start_time', 0),\n 'end_time' => $this->request->input('end_time', 0),\n 'type' => $this->request->input('type', Comment::TYPE_NEUTRAL),\n 'visibility' => $this->request->input('visibility', Comment::VISIBILITY_PUBLIC),\n ]);\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($newComment, new ActivityCommentTransformer());\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not create comment.' . $exception->getMessage());\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function updateComment(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n try {\n $comment->update([\n 'comment' => trim($this->request->input('comment')),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment.');\n }\n }\n\n public function updateCommentVisibility(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'visibility' => sprintf('integer|between:1,%d', count(Comment::getVisibilityLevels())),\n ]);\n\n $visibility = $this->request->input('visibility');\n\n if ($comment->parent !== null) {\n return $this->response->errorWrongArgs('Comment visibility can only be updated on top level comments.');\n }\n\n try {\n $this->activityCommentService->updateCommentVisibility($comment, $visibility);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment\\'s visibility.');\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function deleteComment(Activity $activity, Comment $comment)\n {\n $this->authorize('deleteComment', [$activity, $comment]);\n\n // Delete comment and any children.\n $comment->delete();\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function fetchComments()\n {\n $user = $this->request->user();\n $this->request->validate([\n 'forUserId' => 'uuid:users,team_id,' . $user->team_id,\n 'types' => 'array',\n 'types.*' => 'integer|between:0,3',\n ]);\n $forUser = null;\n\n $types = [Comment::TYPE_NEUTRAL, Comment::TYPE_GAME_CHANGER, Comment::TYPE_POSITIVE];\n $user = $this->request->user();\n if ($this->request->has('forUserId')) {\n $forUser = $user->team->users()->uuid($this->request->input('forUserId'));\n }\n\n $comments = Comment::query()\n ->whereHas('activity', static function (Builder $builder) use ($user, $forUser): void {\n $builder\n // I left feedback on my own activity; or\n ->where('activities.user_id', $user->getId());\n if ($forUser) {\n // I left feedback on any activity for this user.\n $builder->orWhere([\n 'user_id' => $user->getId(),\n 'activities.user_id' => $forUser->getId(),\n ]);\n }\n })\n ->whereIn('type', $this->request->input('types', $types))\n ->orderBy('created_at', 'desc')\n ->get();\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity', 'user'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($comments, new ActivityCommentTransformer());\n }\n\n public function deleteCoachingFeedback(Activity $activity, CoachingFeedback $coachingFeedback)\n {\n $this->authorize('deleteCoachingFeedback', [$activity, $coachingFeedback]);\n $activity = $coachingFeedback->getActivity();\n\n if ($coachingFeedback->delete()) {\n event(new UpdateSingleEntity(\n entityId: $activity->getId(),\n updateTarget: UpdateTargetEnum::ACTIVITY,\n purpose: 'delete-coaching-feedback',\n ));\n\n return $this->response->withOk();\n }\n\n return $this->response->withError('Delete operation failed. Contact support.', 500);\n }\n\n /**\n * Add new or update Coaching feedback\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws \\Illuminate\\Validation\\ValidationException\n *\n * @return mixed\n */\n public function putCoachingFeedback(Request $request, Activity $activity)\n {\n $user = $request->user();\n\n if (! $user instanceof User) {\n abort(403);\n }\n $teamId = $user->getTeamId();\n\n $this->authorize('coach', $activity);\n\n $this->request->validate([\n 'coach_id' => 'required|uuid:users,team_id,' . $teamId,\n 'coachee_id' => 'required|uuid:users,team_id,' . $teamId,\n 'visibility' => ['required', Rule::in(CoachingFeedback::VISIBILITIES)],\n 'coaching_sections.*.uuid' => 'required|uuid:coaching_sections',\n 'coaching_sections.*.score' => ['required', Rule::in(CoachingSectionFeedback::SCORES)],\n 'coaching_sections.*.summary' => 'string|max:10000',\n 'coaching_sections.*.criteria.*.uuid' => 'required|uuid:coaching_section_criteria',\n 'coaching_sections.*.criteria.*.note' => 'required|string|max:10000',\n 'sharedWithUsers' => [\n 'required_if:visibility,' . CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS,\n 'array',\n ],\n 'sharedWithUsers.*' => [\n 'uuid:users,team_id,' . $teamId,\n ],\n ]);\n\n /** @var User $coach */\n $coach = User::uuid($this->request->input('coach_id'));\n /** @var User $coachee */\n $coachee = User::uuid($this->request->input('coachee_id'));\n $coachingSectionFeedbacks = $this->request->input('coaching_sections');\n\n $previousRecord = $this->coachingFeedbackRepository->getOneForActivityByCoacheeAndCoach(\n $coachee->getId(),\n $coach->getId(),\n $activity->getId()\n );\n $recordIsNew = false;\n if ($previousRecord === null) {\n $recordIsNew = true;\n }\n\n if (! $coachee->isSameTeamId($coach)) {\n return $this->response->errorForbidden('User not member of your team.');\n }\n\n if (! is_array($coachingSectionFeedbacks) || count($coachingSectionFeedbacks) < 1) {\n return $this->response->withError('At least one Coaching Framework Section shall be scored.', 422);\n }\n\n if (! $activity->participants()->where('participants.user_id', $coachee->id)->exists()) {\n return $this->response->withError('Coached user did not participate activity.', 422);\n }\n\n $visibility = $this->request->input('visibility');\n\n $shouldSendNotification = $recordIsNew;\n if ($recordIsNew === false && $visibility !== $previousRecord->getVisibility()) {\n $shouldSendNotification = true;\n }\n\n /**\n * Create CoachingFeedback\n *\n * @var CoachingFeedback $coachingFeedback\n */\n $coachingFeedback = $activity->coachingFeedbacks()->updateOrCreate(\n [\n 'coach_id' => $coach->id,\n 'coachee_id' => $coachee->id,\n ],\n [\n 'framework_id' => $activity->category->id,\n 'visibility' => $visibility,\n ]\n );\n\n $sharedUserIds = [];\n if ($visibility === CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS) {\n foreach ($this->request->input('sharedWithUsers') as $sharedWithUserUuid) {\n /** @var User $user */\n $user = User::uuid($sharedWithUserUuid);\n $sharedUserIds[] = $user->getId();\n }\n }\n\n $syncResult = $coachingFeedback->customAccessUsers()->sync($sharedUserIds);\n\n $scores = [];\n\n\n /**\n * Create CoachingSectionsFeedbacks.\n *\n * @var CoachingSectionFeedback $coachingSectionFeedback\n */\n foreach ($coachingSectionFeedbacks as $coachingSectionFeedbackInput) {\n $coachingSection = CoachingSection::uuid($coachingSectionFeedbackInput['uuid']);\n $coachingSectionFeedback = $coachingFeedback->sectionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_id' => $coachingSection->id,\n ],\n [\n 'score' => array_get($coachingSectionFeedbackInput, 'score'),\n 'summary' => array_get($coachingSectionFeedbackInput, 'summary') ?? '',\n ]\n );\n\n $scores[] = array_get($coachingSectionFeedbackInput, 'score');\n\n $criteria = array_get($coachingSectionFeedbackInput, 'criteria');\n if (is_array($criteria) && ! empty($criteria)) {\n foreach ($criteria as $criteriaFeedbackInput) {\n $coachingSectionFeedback->criterionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_criterion_id' => CoachingSectionCriterion::uuid(array_get($criteriaFeedbackInput, 'uuid'))\n ->id,\n ],\n ['note' => array_get($criteriaFeedbackInput, 'note')],\n );\n }\n }\n }\n\n $coachingFeedback->average_score = array_sum($scores) / count($scores);\n\n if ($recordIsNew === false && $coachingFeedback->getAverageScore() !== $previousRecord->getAverageScore()) {\n $shouldSendNotification = true;\n }\n if (! empty($syncResult['attached']) || ! empty($syncResult['detached']) || ! empty($syncResult['updated'])) {\n $shouldSendNotification = true;\n }\n\n $coachingFeedback->save();\n // ensure updated at for coaching feedback on section feedback summary added.\n $coachingFeedback->touch();\n\n if ($shouldSendNotification) {\n event(new Coached($coachingFeedback));\n }\n\n Datadog::increment('jiminny.activity.score.update', 1, ['company' => $activity->user->team->slug]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n $coachingFeedbackTransformer = new CoachingFeedbackTransformer();\n $coachingFeedbackTransformer->setConsumer($this->getUserFromRequest($request));\n\n return $this->response->withItem($coachingFeedback, $coachingFeedbackTransformer);\n }\n\n\n /**\n * Retrieve category criteria for coaching.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachingSections(Activity $activity)\n {\n $this->authorize('coach', $activity);\n\n if ($activity->category === null) {\n return $this->response->errorUnprocessable('Category has not yet been assigned.');\n }\n\n $criteria = $activity\n ->category\n ->coachingSections()\n ->where('is_enabled', 1)\n ->orderBy('sequence', 'asc');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($criteria->get(), new CoachingSectionsTransformer());\n }\n\n /**\n * @throws AuthorizationException\n * @throws ValidationException\n *\n * @return mixed\n */\n public function addToPlaylist(Activity $activity, PlaylistTrackFactoryInterface $playlistTrackFactory)\n {\n $this->request->validate([\n 'playlists' => 'required|array',\n 'playlists.*' => 'uuid:playlists',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'name' => 'required|max:100',\n ]);\n\n $this->authorize('addToPlaylist', [$activity, $this->request->input('playlists')]);\n\n $startTime = $this->request->input('start_time');\n $endTime = $this->request->input('end_time');\n $name = $this->request->input('name');\n /** @var User $user */\n $user = $this->request->user();\n\n // Get playlist by uuid.\n foreach ($this->request->input('playlists') as $playlistId) {\n // Pull out the playlist model.\n $playlist = Playlist::uuid($playlistId);\n\n $playlistTrackFactory->createTrack($playlist, $user, [\n 'name' => $name,\n 'activity' => $activity,\n 'start_time' => $startTime,\n 'end_time' => $endTime,\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function share(Request $request, Activity $activity): JsonResponse\n {\n $this->authorize('share', $activity);\n\n $request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'recipients.*.type' => 'in:user,group',\n 'recipients.*.id' => 'string|max:40',\n 'share' => 'string|max:255',\n ]);\n\n $user = $request->user();\n\n $recipients = $request->get('recipients');\n $users = $this->userService->convertRecipientsToUsers($user, $recipients);\n\n $shareData = [\n 'from_user_id' => $user->id,\n 'note' => $request->input('note'),\n 'start_time' => $request->input('start_time'),\n 'end_time' => $request->input('end_time'),\n ];\n\n // Create a share object against a notification provider channel\n if ($request->input('share')) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'notification_provider_channel' => $request->input('share'),\n ]\n )\n );\n\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n\n // Create a share object against each recipient\n foreach ($users as $recipient) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'to_user_id' => $recipient->id,\n ]\n )\n );\n\n // If parent_share_id has been selected yet\n if (! isset($shareData['parent_share_id'])) {\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachRequest(Activity $activity)\n {\n $this->authorize('coachRequest', $activity);\n\n $this->request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'coachers.*.type' => 'required|in:user',\n 'coachers.*.id' => 'required',\n ]);\n\n $coachers = $this->request->get('coachers');\n $user = $this->request->user();\n $users = $this->userService->convertRecipientsToUsers($user, $coachers);\n\n foreach ($users as $coacher) {\n CoachRequest::create([\n 'user_id' => $coacher->id,\n 'activity_id' => $activity->id,\n 'note' => $this->request->get('note'),\n 'start_time' => $this->request->get('start_time'),\n 'end_time' => $this->request->get('end_time'),\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function createActivityTopicTriggers(Activity $activity, LoggerInterface $logger): HttpFoundation\\JsonResponse\n {\n $this->authorize('analyzeTopicTriggers', $activity);\n\n if (! $activity->hasTranscription()) {\n return new HttpFoundation\\JsonResponse(\n [\n 'error' => 'Transcription not found.',\n ],\n JsonResponse::HTTP_NOT_FOUND\n );\n }\n\n $logger->info(__METHOD__ . ': queued for analysis', [\n 'activity' => $activity->id_string,\n ]);\n\n dispatch(new ActivityAnalytics\\Job\\AnalyzeActivityTopicTriggers($activity));\n\n return new HttpFoundation\\JsonResponse(null, JsonResponse::HTTP_CREATED);\n }\n\n public function fetchActivityTopicTriggers(\n Activity $activity,\n LoggerInterface $logger,\n ActivityTopicTriggerTransformer $transformer\n ): HttpFoundation\\JsonResponse {\n $this->authorize('fetchTopicTriggers', $activity);\n\n $logger->debug(__METHOD__, [\n 'activity' => $activity->id_string,\n ]);\n\n if (! $activity->isProcessed()) {\n return new HttpFoundation\\JsonResponse([]);\n }\n\n $payload = [];\n\n if ($activity->hasTopicTriggers()) {\n $payload = $activity->getTopicTriggersSorted()\n ->map(\n static fn (Activity\\TopicTrigger $activityTopicTrigger): array\n => $transformer->transform($activityTopicTrigger)\n )\n ->values()\n ->all();\n }\n\n return new HttpFoundation\\JsonResponse($payload);\n }\n\n /**\n * @param Activity $activity\n * @param StatsTransformer $statsTransformer\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function stats(Activity $activity, StatsTransformer $statsTransformer)\n {\n $this->authorize('stream', $activity);\n\n if (! $activity->hasTranscription()) {\n return $this->response->errorNotFound('Waveform data is not yet generated.');\n }\n\n $this->response\n ->getManager()\n ->parseIncludes(['wavedata'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($activity, $statsTransformer);\n }\n\n public function destroy(Activity $activity)\n {\n $this->authorize('delete', $activity);\n\n $activity->delete();\n\n \\Log::info('Soft delete activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n\n return $this->response->withNoContent();\n }\n\n public function note(Activity $activity)\n {\n $this->authorize('note', $activity);\n\n $this->request->validate([\n 'note' => 'required|min:1|max:2000',\n 'time' => 'required|numeric|min:0|max:86400',\n ]);\n\n $note = $this->request->input('note');\n $time = $this->request->input('time');\n\n $this->activityService->setActivity($activity);\n $this->activityService->takeNote($this->getUser(), $note, $time);\n\n return $this->response->withCreated();\n }\n\n /**\n * Mark an activity as private.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPrivate(Activity $activity)\n {\n $this->authorize('markAsPrivate', $activity);\n\n if ($activity->is_private === false) {\n $activity->is_private = true;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * Mark an activity as public.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPublic(Activity $activity)\n {\n $this->authorize('markAsPublic', $activity);\n\n if ($activity->is_private) {\n $activity->is_private = false;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws LogicException\n */\n public function fetchCloudFrontS3MediaKeys(Activity $activity, PlaybackService $playbackService): JsonResponse\n {\n $masterTrack = $activity->masterTrack()->first();\n\n if (! $masterTrack instanceof Track) {\n throw new LogicException(sprintf('Master track not found for activity \"%s\"', $activity->getUuid()));\n }\n\n return $this->response->withArray(\n $playbackService->generateCookies(\n $masterTrack,\n $this->request->ip(),\n ),\n );\n }\n\n /**\n * @throws ValidationException\n */\n private function updateOrCreateActivitySearch(Request $request, ?Search $search = null): Search\n {\n $request->validate([\n 'name' => 'required|string|min:2|max:100',\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $searchName = $request->input('name');\n\n if ($search !== null) {\n $search->update([\n 'name' => $searchName,\n ]);\n\n return $search;\n }\n\n $request->validate([\n 'filters' => ['required', 'array', new MultidimensionalArrayMaxCharRule(limit: 255)],\n 'nudges' => 'array|max:' . count(Nudge::MAP_CHANNEL),\n 'nudges.*.channel' => 'required|in:' . implode(',', Nudge::MAP_CHANNEL),\n 'nudges.*.frequency' => 'required|in:' . implode(',', Nudge::MAP_FREQUENCY),\n 'nudges.*.expiresAt' => [\n 'required',\n 'date',\n 'after:today',\n 'before_or_equal:' . now()->addYear()->format('Y-m-d'),\n ],\n ]);\n\n $searchCriteria = Criteria::createFromRequest(\n Collection::make($request->input('filters', []))->all(),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($searchCriteria, $user);\n $this->validateSearch($request, $filterSet, 'filters.');\n\n /** @var Search $search */\n $search = Search::create([\n 'name' => $searchName,\n 'uuid' => Uuid::uuid4()->toString(),\n 'user_id' => $user->getId(),\n ]);\n\n Collection::make($request->input('nudges', []))\n ->each(fn (array $attributes): Nudge => $this->nudgeFactory->createNudge($search, $attributes));\n\n $this->storeNamedSearchFilters(Collection::make($request->all()), $search, $filterSet, 'filters.');\n\n return $search;\n }\n\n private function resolveAccount(\n Team $team,\n Contact $contact,\n ServiceInterface $crmService,\n array $prospects,\n ): ?Account {\n $this->logger->info('Resolving account from contact');\n $account = $contact->getAccount();\n\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS)) {\n $this->logger->info('Team does not have feature to link activity to multiple prospects');\n\n return $account;\n }\n\n $this->logger->info('Resolving account from prospect data');\n $accountData = array_filter(\n $prospects,\n static fn (array $prospectData): bool => $prospectData['type'] === 'account'\n );\n\n if (! empty($accountData)) {\n $this->logger->info('Found account data in prospects');\n $accountData = reset($accountData);\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountData['id'])->first();\n\n if (! $account instanceof Account) {\n $this->logger->info('Account not found in database, syncing from CRM');\n $account = $crmService->syncAccount($accountData['id']);\n }\n }\n\n $this->logger->info('Resolved account', ['account' => $account->getId()]);\n\n return $account;\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.40957448,"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.41821808,"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.42918882,"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.43783244,"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.44647607,"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.4574468,"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.46841756,"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.4950133,"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.50598407,"top":0.09896249,"width":0.029587766,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"bounds":{"left":0.7084442,"top":0.09896249,"width":0.02825798,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"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":"40","depth":4,"bounds":{"left":0.67785907,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.69015956,"top":0.123703115,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"40","depth":4,"bounds":{"left":0.6994681,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"64","depth":4,"bounds":{"left":0.7117686,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.7237367,"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.73105055,"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 * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","depth":4,"on_screen":true,"value":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","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}]...
|
-7287184300264252456
|
-8385861013499833196
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use Carbon\Carbon;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\In;
use Illuminate\Validation\ValidationException;
use InvalidArgumentException;
use Jiminny\Component\ActivityAnalytics;
use Jiminny\Component\ActivitySearch;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Queue\Constants;
use Jiminny\Contracts\ES\Events\UpdateSingleEntity;
use Jiminny\Contracts\ES\UpdateTargetEnum;
use Jiminny\Contracts\Nudge\NudgeFactoryInterface;
use Jiminny\Contracts\Playlist\PlaylistTrackFactoryInterface;
use Jiminny\Contracts\Repositories\PlaylistActivityRepository;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Enums\TeamSetting;
use Jiminny\Events\Activities\AiAutomation\ActivityProspectAdded;
use Jiminny\Events\Activities\Coaching\Coached;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Controllers\CommentContextInterface;
use Jiminny\Http\Responses\Api\AbstractResponse;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\ActivityCommentTransformer;
use Jiminny\Http\Transformers\ActivityTopicTriggerTransformer;
use Jiminny\Http\Transformers\ActivityTransformer;
use Jiminny\Http\Transformers\AvailabilityNotificationTransformer;
use Jiminny\Http\Transformers\CoachingFeedbackTransformer;
use Jiminny\Http\Transformers\CoachingSectionsTransformer;
use Jiminny\Http\Transformers\SearchTransformer;
use Jiminny\Http\Transformers\StatsTransformer;
use Jiminny\Jobs\Crm\SaveActivity;
use Jiminny\Jobs\Crm\UpdateStage;
use Jiminny\Jobs\Telephony\StartRecording;
use Jiminny\Jobs\Telephony\StopRecording;
use Jiminny\Jobs\Telephony\ToggleRecording;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\CoachingFeedback;
use Jiminny\Models\CoachingSection;
use Jiminny\Models\CoachingSectionCriterion;
use Jiminny\Models\CoachingSectionFeedback;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\LanguageDialect;
use Jiminny\Models\Lead;
use Jiminny\Models\Nudge;
use Jiminny\Models\PlaybookCategory;
use Jiminny\Models\Playlist;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\Track;
use Jiminny\Models\User;
use Jiminny\Repositories\CoachingFeedbackRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Rules\CrmReference;
use Jiminny\Rules\MultidimensionalArrayMaxCharRule;
use Jiminny\Services\ActivityService;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Services\PlaybackService;
use Jiminny\Services\UserService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
use Ramsey\Uuid\Uuid;
use Sentry;
use Symfony\Component\HttpFoundation;
final class ActivityController extends Controller implements CommentContextInterface
{
// Number of minutes to look back on activities. i.e. a timeout on activity duration.
private const int LOOK_BACK = 180;
public function __construct(
private ProviderRegistry $providerRegistry,
private ActivityService $activityService,
Response $response,
private UserService $userService,
private ActivitySearch\Service\ActivitySearch $activitySearch,
private NudgeFactoryInterface $nudgeFactory,
private ActivityCommentService $activityCommentService,
private LoggerInterface $logger,
private readonly CoachingFeedbackRepository $coachingFeedbackRepository,
private readonly TeamRepository $teamRepository,
) {
parent::__construct($response);
}
public static function getCommentImplementation(): string
{
return Comment::class;
}
public function delete()
{
$this->request->validate([
'*' => 'uuid:activities',
]);
$deletedIds = [];
foreach ($this->request->all() as $activityId) {
$activity = Activity::idOrUuId($activityId);
try {
if ($this->authorize('delete', $activity)) {
$activity->delete();
$deletedIds[] = $activityId;
\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);
}
} catch (AuthorizationException $authorizationException) {
// They didn't have permission.
}
}
return $this->response->withArray($deletedIds);
}
public function update(Request $request, Activity $activity)
{
$this->authorize('updateMetadata', $activity);
$request->validate([
'title' => 'string|max:250',
'category_id' => 'uuid:playbook_categories',
'language' => [
new In(
LanguageDialect::query()
->with('language')
->cursor()
->map(static function (LanguageDialect $languageDialect): string {
return $languageDialect->getLanguageLocale();
})
->all()
),
],
]);
if ($request->has('title')) {
$activity->title = $request->input('title');
}
if ($request->has('category_id')) {
$category = PlaybookCategory::uuid($request->input('category_id'));
if ($category->playbook->team_id !== $request->user()->team_id) {
return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
if ($request->has('language')) {
if (! $activity->isInProgress()) {
return $this->response->withError(
'Activity language can only be set while the meeting is in progress.',
400
);
}
$activity->setLanguageCode($request->input('language'));
}
$activity->save();
return $this->response->withOk();
}
// XXX: This should be merged with the update method.
/**
* @param Activity $activity
*
* @throws AuthorizationException
* @throws SocialAccountTokenInvalidException
*
* @return mixed
*/
public function summarize(Activity $activity): mixed
{
$this->logger->info('[Log Activity] Summarizing activity ', [
'activityId' => $activity->getUuid(),
'payload' => $this->request->all(),
]);
$this->authorize('update', $activity);
$this->logger->info('[Log Activity] Validating summary');
// Validate the payload.
$this->validateSummary($activity);
// All objects must belong to this team.
/** @var User $user */
$user = $this->request->user();
$team = $user->getTeam();
$crmService = $this->providerRegistry->get($team->crm->provider);
try {
$crmUser = $user;
if ($user->isCrmRequired() === false) {
$crmUser = $team->owner;
}
$crmService->setUser($crmUser);
} catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());
}
$rawEntities = $this->request->input('entities');
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid(
$this->request->input('layout_id')
);
// Delay execution of CRM jobs to avoid locking issues.
$jobDelay = 0;
// If we have arrived from a notification, mark it as read.
$notificationId = $this->request->input('nId');
if ($notificationId) {
$notification = $user->unreadNotifications->where('id', $notificationId)->first();
if ($notification) {
$notification->markAsRead();
}
}
$title = $this->request->input('title');
$prospects = $this->request->input('prospects');
$opportunityId = $this->request->input('opportunity_id');
$stageId = $this->request->input('stage_id');
$categoryId = $this->request->input('category_id');
$summary = $this->request->input('summary');
$crmProviderId = $this->request->input('crm_id');
$isInternal = $this->request->input('is_internal') ?? false;
$lead = null;
$category = null;
$account = null;
$contact = null;
$opportunity = null;
$stage = null;
$callStage = null;
foreach ($prospects as $prospectData) {
$objectId = $prospectData['id'];
if ($objectId === null) {
continue;
}
$objectType = $prospectData['type'];
$this->logger->info('debug', ['prospect_data' => $prospectData]);
try {
if ($objectType === null) {
$this->logger->info('no object type');
if ($crmService instanceof SupportsObjectTypeParseInterface) {
$objectType = $crmService->parseObjectType($objectId);
}
}
switch ($objectType) {
case 'lead':
$this->logger->info('Processing lead');
/** @var Lead|null $lead */
$lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();
// Lead does not exist locally, import it.
if ($lead === null) {
$this->logger->info('Lead does not exist locally');
/** @var Lead $lead */
$lead = $crmService->syncLead($objectId);
}
$this->logger->info('Lead found', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
if ($stageId === null) {
$this->logger->info('Stage ID is null');
// If it was not provided, just assume it is the current stage.
$callStage = $lead->stage;
break;
}
$this->logger->info('Looking for stage');
// Determine if they have changed the stage.
/** @var Stage $stage */
$stage = $team->crm->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_LEAD)
->firstOrFail();
$this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);
if ($lead->stage_id && $lead->stage_id !== $stage->id) {
$this->logger->info('Stage has changed');
// Storage current stage on activity.
$callStage = $lead->stage;
// The stage has changed, update in remote CRM.
dispatch(new UpdateStage($activity, $lead, $callStage, $stage));
$this->logger->info(
sprintf(
'[%s] User changing lead stage from %s to %s',
$crmService->getDisplayName(),
$callStage->getName(),
$stage->getName()
),
[
'user' => $user->getUuid(),
'lead' => $lead->getUuid(),
]
);
} else {
$this->logger->info('Stage has not changed');
// Stage remains as current.
$callStage = $stage;
}
break;
case 'account':
$this->logger->info('Processing account');
// If the object is not a lead, it should be an account.
$account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();
// Account does not exist locally, import it.
if ($account === null) {
$this->logger->info('Account does not exist locally');
$account = $crmService->syncAccount($objectId);
}
$this->logger->info('Account found', ['accountId' => $account->id]);
break;
case 'contact':
$this->logger->info('processing contact');
$contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$this->logger->info('contact does not exist locally');
$contact = $crmService->syncContact($objectId);
}
$this->logger->info('resolving account');
$account = $this->resolveAccount($team, $contact, $crmService, $prospects);
break;
}
// If they have specified an opportunity, retrieve this with stage.
if ($opportunityId) {
$this->logger->info('opportunity id is set');
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if ($opportunity === null) {
$this->logger->info('opportunity does not exist locally');
$opportunity = $crmService->syncOpportunity($opportunityId);
}
if ($stageId === null) {
$this->logger->info('stage id is null');
// If it was not provided, just assume it is the current stage.
$callStage = $opportunity->stage ?? null;
} else {
$this->logger->info('looking for stage');
/** @var ?Stage $opportunityStage */
$opportunityStage = $team->crm
->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
// There is a chance we still cannot import this opportunity.
if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {
$this->logger->info('opportunity stage has changed');
// Storage current stage on activity.
$callStage = $opportunity->stage;
dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));
$this->logger->info(
sprintf(
'[%s] User changing opportunity stage from %s to %s',
$crmService->getDisplayName(),
$callStage->name,
$opportunityStage->name
),
[
'userId' => $user->id_string,
'opportunityId' => $opportunity->id_string,
]
);
} else {
$this->logger->info('opportunity stage has not changed');
// Stage remains as current.
$callStage = $opportunityStage;
}
}
}
if ($crmProviderId) {
// Cast $crmProviderId to string otherwise it won't use database index for some records
$linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();
// Check if this activity has already been assigned to a different activity.
if ($linkedActivity && $linkedActivity->id !== $activity->id) {
throw new InvalidArgumentException(
'Sorry, the linked task has already been logged under a different call. '
. 'Please choose another linked task.'
);
}
}
} catch (InvalidArgumentException $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($exception->getMessage());
} catch (Exception $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorInternalError(
'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'
);
}
}
if ($categoryId) {
$category = PlaybookCategory::uuid($categoryId);
if ($category->playbook->team_id !== $team->id) {
throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
$this->logger->info('Prospect data', [
'lead_id' => $lead?->getId(),
'account_id' => $account?->getId(),
'contact_id' => $contact?->getId(),
'opportunity_id' => $opportunity?->getId(),
'stage_id' => $stage?->getId(),
]);
if ($title) {
$activity->title = $title;
}
if ($summary) {
$activity->summary = $summary;
}
if ($crmProviderId) {
$activity->crm_provider_id = $crmProviderId;
}
if ($callStage) {
$this->logger->info('Setting stage id', ['stageId' => $callStage->id]);
$activity->stage_id = $callStage->id;
}
if ($lead) {
$this->logger->info('Setting lead id', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
// If we are changed from an account > lead, unset the account data.
$this->logger->info('Unsetting account id, opportunity id, contact id, value');
$activity->account_id = null;
$activity->opportunity_id = null;
$activity->contact_id = null;
$activity->value = null;
}
if ($account) {
$this->logger->info('Setting account id', ['accountId' => $account->id]);
$activity->account_id = $account->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('unsetting lead id');
$activity->lead_id = null;
// Unset the contact if switching different accounts. Will be set up below if still applicable.
if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {
$this->logger->info('Unsetting contact id');
$activity->contact_id = null;
}
}
if ($opportunity) {
$this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);
$this->logger->info('unsetting lead id');
$activity->opportunity_id = $opportunity->id;
$activity->value = $opportunity->value;
// If we are changed from an lead > account, unset the lead data.
$activity->lead_id = null;
}
if ($contact) {
$this->logger->info('setting contact id', ['contactId' => $contact->id]);
$activity->contact_id = $contact->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('Unsetting lead id');
$activity->lead_id = null;
}
$activity->is_internal = $isInternal;
$activity->save();
$activity->refresh();
$this->logger->notice('Activity saved', [
'activity_id' => $activity->getId(),
'lead_id' => $activity->lead_id,
'account_id' => $activity->account_id,
'contact_id' => $activity->contact_id,
'opportunity_id' => $activity->opportunity_id,
'stage_id' => $activity->stage_id,
'crm_provider_id' => $activity->getCrmProviderId(),
]);
// Store entities as field data on the activity.
$updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);
if ($activity->isLoggable()) {
// Follow-up Task or Event data.
$followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);
$this->logger->info('CRM LOG manual log triggered', [
'activityId' => $activity->getUuid(),
'followupData' => $followupData,
'userId' => $user->getUuid(),
]);
// Store data in the CRM.
// ++add check for crm_required
$job = new SaveActivity($activity, $followupData);
if ($updatedData) {
$job->delay(Carbon::now()->addMinutes($jobDelay));
}
dispatch($job);
// Manually dispatch log for Opportunity or Prospect added
if ($activity->hasOpportunity() || $activity->hasProspect()) {
event(new ActivityProspectAdded(
activity: $activity,
eventSource: 'manually-log-crm-data'
));
}
}
return $this->response->withOk();
}
/**
* Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.
*
* @param ServiceInterface $service
* @param Activity $activity
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array
{
$updatedData = [];
$existingData = $activity->data()->get();
// We need to delete any existing data to overwrite with latest values.
$activity->data()->delete();
$layoutEntities = $layout->entities()
->with('field', 'parent')
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->get();
/** @var LayoutEntity $entity */
foreach ($layoutEntities as $entity) {
// If the user has provided a value for this entity
if (array_key_exists($entity->id_string, $entities)) {
$value = $entities[$entity->id_string];
// Convert raw data into values that the CRM can consume.
if ($value) {
$value = $service->normalizeValue($entity->field->type, $value);
}
// Check the field is part of the activity-summary section.
if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {
// This is the internal database ID, not the external CRM ID.
$objectId = null;
switch ($entity->field->object_type) {
case Field::OBJECT_ACCOUNT:
$objectId = $activity->account_id;
break;
case Field::OBJECT_CONTACT:
$objectId = $activity->contact_id;
break;
case Field::OBJECT_OPPORTUNITY:
$objectId = $activity->opportunity_id;
break;
case Field::OBJECT_LEAD:
$objectId = $activity->lead_id;
break;
case Field::OBJECT_TASK:
case Field::OBJECT_EVENT:
$objectId = $activity->id;
break;
}
if ($objectId) {
/** @var FieldData $data */
$data = $activity->data()->create([
'crm_layout_entity_id' => $entity->id,
'crm_field_id' => $entity->crm_field_id,
'object_type' => $entity->field->object_type,
'object_id' => $objectId,
'value' => $value,
]);
// Never send read-only field data to the CRM.
if ($entity->read_only === false && $entity->is_visible) {
$existingValue = $existingData
->where('crm_layout_entity_id', $entity->id)
->where('crm_field_id', $entity->crm_field_id)
->where('object_type', $entity->field->object_type)
->where('object_id', $objectId)
->first();
// If the field was actually changed, we need to reflect this in the CRM too.
if ($existingValue === null || $existingValue->value !== $value) {
$updatedData[] = $data->id;
}
}
}
}
}
}
return $updatedData;
}
/**
* Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.
*
* @param ServiceInterface $crmService
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array
{
$fieldData = [];
foreach ($entities as $entityId => $value) {
// Only bother with fields that have a value.
if ($value) {
// Extract the entity from the UUID. Check the field is valid and part of the follow-up section.
$entity = $layout->entities()
->uuid($entityId, false)
->whereHas('parent', function ($query) {
$query->where('label', 'follow-up');
})
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->first();
if ($entity) {
// Convert raw data into values that the CRM can consume.
$value = $crmService->normalizeValue($entity->field->type, $value);
// Add the field and value to the payload.
$fieldData += [
$entity->field->crm_provider_id => $value,
];
}
}
}
return $fieldData;
}
/**
* @param Activity $activity
*/
private function validateSummary(Activity $activity): void
{
$team = $activity->user->team;
$crmProvider = $team->crm->provider;
$attributes = [];
$rules = [
'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,
'title' => 'string|max:250',
'prospects' => 'required|array',
'opportunity_id' => new CrmReference($crmProvider),
'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',
'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator
'summary' => 'max:50000',
'nId' => 'exists:notifications,id',
'crm_id' => new CrmReference($crmProvider),
'entities' => 'array',
'is_internal' => 'boolean',
];
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));
// Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.
$entities = $layout->entities()
->where('read_only', 0)
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->whereHas('parent', function ($query) use ($activity) {
if ($activity->isLoggable() === false) {
$query->where('label', '<>', 'follow-up');
}
});
$isInternal = $this->request->input('is_internal', false);
foreach ($entities->get() as $entity) {
$rules += $this->buildFieldValidator($entity, $isInternal);
$attributes += $this->buildFieldMessage($entity);
}
$this->request->validate($rules, [], $attributes);
}
private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array
{
return [
'entities.' . $entity->id_string => $entity->getValidator($isInternal),
];
}
/**
* @param LayoutEntity $entity
*
* @return array
*/
private function buildFieldMessage(LayoutEntity $entity): array
{
$label = $entity->label;
if ($label === null) {
$label = $entity->field->label;
}
return [
'entities.' . $entity->id_string => $label,
];
}
public function search(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->debugLog(
$user,
'User extracted from request',
['user' => $user->getId(), 'tz' => $user->getTimezone()]
);
$searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());
$this->debugLog(
$user,
'ActivitySearch criteria built',
['searchCriteria' => $searchCriteria]
);
$filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);
$this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);
$this->validateSearch($request, $filterSet);
$this->debugLog($user, 'Request validated');
$searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);
/** @var Collection<Activity> $activities */
$activities = $searchResponse['results'];
$this->debugLog($user, 'Activities ES response extracted');
$hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(
$user->getTeamId(),
TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),
);
if ($hideInternalMeetingsSetting?->getValue() === '1') {
$activities = $activities->filter(function (Activity $activity) {
if ($activity->is_internal && empty($activity->actual_start_time)) {
return false;
}
return true;
});
}
$this->debugLog($user, 'Internal meetings (?!) filtered');
$this->response->getManager()
->parseIncludes([
'category',
'organizer.group',
'prospect',
'stage',
'opportunity',
'stats',
'scorecards',
'masterTrack',
'activeParticipants',
'notification',
])
->setSerializer(new JsonSerializer());
$transformerExcludes = $this->request->input('exclude');
if ($transformerExcludes) {
$this->response->getManager()->parseExcludes($transformerExcludes);
}
$this->debugLog($user, 'Response Manager (?!) applied');
$transformer = new ActivityTransformer();
$transformer->setConsumer($user);
$this->debugLog($user, 'Activity Transformer added');
$resource = new \League\Fractal\Resource\Collection($activities, $transformer);
$page = $searchCriteria->getPageNumber();
$this->debugLog($user, 'Search criteria page number called', ['page' => $page]);
$histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');
$this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);
return $this->response->withArray([
'pagination' => [
'total' => $searchResponse['totalHits'],
'current' => $page,
'prev' => max($page - 1, 1),
'next' => $page + 1,
],
'results' => $this->response->getManager()->createData($resource)->toArray(),
'histogram' => $histogram,
]);
}
private function debugLog(User $user, string $logMessage, ?array $context = []): void
{
// Debug for Learning People Only
if ($user->getTeamId() !== 260) {
return;
}
Log::notice(
sprintf('[activity-search-controller] %s', $logMessage),
$context
);
}
/** @throws ValidationException */
private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void
{
$rules = [
'exclude' => 'array',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
];
if ($prefix !== null && mb_strpos($prefix, '.') !== false) {
$rules[rtrim($prefix, '.')] = sprintf(
'required|array|max:%d',
$filterSet->count()
);
}
$validationRules = $filterSet->getValidationRules($prefix)
->merge($rules)
->all();
$request->validate($validationRules);
}
public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$search = $this->updateOrCreateActivitySearch($request);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function updateActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('update', $search);
$this->updateOrCreateActivitySearch($request, $search);
return $this->response->withOk();
}
private function storeNamedSearchFilters(
Collection $request,
Search $search,
FilterDefinitionCollection $filterSet,
?string $prefix = null,
): self {
$arrayTypeProperties = $filterSet
->getPropertyTypes([
FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,
])
->all();
$supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);
foreach ($supportedRequestProperties as $requestPropertyName) {
if (! array_has($request, $requestPropertyName)) {
continue;
}
/** @var string|string[] $propertyValue */
$propertyValue = array_get($request, $requestPropertyName);
$propertyName = $prefix === null
? $requestPropertyName
: mb_substr($requestPropertyName, mb_strlen($prefix));
$isArrayType = array_has($arrayTypeProperties, $propertyName);
if (! $isArrayType) {
/** @var string $requestPropertyValue */
$search->filters()->updateOrCreate(
[
'filter' => $propertyName,
],
[
'value' => $propertyValue,
]
);
continue;
}
/** @var string[] $requestPropertyValue */
/** @var SearchFilter[]|Collection $existingFilterValues */
$existingFilterValuesKeyed = $search->filters()
->where('filter', $propertyName)
->get()
->keyBy('id');
// Iterate over values provided as request parameters
foreach ($propertyValue as $value) {
/** @var SearchFilter|null $valueFilter */
$valueFilter = $search->filters()
->where(
[
'filter' => $propertyName,
'value' => $value,
]
)
->first();
if ($valueFilter !== null) {
// Remove filter value pair from list to be deleted
$existingFilterValuesKeyed->forget($valueFilter->id);
} else {
// Add new filter/value pair
$search->filters()->updateOrCreate([
'filter' => $propertyName,
'value' => $value,
]);
}
}
// Delete filter value pairs for this filter that no longer exist in request parameters
foreach ($existingFilterValuesKeyed as $existingFilter) {
$existingFilter->delete();
}
}
/** @var Collection<int, SearchFilter> $filtersKeyed */
$filtersKeyed = $search->filters()->get()->keyBy('filter');
// wipe removed filters from this search
foreach ($filtersKeyed as $filterName => $filter) {
if (array_has($request, $prefix . $filterName)) {
continue;
}
// Remove all filter values for this filter
$search->filters()->where('filter', $filterName)->delete();
}
return $this;
}
/**
* @throws AuthorizationException
*/
public function fetchActivitySearch(
Search $search,
Request $request,
SearchTransformer $searchTransformer,
): JsonResponse {
$this->authorize('view', $search);
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withCollection(
$user->searches()->get(),
$searchTransformer
->withConsumer($user)
);
}
/**
* Deletes a saved search
*
* @param Request $request
* @param Search $search
*
* @throws Exception
*
* @return JsonResponse
*/
public function deleteActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('delete', $search);
// Orphan any AutomatedReports that use this search
$search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);
// Delete filters and the search itself
$search->filters()->delete();
$search->delete();
return $this->response->withOk();
}
public function live(Request $request, ElasticActivityRepository $repository): JsonResponse
{
$user = $this->getUserFromRequest($request);
$this->request->validate([
'sort_direction' => 'in:asc,desc',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
]);
$activities = $repository->getLiveCoachingEligibleActivities(
user: $user,
lookBackMinutes: self::LOOK_BACK,
limit: (int) $this->request->input('limit', 25),
page: (int) $this->request->input('page', 1),
sortBy: ['actual_start_time', 'scheduled_start_time'],
sortDirection: (string) $this->request->input('sort_direction', 'asc'),
);
$this->response
->getManager()
->parseIncludes(['organizer.group', 'prospect'])
->setSerializer(new JsonSerializer());
return $this->response->withCollection($activities, new ActivityTransformer());
}
/**
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function show(Activity $activity, ActivityService $activityService): JsonResponse
{
$this->authorize('show', $activity);
$user = $activity->getUser();
$team = $user->getTeam();
// Sync the opportunity with the latest data if possible.
if ($activity->opportunity_id) {
try {
$crmService = $this->providerRegistry->get($team->crm->provider);
if (! $user->isCrmRequired()) {
$crmService->setUser($team->getOwner());
} else {
$crmService->setUser($user);
}
$crmService->syncOpportunity($activity->opportunity->crm_provider_id);
} catch (Exception $exception) {
// Move on.
}
}
$activityData = $activityService->getActivityData($this->request->user(), $activity);
return response()->json($activityData);
}
public function createRecording(Activity $activity)
{
$this->authorize('record', $activity);
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Tell Twilio to start recording this activity.
if ($activity->recording_state === Activity::RECORDING_OFF) {
$job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withCreated();
}
return $this->response->errorGone('Activity is already recording.');
}
public function updateRecording(Request $request, Activity $activity)
{
$this->authorize('record', $activity);
$request->validate([
'preference' => 'boolean',
'state' => [
'string',
Rule::in([
Activity::RECORDING_IN_PROGRESS,
Activity::RECORDING_PAUSED,
]),
],
]);
if ($request->has('state')) {
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Toggle the recording state between paused and resumed.
if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {
$job = (new ToggleRecording($activity, $request->input('state')))
->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Recording is not toggleable.');
}
if ($request->has('preference')) {
$activity->update([
'recording_preference' => $request->input('preference') ? 1 : 0,
]);
return $this->response->withOk();
}
return $this->response->errorWrongArgs('Something went wrong');
}
public function stopRecording(Activity $activity)
{
$this->authorize('stopRecord', $activity);
// Tell Twilio to stop recording this activity.
if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {
$job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Activity is not recording.');
}
/**
* Add activity to this user's favorites playlist
*
* @throws AuthorizationException
*/
public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse
{
$this->authorize('favorite', $activity);
$user = $this->getUserFromRequest($this->request);
$favorite = $activity->wasFavoritedBy($user);
$name = $activity->activity_title ?? '';
// It needs to check at least one record.
if (! $favorite) {
$favoritePlaylist = $user->favoritePlaylist();
$playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(
$activity,
$user,
$favoritePlaylist
);
if ($playlistActivity !== null) {
$playlistActivity->update(
// Just update, don't sort.
['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],
);
} else {
$playlistActivity = $activity->playlistActivities()->create([
'playlist_id' => $favoritePlaylist->getId(),
'user_id' => $user->getId(),
'start_time' => 0,
'name' => mb_strimwidth($name, 0, 100),
]);
// Sort it on top.
$playlistActivity->update(
[
'sort' => $playlistActivityRepository->calculateNewSortOrder(
null,
$playlistActivity,
),
],
);
}
$playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);
return new JsonResponse([], JsonResponse::HTTP_CREATED);
}
return new JsonResponse(
[
'error' => [
'code' => AbstractResponse::CODE_CONFLICT,
'http_code' => JsonResponse::HTTP_CONFLICT,
'message' => 'Resource Already Exists',
],
],
JsonResponse::HTTP_CONFLICT,
);
}
/**
* Remove activity from this user's favorites playlist
*
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function unfavorite(Activity $activity)
{
$user = $t...
|
32837
|
NULL
|
NULL
|
NULL
|
|
32839
|
1254
|
20
|
2026-05-13T09:39:24.253054+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665164253_m1.jpg...
|
PhpStorm
|
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Undo
Redo
Cut
Copy
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"Undo","depth":5,"bounds":{"left":0.0,"top":0.0,"width":0.065972224,"height":0.024444444},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Redo","depth":5,"bounds":{"left":0.0,"top":0.0,"width":0.065972224,"height":0.024444444},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Cut","depth":5,"bounds":{"left":0.0,"top":0.0,"width":0.065972224,"height":0.024444444},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Copy","depth":5,"bounds":{"left":0.0,"top":0.0,"width":0.065972224,"height":0.024444444},"on_screen":false,"role_description":"text"}]...
|
-1761439154607564475
|
2810590740393765198
|
click
|
hybrid
|
NULL
|
Undo
Redo
Cut
Copy
SlackFileEdit ViewGoHistoryWind Undo
Redo
Cut
Copy
SlackFileEdit ViewGoHistoryWindowHelpAPPDOCKER• ₴1DEV (docker)₴82APP (-zshtests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleterTest.phptests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesProviderTest.phptests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesUploaderTest.phptests/Unit/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeeches?tests/Unit/Component/Transcription/Diarization/Source/MeetingBotSourceTest.phptests/Unit/Contracts/Services/Calendar/CalendarTraitTest.phptests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.phptests/Unit/Jobs/Activity/Import/ImportTwilioVideoSpeechesJobTest.phptests/Unit/Jobs/Activity/Import/IsActivityReadyForProcessingJobTest.phptests/Unit/Jobs/Calendar/SetupCalendarSyncTest.phptests/Unit/Services/Activity/ParticipantsServiceTest.phptests/Unit/Services/Calendar/Command/ImportParticipantsTest.phptests/Unit/Services/Calendar/GoogleCalendarServiceTest.phptests/Unit/Services/Crm/Close/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTest.phptests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTraitMatchActivitiesTest.phytests/Unit/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTraitOpportunitiesTe:tests/Unit/Services/Crm/Pipedrive/ImportOpportunityMatchActivitiesTest.phptests/Unit/Services/Crm/Salesforce/ServiceTest.phptests/Unit/Services/Mail/0ffice/EmailApiClientTest.phptests/Unit/Services/RecallAI/RecallAIServiceTest.php113 files changed, 4143 insertions(+), 1740 deletions(-)create mode 120000 CLAUDE.mdcreate mode 100644 app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.phpdelete mode 100644 app/Component/ES/ElasticSearchWorkerManager.phpdelete mode 100644 app/Component/ES/Worker/ActivityWorker.phpdelete mode 100644 app/Component/ES/Worker/EntityWorker.phpdelete mode100644 app/Component/ES/Worker/WorkerAmount.phpdelete mode100644 app/Component/ES/Worker/WorkerInterface.phpcreate mode100644 app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.phtcreate mode100644 app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/Assembl:create mode100644 app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNot(create mode 100644 app/Console/Commands/Crm/Backfill0pportunityUserFromAccountCommand.phpdelete mode 100644 app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.phpcreate mode100644 front-end/src/components/shared/modals/EntityPickerModal/__tests__/us‹create mode 100644 tests/Feature/Component/Nudge/Process0rganisationImmediateNudgesJobTe:create mode 100644 tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheck‹delete mode 100644 tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/ActivityWorkerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/EntityWorkerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/WorkerAmountTest.phpcreate mode 100644 tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCr‹create mode 100644 tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.phpLukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ I|•HomeDMsActivityFilesLaterMore(ab)# Support Daily • in 2h 21 m100% <78•Wed 13 May12:39:23ED-→Describe what you are looking forJiminny ...curoaroylau# engineering# general# jiminny-bg# platform-tickets# product_launches#random# releases# sofia-office# support# thank-yous# the_people_of jimi...° Direct messages& Nikolay Ivanovdo James Graham. Stoyan Tanev. Galya DimitrovaP. Steliyan Georgievo Petko Kashinski®. Aneliya Angelovaã. Stefka Stoyanova•. Vasil Vasilev •!Lukas Kovalik y...l:: AppsJira CloudToastNikolay Ivanov6 0MessagesAdd canvas@ Files+Lukas Kovalik 11.Today ~мен все ме праща наhttps://app.vanta.com/c/jiminny.com/employee/onboardingNikolay Ivanov 11:01 AMХм, Джейс дали не може да ти помогне?Lukas Kovalik 11:01 AMще питам James, предполагам че нямам правада мерсиNikolay Ivanov 11:01 AMмдаМОЛЯLukas Kovalik 12:13 PMНики сори, още един въпрос имамкогато ги правеше ти FE ли оправяима vulnerabilities no npmNikolay Ivanov 12:28 PMнетях ги оставямLukas Kovalik 12:29 PMаз погледнах твоя тикет и там друго нямашесамо FEкак стигна до WorkerMessage Nikolay Ivanov...
|
32836
|
NULL
|
NULL
|
NULL
|
|
32840
|
1255
|
26
|
2026-05-13T09:39:24.295490+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665164295_m2.jpg...
|
PhpStorm
|
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Undo
Redo
Cut
Copy
Paste
Paste and Match Style
Sel Undo
Redo
Cut
Copy
Paste
Paste and Match Style
Select All...
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"Undo","depth":5,"bounds":{"left":0.27027926,"top":1.0,"width":0.03158245,"height":0.0},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Redo","depth":5,"bounds":{"left":0.27027926,"top":1.0,"width":0.03158245,"height":0.0},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Cut","depth":5,"bounds":{"left":0.27027926,"top":1.0,"width":0.03158245,"height":0.0},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Copy","depth":5,"bounds":{"left":0.27027926,"top":1.0,"width":0.03158245,"height":0.0},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Paste","depth":5,"bounds":{"left":0.27027926,"top":1.0,"width":0.03158245,"height":0.0},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Paste and Match Style","depth":5,"bounds":{"left":0.27027926,"top":1.0,"width":0.03158245,"height":0.0},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Select All","depth":5,"bounds":{"left":0.27027926,"top":1.0,"width":0.03158245,"height":0.0},"on_screen":false,"role_description":"text"}]...
|
1892201816994965258
|
7802479394038844655
|
click
|
hybrid
|
NULL
|
Undo
Redo
Cut
Copy
Paste
Paste and Match Style
Sel Undo
Redo
Cut
Copy
Paste
Paste and Match Style
Select All
PhostormProiectVIeWINavigareCodeLaravelKeractorJOOISWindowFV faVsco.js°9 master ~(C ActivityController.pnp|aravel.l0gA SF (jiminny@localhost]4 HS_local [jiminny@localhost]& console (PROD] X A console [EU]D Teaminsights, m Themesv D UserAutomatedRep -007final class ActivityController extends Controller implements CommentContextInterfaceA console [STAGING]v DV2c) ACuviLyvzconuroAskAnythingCorLL0/() AskJiminnyRepc© DealsV2Controll 410%(C) OnDemandV2Cc€ PlavlistControlleC) PlavlistSharecorC PlavlistTrackCor111131114(C) UoloadControlleC) [EMAIL]) AiCrmNotesControl(c) Racecontroller nhn@ ClientTokenControl 1157(e) CrmController.pnp11158© DealLevelPromptsC 1159c) DealRiskcontroller.@ InctantMeetinaCont 11611164C) Languagecontrolle© LayoutManagemen 1163Ca) livoCoodControllor1164 9© MeetingsController 1192© MessageController. 1193 l >C) MotadntoControllor L2141212 |159c) Mobilesettinasconi© MomentController.r 125gc Nudgecontroller.phNumberAllocatorCc 12/e11271OraanizationMembi 1212C) OraanizationRetentC) OraanizationSvnce@ PartnerController.o1276 1g) PlavbackController1133480 PlavlictController pl 1335g ScimController.nhn9) SidekickController , 13379a) SoftnhoneControlle© SsoController.php() CnbccrintionGontrae ToamAiAutomationte) ToamAiContovtCor0 ToamContrallor nhr 1343 (Q9 >public function ListActivitySearch(Request Srequest, SearchTransformen SsearchTransformer): JsonResponses: 569— 571* Deletes a saved search— 573* @param Request $request* apanam Search $search575* achrows except1or* drecurn Jsonkesponse578579— 580pubLic tunccion deleteActivicysearch kequest srequest, search ssearch: Jsonkesponse.582oubunc tunction uivelrequest srequest, clastcactIvirvkedosirory srepostrory: usonkesponse....* dparam Activitu Sactivitu*Gthrows_AuthorizationExcent.zon589* Greturn mixedpublic function show(Activity Sactivity, ActivityService $activityService): JsonResponse{...}public function createRecordingActivity Sactivity)i...h597593594public function updateRecording(Request Srequest, Activity $activity)i...h~ 596public function stopRecording(Activity Sactivity)(...}60€* Add activity to this user's favorites playlist_ 601=602* athrows AuthorizationException604public function favorite(Activity Sactivitv. PlavlistActivitvRepository SolavlistActivitvRepositorv): J501605606=607* Remove activitu from this user's favorites plaulisti60S•Goarom Actvatu sactvitu*athrowsAuthorizationExcent.ion* Greturn mixednublic function unfavorite Activity Sactivitv ?Tx: AutovCONCAT(u.id, CASE WHEN U.id = t.owner_id THEN ' (owner)' ELSE'' END) AS user_id,sa.*t.owner_id FROM social_accounts saNolN usens u on u.id e sa.sociablle i.diJOIN teams t .n<->l: on t.id = u.team_icWHERE u.team_id = 581 and sa.provider = 'salesforce';SELECT * FROM automated_report_results order by id desc;select * from features;select * from team_features where feature_id = 40;select * from teams where id = 556:select * from automated_reports:where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044"pat", "podcast"]SELECT * FROM automated report_ results WHERE uuid to bin( '822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;select * from automated_report_results order by za desc;SELECT * FROM automated report resultsWHEKE 10 =144select * from automated report results WHERE report id = 54:select * from opportunities where 1d = 7594349÷SELE * FROM teams WHERE name LIKE "%Les%': # 711, 692. 16067 - Timinnvintearationdlesmils.comselect * from playbooks where team id = 711: # event 226147SELEd * FROM Davbook catedonies WHERE Dlavbook 10 e 55151SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_typeSELECT * EROM eom fields WHERE 1d = 226147÷SELECT * EROM eom field values WHERE com field 1d = 226147.SELECT * FROM crm_configurations WHERE id = 692;SEISCTCONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '• END) AS user_id,nemailiSa.xt.owner id FROM social accounts saJOIN users u on u.id = sa.sociable idJOIN teams t 1..n<->1: on t.id = u.team_idWHERE U.team id = 711 and sa.provider = 'salesforce':SELECT * FROM crm profiles co JOIN users u 1..n<->1: on u.id = co.user id WHERE u.team_id = 711:select * from leads:select * from calendars:SELECTcascadeNew Cascade50 lihi7 & Support Daily - in 2h 21 m100% L2• Wed 13 May 12:39:23AskJiminnyReportActivityServiceTest v+0 ..So jiminny040 A1 A40 V 64 ^Cascade Code x .Kick off a new project. Make changes, Event Serialization Requirement ThC Fixing Automated Report Job Failur© Planhat Event Playback Investigationeed to review tha tocl"÷ @Code SWF-1.6UndoSerializesModels trait is necessary in the Automat... 22hpactePaste and Match StyleSelect AllOpen DevToolsWN Windsurf Toams 1120-1UTF.8Po 4 spaces...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
32846
|
1254
|
22
|
2026-05-13T09:39:42.955183+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665182955_m1.jpg...
|
PhpStorm
|
faVsco.js – ActivityController.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-7429716278976468786
|
-8636355650190325311
|
click
|
hybrid
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
SlackFileEditViewGoHistoryWindowHelp•APPDOCKERDEV (docker)₴82APP (-zshtests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleterTest.phptests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesProviderTest.phptests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesUploaderTest.phptests/Unit/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeeches?tests/Unit/Component/Transcription/Diarization/Source/MeetingBotSourceTest.phptests/Unit/Contracts/Services/Calendar/CalendarTraitTest.phptests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.phptests/Unit/Jobs/Activity/Import/ImportTwilioVideoSpeechesJobTest.phptests/Unit/Jobs/Activity/Import/IsActivityReadyForProcessingJobTest.phptests/Unit/Jobs/Calendar/SetupCalendarSyncTest.phptests/Unit/Services/Activity/ParticipantsServiceTest.phptests/Unit/Services/Calendar/Command/ImportParticipantsTest.phptests/Unit/Services/Calendar/GoogleCalendarServiceTest.phptests/Unit/Services/Crm/Close/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTest.phptests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTraitMatchActivitiesTest.phytests/Unit/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTraitOpportunitiesTe:tests/Unit/Services/Crm/Pipedrive/ImportOpportunityMatchActivitiesTest.phptests/Unit/Services/Crm/Salesforce/ServiceTest.phptests/Unit/Services/Mail/Office/EmailApiClientTest.phptests/Unit/Services/RecallAI/RecallAIServiceTest.php113 files changed, 4143 insertions(+), 1740 deletions(-)create mode 120000 CLAUDE.mdcreate mode 100644 app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.phpdelete mode 100644 app/Component/ES/ElasticSearchWorkerManager.phpdelete mode 100644 app/Component/ES/Worker/ActivityWorker.phpdelete mode 100644 app/Component/ES/Worker/EntityWorker.phpdelete mode100644 app/Component/ES/Worker/WorkerAmount.phpdelete mode100644 app/Component/ES/Worker/WorkerInterface.phpcreate mode100644 app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.phtcreate mode100644 app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/Assembl:create mode100644 app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNot(create mode 100644 app/Console/Commands/Crm/Backfill0pportunityUserFromAccountCommand.phydelete mode 100644 app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.phpcreate mode100644 front-end/src/components/shared/modals/EntityPickerModal/__tests__/uscreate mode 100644 tests/Feature/Component/Nudge/Process0rganisationImmediateNudgesJobTe:create mode 100644 tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheck‹delete mode 100644 tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/ActivityWorkerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/EntityWorkerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/WorkerAmountTest.phpcreate mode 100644 tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCr‹create mode 100644 tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.phpLukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ I|HomeDMsActivityFilesLaterMore§ Support Daily - in 2h 21 m100% (C478•Wed 13 May 12:39:42-→Describe what you are looking forJiminny ...Nikolay Ivanov6 0curoaroylau# engineering# general# jiminny-bg# platform-tickets# product_launches#random# releases# sofia-office# support# thank-yous# the_people_of jimi...• Messages+° Direct messages& Nikolay Ivanovdo James Graham. Stoyan Tanev. Galya Dimitrova. Steliyan Georgievo Petko Kashinski®. Aneliya Angelovaã. Stefka Stoyanova•. Vasil Vasilev •!Lukas Kovalik y...l:: AppsAdd canvasO FilesLukas Kovalik 11.Today ~мен все ме праща наhttps://app.vanta.com/c/jiminny.com/employee/onboardingNikolay Ivanov 11:01 AMХм, Джейс дали не може да ти помогне?Lukas Kovalik 11:01 AMще питам James, предполагам че нямам правада мерсиNikolay Ivanov 11:01 AMмдаМОЛЯLukas Kovalik 12:13 PMНики сори, още един въпрос имамкогато ги правеше ти FE ли оправяима vulnerabilities no npmNikolay Ivanov 12:28 PMнетях ги оставямLukas Kovalik 12:29 PMаз погледнах твоя тикет и там друго нямашесамо FEкак стигна до WorkerJira CloudMessage Nikolay IvanovToast...
|
32842
|
NULL
|
NULL
|
NULL
|
|
32847
|
1254
|
23
|
2026-05-13T09:39:45.660694+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665185660_m1.jpg...
|
PhpStorm
|
faVsco.js – ActivityController.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use Carbon\Carbon;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\In;
use Illuminate\Validation\ValidationException;
use InvalidArgumentException;
use Jiminny\Component\ActivityAnalytics;
use Jiminny\Component\ActivitySearch;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Queue\Constants;
use Jiminny\Contracts\ES\Events\UpdateSingleEntity;
use Jiminny\Contracts\ES\UpdateTargetEnum;
use Jiminny\Contracts\Nudge\NudgeFactoryInterface;
use Jiminny\Contracts\Playlist\PlaylistTrackFactoryInterface;
use Jiminny\Contracts\Repositories\PlaylistActivityRepository;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Enums\TeamSetting;
use Jiminny\Events\Activities\AiAutomation\ActivityProspectAdded;
use Jiminny\Events\Activities\Coaching\Coached;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Controllers\CommentContextInterface;
use Jiminny\Http\Responses\Api\AbstractResponse;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\ActivityCommentTransformer;
use Jiminny\Http\Transformers\ActivityTopicTriggerTransformer;
use Jiminny\Http\Transformers\ActivityTransformer;
use Jiminny\Http\Transformers\AvailabilityNotificationTransformer;
use Jiminny\Http\Transformers\CoachingFeedbackTransformer;
use Jiminny\Http\Transformers\CoachingSectionsTransformer;
use Jiminny\Http\Transformers\SearchTransformer;
use Jiminny\Http\Transformers\StatsTransformer;
use Jiminny\Jobs\Crm\SaveActivity;
use Jiminny\Jobs\Crm\UpdateStage;
use Jiminny\Jobs\Telephony\StartRecording;
use Jiminny\Jobs\Telephony\StopRecording;
use Jiminny\Jobs\Telephony\ToggleRecording;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\CoachingFeedback;
use Jiminny\Models\CoachingSection;
use Jiminny\Models\CoachingSectionCriterion;
use Jiminny\Models\CoachingSectionFeedback;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\LanguageDialect;
use Jiminny\Models\Lead;
use Jiminny\Models\Nudge;
use Jiminny\Models\PlaybookCategory;
use Jiminny\Models\Playlist;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\Track;
use Jiminny\Models\User;
use Jiminny\Repositories\CoachingFeedbackRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Rules\CrmReference;
use Jiminny\Rules\MultidimensionalArrayMaxCharRule;
use Jiminny\Services\ActivityService;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Services\PlaybackService;
use Jiminny\Services\UserService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
use Ramsey\Uuid\Uuid;
use Sentry;
use Symfony\Component\HttpFoundation;
final class ActivityController extends Controller implements CommentContextInterface
{
// Number of minutes to look back on activities. i.e. a timeout on activity duration.
private const int LOOK_BACK = 180;
public function __construct(
private ProviderRegistry $providerRegistry,
private ActivityService $activityService,
Response $response,
private UserService $userService,
private ActivitySearch\Service\ActivitySearch $activitySearch,
private NudgeFactoryInterface $nudgeFactory,
private ActivityCommentService $activityCommentService,
private LoggerInterface $logger,
private readonly CoachingFeedbackRepository $coachingFeedbackRepository,
private readonly TeamRepository $teamRepository,
) {
parent::__construct($response);
}
public static function getCommentImplementation(): string
{
return Comment::class;
}
public function delete()
{
$this->request->validate([
'*' => 'uuid:activities',
]);
$deletedIds = [];
foreach ($this->request->all() as $activityId) {
$activity = Activity::idOrUuId($activityId);
try {
if ($this->authorize('delete', $activity)) {
$activity->delete();
$deletedIds[] = $activityId;
\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);
}
} catch (AuthorizationException $authorizationException) {
// They didn't have permission.
}
}
return $this->response->withArray($deletedIds);
}
public function update(Request $request, Activity $activity)
{
$this->authorize('updateMetadata', $activity);
$request->validate([
'title' => 'string|max:250',
'category_id' => 'uuid:playbook_categories',
'language' => [
new In(
LanguageDialect::query()
->with('language')
->cursor()
->map(static function (LanguageDialect $languageDialect): string {
return $languageDialect->getLanguageLocale();
})
->all()
),
],
]);
if ($request->has('title')) {
$activity->title = $request->input('title');
}
if ($request->has('category_id')) {
$category = PlaybookCategory::uuid($request->input('category_id'));
if ($category->playbook->team_id !== $request->user()->team_id) {
return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
if ($request->has('language')) {
if (! $activity->isInProgress()) {
return $this->response->withError(
'Activity language can only be set while the meeting is in progress.',
400
);
}
$activity->setLanguageCode($request->input('language'));
}
$activity->save();
return $this->response->withOk();
}
// XXX: This should be merged with the update method.
/**
* @param Activity $activity
*
* @throws AuthorizationException
* @throws SocialAccountTokenInvalidException
*
* @return mixed
*/
public function summarize(Activity $activity): mixed
{
$this->logger->info('[Log Activity] Summarizing activity ', [
'activityId' => $activity->getUuid(),
'payload' => $this->request->all(),
]);
$this->authorize('update', $activity);
$this->logger->info('[Log Activity] Validating summary');
// Validate the payload.
$this->validateSummary($activity);
// All objects must belong to this team.
/** @var User $user */
$user = $this->request->user();
$team = $user->getTeam();
$crmService = $this->providerRegistry->get($team->crm->provider);
try {
$crmUser = $user;
if ($user->isCrmRequired() === false) {
$crmUser = $team->owner;
}
$crmService->setUser($crmUser);
} catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());
}
$rawEntities = $this->request->input('entities');
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid(
$this->request->input('layout_id')
);
// Delay execution of CRM jobs to avoid locking issues.
$jobDelay = 0;
// If we have arrived from a notification, mark it as read.
$notificationId = $this->request->input('nId');
if ($notificationId) {
$notification = $user->unreadNotifications->where('id', $notificationId)->first();
if ($notification) {
$notification->markAsRead();
}
}
$title = $this->request->input('title');
$prospects = $this->request->input('prospects');
$opportunityId = $this->request->input('opportunity_id');
$stageId = $this->request->input('stage_id');
$categoryId = $this->request->input('category_id');
$summary = $this->request->input('summary');
$crmProviderId = $this->request->input('crm_id');
$isInternal = $this->request->input('is_internal') ?? false;
$lead = null;
$category = null;
$account = null;
$contact = null;
$opportunity = null;
$stage = null;
$callStage = null;
foreach ($prospects as $prospectData) {
$objectId = $prospectData['id'];
if ($objectId === null) {
continue;
}
$objectType = $prospectData['type'];
$this->logger->info('debug', ['prospect_data' => $prospectData]);
try {
if ($objectType === null) {
$this->logger->info('no object type');
if ($crmService instanceof SupportsObjectTypeParseInterface) {
$objectType = $crmService->parseObjectType($objectId);
}
}
switch ($objectType) {
case 'lead':
$this->logger->info('Processing lead');
/** @var Lead|null $lead */
$lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();
// Lead does not exist locally, import it.
if ($lead === null) {
$this->logger->info('Lead does not exist locally');
/** @var Lead $lead */
$lead = $crmService->syncLead($objectId);
}
$this->logger->info('Lead found', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
if ($stageId === null) {
$this->logger->info('Stage ID is null');
// If it was not provided, just assume it is the current stage.
$callStage = $lead->stage;
break;
}
$this->logger->info('Looking for stage');
// Determine if they have changed the stage.
/** @var Stage $stage */
$stage = $team->crm->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_LEAD)
->firstOrFail();
$this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);
if ($lead->stage_id && $lead->stage_id !== $stage->id) {
$this->logger->info('Stage has changed');
// Storage current stage on activity.
$callStage = $lead->stage;
// The stage has changed, update in remote CRM.
dispatch(new UpdateStage($activity, $lead, $callStage, $stage));
$this->logger->info(
sprintf(
'[%s] User changing lead stage from %s to %s',
$crmService->getDisplayName(),
$callStage->getName(),
$stage->getName()
),
[
'user' => $user->getUuid(),
'lead' => $lead->getUuid(),
]
);
} else {
$this->logger->info('Stage has not changed');
// Stage remains as current.
$callStage = $stage;
}
break;
case 'account':
$this->logger->info('Processing account');
// If the object is not a lead, it should be an account.
$account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();
// Account does not exist locally, import it.
if ($account === null) {
$this->logger->info('Account does not exist locally');
$account = $crmService->syncAccount($objectId);
}
$this->logger->info('Account found', ['accountId' => $account->id]);
break;
case 'contact':
$this->logger->info('processing contact');
$contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$this->logger->info('contact does not exist locally');
$contact = $crmService->syncContact($objectId);
}
$this->logger->info('resolving account');
$account = $this->resolveAccount($team, $contact, $crmService, $prospects);
break;
}
// If they have specified an opportunity, retrieve this with stage.
if ($opportunityId) {
$this->logger->info('opportunity id is set');
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if ($opportunity === null) {
$this->logger->info('opportunity does not exist locally');
$opportunity = $crmService->syncOpportunity($opportunityId);
}
if ($stageId === null) {
$this->logger->info('stage id is null');
// If it was not provided, just assume it is the current stage.
$callStage = $opportunity->stage ?? null;
} else {
$this->logger->info('looking for stage');
/** @var ?Stage $opportunityStage */
$opportunityStage = $team->crm
->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
// There is a chance we still cannot import this opportunity.
if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {
$this->logger->info('opportunity stage has changed');
// Storage current stage on activity.
$callStage = $opportunity->stage;
dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));
$this->logger->info(
sprintf(
'[%s] User changing opportunity stage from %s to %s',
$crmService->getDisplayName(),
$callStage->name,
$opportunityStage->name
),
[
'userId' => $user->id_string,
'opportunityId' => $opportunity->id_string,
]
);
} else {
$this->logger->info('opportunity stage has not changed');
// Stage remains as current.
$callStage = $opportunityStage;
}
}
}
if ($crmProviderId) {
// Cast $crmProviderId to string otherwise it won't use database index for some records
$linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();
// Check if this activity has already been assigned to a different activity.
if ($linkedActivity && $linkedActivity->id !== $activity->id) {
throw new InvalidArgumentException(
'Sorry, the linked task has already been logged under a different call. '
. 'Please choose another linked task.'
);
}
}
} catch (InvalidArgumentException $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($exception->getMessage());
} catch (Exception $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorInternalError(
'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'
);
}
}
if ($categoryId) {
$category = PlaybookCategory::uuid($categoryId);
if ($category->playbook->team_id !== $team->id) {
throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
$this->logger->info('Prospect data', [
'lead_id' => $lead?->getId(),
'account_id' => $account?->getId(),
'contact_id' => $contact?->getId(),
'opportunity_id' => $opportunity?->getId(),
'stage_id' => $stage?->getId(),
]);
if ($title) {
$activity->title = $title;
}
if ($summary) {
$activity->summary = $summary;
}
if ($crmProviderId) {
$activity->crm_provider_id = $crmProviderId;
}
if ($callStage) {
$this->logger->info('Setting stage id', ['stageId' => $callStage->id]);
$activity->stage_id = $callStage->id;
}
if ($lead) {
$this->logger->info('Setting lead id', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
// If we are changed from an account > lead, unset the account data.
$this->logger->info('Unsetting account id, opportunity id, contact id, value');
$activity->account_id = null;
$activity->opportunity_id = null;
$activity->contact_id = null;
$activity->value = null;
}
if ($account) {
$this->logger->info('Setting account id', ['accountId' => $account->id]);
$activity->account_id = $account->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('unsetting lead id');
$activity->lead_id = null;
// Unset the contact if switching different accounts. Will be set up below if still applicable.
if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {
$this->logger->info('Unsetting contact id');
$activity->contact_id = null;
}
}
if ($opportunity) {
$this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);
$this->logger->info('unsetting lead id');
$activity->opportunity_id = $opportunity->id;
$activity->value = $opportunity->value;
// If we are changed from an lead > account, unset the lead data.
$activity->lead_id = null;
}
if ($contact) {
$this->logger->info('setting contact id', ['contactId' => $contact->id]);
$activity->contact_id = $contact->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('Unsetting lead id');
$activity->lead_id = null;
}
$activity->is_internal = $isInternal;
$activity->save();
$activity->refresh();
$this->logger->notice('Activity saved', [
'activity_id' => $activity->getId(),
'lead_id' => $activity->lead_id,
'account_id' => $activity->account_id,
'contact_id' => $activity->contact_id,
'opportunity_id' => $activity->opportunity_id,
'stage_id' => $activity->stage_id,
'crm_provider_id' => $activity->getCrmProviderId(),
]);
// Store entities as field data on the activity.
$updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);
if ($activity->isLoggable()) {
// Follow-up Task or Event data.
$followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);
$this->logger->info('CRM LOG manual log triggered', [
'activityId' => $activity->getUuid(),
'followupData' => $followupData,
'userId' => $user->getUuid(),
]);
// Store data in the CRM.
// ++add check for crm_required
$job = new SaveActivity($activity, $followupData);
if ($updatedData) {
$job->delay(Carbon::now()->addMinutes($jobDelay));
}
dispatch($job);
// Manually dispatch log for Opportunity or Prospect added
if ($activity->hasOpportunity() || $activity->hasProspect()) {
event(new ActivityProspectAdded(
activity: $activity,
eventSource: 'manually-log-crm-data'
));
}
}
return $this->response->withOk();
}
/**
* Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.
*
* @param ServiceInterface $service
* @param Activity $activity
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array
{
$updatedData = [];
$existingData = $activity->data()->get();
// We need to delete any existing data to overwrite with latest values.
$activity->data()->delete();
$layoutEntities = $layout->entities()
->with('field', 'parent')
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->get();
/** @var LayoutEntity $entity */
foreach ($layoutEntities as $entity) {
// If the user has provided a value for this entity
if (array_key_exists($entity->id_string, $entities)) {
$value = $entities[$entity->id_string];
// Convert raw data into values that the CRM can consume.
if ($value) {
$value = $service->normalizeValue($entity->field->type, $value);
}
// Check the field is part of the activity-summary section.
if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {
// This is the internal database ID, not the external CRM ID.
$objectId = null;
switch ($entity->field->object_type) {
case Field::OBJECT_ACCOUNT:
$objectId = $activity->account_id;
break;
case Field::OBJECT_CONTACT:
$objectId = $activity->contact_id;
break;
case Field::OBJECT_OPPORTUNITY:
$objectId = $activity->opportunity_id;
break;
case Field::OBJECT_LEAD:
$objectId = $activity->lead_id;
break;
case Field::OBJECT_TASK:
case Field::OBJECT_EVENT:
$objectId = $activity->id;
break;
}
if ($objectId) {
/** @var FieldData $data */
$data = $activity->data()->create([
'crm_layout_entity_id' => $entity->id,
'crm_field_id' => $entity->crm_field_id,
'object_type' => $entity->field->object_type,
'object_id' => $objectId,
'value' => $value,
]);
// Never send read-only field data to the CRM.
if ($entity->read_only === false && $entity->is_visible) {
$existingValue = $existingData
->where('crm_layout_entity_id', $entity->id)
->where('crm_field_id', $entity->crm_field_id)
->where('object_type', $entity->field->object_type)
->where('object_id', $objectId)
->first();
// If the field was actually changed, we need to reflect this in the CRM too.
if ($existingValue === null || $existingValue->value !== $value) {
$updatedData[] = $data->id;
}
}
}
}
}
}
return $updatedData;
}
/**
* Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.
*
* @param ServiceInterface $crmService
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array
{
$fieldData = [];
foreach ($entities as $entityId => $value) {
// Only bother with fields that have a value.
if ($value) {
// Extract the entity from the UUID. Check the field is valid and part of the follow-up section.
$entity = $layout->entities()
->uuid($entityId, false)
->whereHas('parent', function ($query) {
$query->where('label', 'follow-up');
})
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->first();
if ($entity) {
// Convert raw data into values that the CRM can consume.
$value = $crmService->normalizeValue($entity->field->type, $value);
// Add the field and value to the payload.
$fieldData += [
$entity->field->crm_provider_id => $value,
];
}
}
}
return $fieldData;
}
/**
* @param Activity $activity
*/
private function validateSummary(Activity $activity): void
{
$team = $activity->user->team;
$crmProvider = $team->crm->provider;
$attributes = [];
$rules = [
'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,
'title' => 'string|max:250',
'prospects' => 'required|array',
'opportunity_id' => new CrmReference($crmProvider),
'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',
'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator
'summary' => 'max:50000',
'nId' => 'exists:notifications,id',
'crm_id' => new CrmReference($crmProvider),
'entities' => 'array',
'is_internal' => 'boolean',
];
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));
// Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.
$entities = $layout->entities()
->where('read_only', 0)
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->whereHas('parent', function ($query) use ($activity) {
if ($activity->isLoggable() === false) {
$query->where('label', '<>', 'follow-up');
}
});
$isInternal = $this->request->input('is_internal', false);
foreach ($entities->get() as $entity) {
$rules += $this->buildFieldValidator($entity, $isInternal);
$attributes += $this->buildFieldMessage($entity);
}
$this->request->validate($rules, [], $attributes);
}
private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array
{
return [
'entities.' . $entity->id_string => $entity->getValidator($isInternal),
];
}
/**
* @param LayoutEntity $entity
*
* @return array
*/
private function buildFieldMessage(LayoutEntity $entity): array
{
$label = $entity->label;
if ($label === null) {
$label = $entity->field->label;
}
return [
'entities.' . $entity->id_string => $label,
];
}
public function search(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->debugLog(
$user,
'User extracted from request',
['user' => $user->getId(), 'tz' => $user->getTimezone()]
);
$searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());
$this->debugLog(
$user,
'ActivitySearch criteria built',
['searchCriteria' => $searchCriteria]
);
$filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);
$this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);
$this->validateSearch($request, $filterSet);
$this->debugLog($user, 'Request validated');
$searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);
/** @var Collection<Activity> $activities */
$activities = $searchResponse['results'];
$this->debugLog($user, 'Activities ES response extracted');
$hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(
$user->getTeamId(),
TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),
);
if ($hideInternalMeetingsSetting?->getValue() === '1') {
$activities = $activities->filter(function (Activity $activity) {
if ($activity->is_internal && empty($activity->actual_start_time)) {
return false;
}
return true;
});
}
$this->debugLog($user, 'Internal meetings (?!) filtered');
$this->response->getManager()
->parseIncludes([
'category',
'organizer.group',
'prospect',
'stage',
'opportunity',
'stats',
'scorecards',
'masterTrack',
'activeParticipants',
'notification',
])
->setSerializer(new JsonSerializer());
$transformerExcludes = $this->request->input('exclude');
if ($transformerExcludes) {
$this->response->getManager()->parseExcludes($transformerExcludes);
}
$this->debugLog($user, 'Response Manager (?!) applied');
$transformer = new ActivityTransformer();
$transformer->setConsumer($user);
$this->debugLog($user, 'Activity Transformer added');
$resource = new \League\Fractal\Resource\Collection($activities, $transformer);
$page = $searchCriteria->getPageNumber();
$this->debugLog($user, 'Search criteria page number called', ['page' => $page]);
$histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');
$this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);
return $this->response->withArray([
'pagination' => [
'total' => $searchResponse['totalHits'],
'current' => $page,
'prev' => max($page - 1, 1),
'next' => $page + 1,
],
'results' => $this->response->getManager()->createData($resource)->toArray(),
'histogram' => $histogram,
]);
}
private function debugLog(User $user, string $logMessage, ?array $context = []): void
{
// Debug for Learning People Only
if ($user->getTeamId() !== 260) {
return;
}
Log::notice(
sprintf('[activity-search-controller] %s', $logMessage),
$context
);
}
/** @throws ValidationException */
private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void
{
$rules = [
'exclude' => 'array',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
];
if ($prefix !== null && mb_strpos($prefix, '.') !== false) {
$rules[rtrim($prefix, '.')] = sprintf(
'required|array|max:%d',
$filterSet->count()
);
}
$validationRules = $filterSet->getValidationRules($prefix)
->merge($rules)
->all();
$request->validate($validationRules);
}
public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$search = $this->updateOrCreateActivitySearch($request);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function updateActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('update', $search);
$this->updateOrCreateActivitySearch($request, $search);
return $this->response->withOk();
}
private function storeNamedSearchFilters(
Collection $request,
Search $search,
FilterDefinitionCollection $filterSet,
?string $prefix = null,
): self {
$arrayTypeProperties = $filterSet
->getPropertyTypes([
FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,
])
->all();
$supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);
foreach ($supportedRequestProperties as $requestPropertyName) {
if (! array_has($request, $requestPropertyName)) {
continue;
}
/** @var string|string[] $propertyValue */
$propertyValue = array_get($request, $requestPropertyName);
$propertyName = $prefix === null
? $requestPropertyName
: mb_substr($requestPropertyName, mb_strlen($prefix));
$isArrayType = array_has($arrayTypeProperties, $propertyName);
if (! $isArrayType) {
/** @var string $requestPropertyValue */
$search->filters()->updateOrCreate(
[
'filter' => $propertyName,
],
[
'value' => $propertyValue,
]
);
continue;
}
/** @var string[] $requestPropertyValue */
/** @var SearchFilter[]|Collection $existingFilterValues */
$existingFilterValuesKeyed = $search->filters()
->where('filter', $propertyName)
->get()
->keyBy('id');
// Iterate over values provided as request parameters
foreach ($propertyValue as $value) {
/** @var SearchFilter|null $valueFilter */
$valueFilter = $search->filters()
->where(
[
'filter' => $propertyName,
'value' => $value,
]
)
->first();
if ($valueFilter !== null) {
// Remove filter value pair from list to be deleted
$existingFilterValuesKeyed->forget($valueFilter->id);
} else {
// Add new filter/value pair
$search->filters()->updateOrCreate([
'filter' => $propertyName,
'value' => $value,
]);
}
}
// Delete filter value pairs for this filter that no longer exist in request parameters
foreach ($existingFilterValuesKeyed as $existingFilter) {
$existingFilter->delete();
}
}
/** @var Collection<int, SearchFilter> $filtersKeyed */
$filtersKeyed = $search->filters()->get()->keyBy('filter');
// wipe removed filters from this search
foreach ($filtersKeyed as $filterName => $filter) {
if (array_has($request, $prefix . $filterName)) {
continue;
}
// Remove all filter values for this filter
$search->filters()->where('filter', $filterName)->delete();
}
return $this;
}
/**
* @throws AuthorizationException
*/
public function fetchActivitySearch(
Search $search,
Request $request,
SearchTransformer $searchTransformer,
): JsonResponse {
$this->authorize('view', $search);
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withCollection(
$user->searches()->get(),
$searchTransformer
->withConsumer($user)
);
}
/**
* Deletes a saved search
*
* @param Request $request
* @param Search $search
*
* @throws Exception
*
* @return JsonResponse
*/
public function deleteActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('delete', $search);
// Orphan any AutomatedReports that use this search
$search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);
// Delete filters and the search itself
$search->filters()->delete();
$search->delete();
return $this->response->withOk();
}
public function live(Request $request, ElasticActivityRepository $repository): JsonResponse
{
$user = $this->getUserFromRequest($request);
$this->request->validate([
'sort_direction' => 'in:asc,desc',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
]);
$activities = $repository->getLiveCoachingEligibleActivities(
user: $user,
lookBackMinutes: self::LOOK_BACK,
limit: (int) $this->request->input('limit', 25),
page: (int) $this->request->input('page', 1),
sortBy: ['actual_start_time', 'scheduled_start_time'],
sortDirection: (string) $this->request->input('sort_direction', 'asc'),
);
$this->response
->getManager()
->parseIncludes(['organizer.group', 'prospect'])
->setSerializer(new JsonSerializer());
return $this->response->withCollection($activities, new ActivityTransformer());
}
/**
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function show(Activity $activity, ActivityService $activityService): JsonResponse
{
$this->authorize('show', $activity);
$user = $activity->getUser();
$team = $user->getTeam();
// Sync the opportunity with the latest data if possible.
if ($activity->opportunity_id) {
try {
$crmService = $this->providerRegistry->get($team->crm->provider);
if (! $user->isCrmRequired()) {
$crmService->setUser($team->getOwner());
} else {
$crmService->setUser($user);
}
$crmService->syncOpportunity($activity->opportunity->crm_provider_id);
} catch (Exception $exception) {
// Move on.
}
}
$activityData = $activityService->getActivityData($this->request->user(), $activity);
return response()->json($activityData);
}
public function createRecording(Activity $activity)
{
$this->authorize('record', $activity);
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Tell Twilio to start recording this activity.
if ($activity->recording_state === Activity::RECORDING_OFF) {
$job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withCreated();
}
return $this->response->errorGone('Activity is already recording.');
}
public function updateRecording(Request $request, Activity $activity)
{
$this->authorize('record', $activity);
$request->validate([
'preference' => 'boolean',
'state' => [
'string',
Rule::in([
Activity::RECORDING_IN_PROGRESS,
Activity::RECORDING_PAUSED,
]),
],
]);
if ($request->has('state')) {
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Toggle the recording state between paused and resumed.
if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {
$job = (new ToggleRecording($activity, $request->input('state')))
->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Recording is not toggleable.');
}
if ($request->has('preference')) {
$activity->update([
'recording_preference' => $request->input('preference') ? 1 : 0,
]);
return $this->response->withOk();
}
return $this->response->errorWrongArgs('Something went wrong');
}
public function stopRecording(Activity $activity)
{
$this->authorize('stopRecord', $activity);
// Tell Twilio to stop recording this activity.
if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {
$job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Activity is not recording.');
}
/**
* Add activity to this user's favorites playlist
*
* @throws AuthorizationException
*/
public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse
{
$this->authorize('favorite', $activity);
$user = $this->getUserFromRequest($this->request);
$favorite = $activity->wasFavoritedBy($user);
$name = $activity->activity_title ?? '';
// It needs to check at least one record.
if (! $favorite) {
$favoritePlaylist = $user->favoritePlaylist();
$playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(
$activity,
$user,
$favoritePlaylist
);
if ($playlistActivity !== null) {
$playlistActivity->update(
// Just update, don't sort.
['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],
);
} else {
$playlistActivity = $activity->playlistActivities()->create([
'playlist_id' => $favoritePlaylist->getId(),
'user_id' => $user->getId(),
'start_time' => 0,
'name' => mb_strimwidth($name, 0, 100),
]);
// Sort it on top.
$playlistActivity->update(
[
'sort' => $playlistActivityRepository->calculateNewSortOrder(
null,
$playlistActivity,
),
],
);
}
$playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);
return new JsonResponse([], JsonResponse::HTTP_CREATED);
}
return new JsonResponse(
[
'error' => [
'code' => AbstractResponse::CODE_CONFLICT,
'http_code' => JsonResponse::HTTP_CONFLICT,
'message' => 'Resource Already Exists',
],
],
JsonResponse::HTTP_CONFLICT,
);
}
/**
* Remove activity from this user's favorites playlist
*
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function unfavorite(Activity $activity)
{
$user = $t...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"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":"Analyzing…","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 Carbon\\Carbon;\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Exception;\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Validation\\Rule;\nuse Illuminate\\Validation\\Rules\\In;\nuse Illuminate\\Validation\\ValidationException;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ActivityAnalytics;\nuse Jiminny\\Component\\ActivitySearch;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Contracts\\ES\\Events\\UpdateSingleEntity;\nuse Jiminny\\Contracts\\ES\\UpdateTargetEnum;\nuse Jiminny\\Contracts\\Nudge\\NudgeFactoryInterface;\nuse Jiminny\\Contracts\\Playlist\\PlaylistTrackFactoryInterface;\nuse Jiminny\\Contracts\\Repositories\\PlaylistActivityRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Enums\\TeamSetting;\nuse Jiminny\\Events\\Activities\\AiAutomation\\ActivityProspectAdded;\nuse Jiminny\\Events\\Activities\\Coaching\\Coached;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Controllers\\CommentContextInterface;\nuse Jiminny\\Http\\Responses\\Api\\AbstractResponse;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\ActivityCommentTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTopicTriggerTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTransformer;\nuse Jiminny\\Http\\Transformers\\AvailabilityNotificationTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingFeedbackTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingSectionsTransformer;\nuse Jiminny\\Http\\Transformers\\SearchTransformer;\nuse Jiminny\\Http\\Transformers\\StatsTransformer;\nuse Jiminny\\Jobs\\Crm\\SaveActivity;\nuse Jiminny\\Jobs\\Crm\\UpdateStage;\nuse Jiminny\\Jobs\\Telephony\\StartRecording;\nuse Jiminny\\Jobs\\Telephony\\StopRecording;\nuse Jiminny\\Jobs\\Telephony\\ToggleRecording;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\CoachingFeedback;\nuse Jiminny\\Models\\CoachingSection;\nuse Jiminny\\Models\\CoachingSectionCriterion;\nuse Jiminny\\Models\\CoachingSectionFeedback;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\LanguageDialect;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Nudge;\nuse Jiminny\\Models\\PlaybookCategory;\nuse Jiminny\\Models\\Playlist;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\Track;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\CoachingFeedbackRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Rules\\MultidimensionalArrayMaxCharRule;\nuse Jiminny\\Services\\ActivityService;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Services\\PlaybackService;\nuse Jiminny\\Services\\UserService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\nuse Ramsey\\Uuid\\Uuid;\nuse Sentry;\nuse Symfony\\Component\\HttpFoundation;\n\nfinal class ActivityController extends Controller implements CommentContextInterface\n{\n // Number of minutes to look back on activities. i.e. a timeout on activity duration.\n private const int LOOK_BACK = 180;\n\n public function __construct(\n private ProviderRegistry $providerRegistry,\n private ActivityService $activityService,\n Response $response,\n private UserService $userService,\n private ActivitySearch\\Service\\ActivitySearch $activitySearch,\n private NudgeFactoryInterface $nudgeFactory,\n private ActivityCommentService $activityCommentService,\n private LoggerInterface $logger,\n private readonly CoachingFeedbackRepository $coachingFeedbackRepository,\n private readonly TeamRepository $teamRepository,\n ) {\n parent::__construct($response);\n }\n\n public static function getCommentImplementation(): string\n {\n return Comment::class;\n }\n\n public function delete()\n {\n $this->request->validate([\n '*' => 'uuid:activities',\n ]);\n\n $deletedIds = [];\n foreach ($this->request->all() as $activityId) {\n $activity = Activity::idOrUuId($activityId);\n\n try {\n if ($this->authorize('delete', $activity)) {\n $activity->delete();\n $deletedIds[] = $activityId;\n\n \\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n }\n } catch (AuthorizationException $authorizationException) {\n // They didn't have permission.\n }\n }\n\n return $this->response->withArray($deletedIds);\n }\n\n public function update(Request $request, Activity $activity)\n {\n $this->authorize('updateMetadata', $activity);\n\n $request->validate([\n 'title' => 'string|max:250',\n 'category_id' => 'uuid:playbook_categories',\n 'language' => [\n new In(\n LanguageDialect::query()\n ->with('language')\n ->cursor()\n ->map(static function (LanguageDialect $languageDialect): string {\n return $languageDialect->getLanguageLocale();\n })\n ->all()\n ),\n ],\n ]);\n\n if ($request->has('title')) {\n $activity->title = $request->input('title');\n }\n\n if ($request->has('category_id')) {\n $category = PlaybookCategory::uuid($request->input('category_id'));\n\n if ($category->playbook->team_id !== $request->user()->team_id) {\n return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n if ($request->has('language')) {\n if (! $activity->isInProgress()) {\n return $this->response->withError(\n 'Activity language can only be set while the meeting is in progress.',\n 400\n );\n }\n\n $activity->setLanguageCode($request->input('language'));\n }\n\n $activity->save();\n\n return $this->response->withOk();\n }\n\n // XXX: This should be merged with the update method.\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws SocialAccountTokenInvalidException\n *\n * @return mixed\n */\n public function summarize(Activity $activity): mixed\n {\n $this->logger->info('[Log Activity] Summarizing activity ', [\n 'activityId' => $activity->getUuid(),\n 'payload' => $this->request->all(),\n ]);\n $this->authorize('update', $activity);\n\n $this->logger->info('[Log Activity] Validating summary');\n // Validate the payload.\n $this->validateSummary($activity);\n\n // All objects must belong to this team.\n /** @var User $user */\n $user = $this->request->user();\n $team = $user->getTeam();\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n try {\n $crmUser = $user;\n if ($user->isCrmRequired() === false) {\n $crmUser = $team->owner;\n }\n $crmService->setUser($crmUser);\n } catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());\n }\n\n $rawEntities = $this->request->input('entities');\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid(\n $this->request->input('layout_id')\n );\n\n // Delay execution of CRM jobs to avoid locking issues.\n $jobDelay = 0;\n\n // If we have arrived from a notification, mark it as read.\n $notificationId = $this->request->input('nId');\n if ($notificationId) {\n $notification = $user->unreadNotifications->where('id', $notificationId)->first();\n\n if ($notification) {\n $notification->markAsRead();\n }\n }\n\n $title = $this->request->input('title');\n $prospects = $this->request->input('prospects');\n $opportunityId = $this->request->input('opportunity_id');\n $stageId = $this->request->input('stage_id');\n $categoryId = $this->request->input('category_id');\n $summary = $this->request->input('summary');\n $crmProviderId = $this->request->input('crm_id');\n $isInternal = $this->request->input('is_internal') ?? false;\n\n $lead = null;\n $category = null;\n $account = null;\n $contact = null;\n $opportunity = null;\n $stage = null;\n $callStage = null;\n\n foreach ($prospects as $prospectData) {\n $objectId = $prospectData['id'];\n\n if ($objectId === null) {\n continue;\n }\n\n $objectType = $prospectData['type'];\n $this->logger->info('debug', ['prospect_data' => $prospectData]);\n\n try {\n if ($objectType === null) {\n $this->logger->info('no object type');\n if ($crmService instanceof SupportsObjectTypeParseInterface) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n }\n\n switch ($objectType) {\n case 'lead':\n $this->logger->info('Processing lead');\n /** @var Lead|null $lead */\n $lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();\n\n // Lead does not exist locally, import it.\n if ($lead === null) {\n $this->logger->info('Lead does not exist locally');\n /** @var Lead $lead */\n $lead = $crmService->syncLead($objectId);\n }\n\n $this->logger->info('Lead found', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n if ($stageId === null) {\n $this->logger->info('Stage ID is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $lead->stage;\n\n break;\n }\n\n $this->logger->info('Looking for stage');\n // Determine if they have changed the stage.\n /** @var Stage $stage */\n $stage = $team->crm->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_LEAD)\n ->firstOrFail();\n\n $this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);\n if ($lead->stage_id && $lead->stage_id !== $stage->id) {\n $this->logger->info('Stage has changed');\n // Storage current stage on activity.\n $callStage = $lead->stage;\n\n // The stage has changed, update in remote CRM.\n dispatch(new UpdateStage($activity, $lead, $callStage, $stage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing lead stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->getName(),\n $stage->getName()\n ),\n [\n 'user' => $user->getUuid(),\n 'lead' => $lead->getUuid(),\n ]\n );\n } else {\n $this->logger->info('Stage has not changed');\n // Stage remains as current.\n $callStage = $stage;\n }\n\n break;\n\n case 'account':\n $this->logger->info('Processing account');\n // If the object is not a lead, it should be an account.\n $account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();\n\n // Account does not exist locally, import it.\n if ($account === null) {\n $this->logger->info('Account does not exist locally');\n $account = $crmService->syncAccount($objectId);\n }\n\n $this->logger->info('Account found', ['accountId' => $account->id]);\n\n break;\n case 'contact':\n $this->logger->info('processing contact');\n $contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $this->logger->info('contact does not exist locally');\n $contact = $crmService->syncContact($objectId);\n }\n\n $this->logger->info('resolving account');\n $account = $this->resolveAccount($team, $contact, $crmService, $prospects);\n\n break;\n }\n\n // If they have specified an opportunity, retrieve this with stage.\n if ($opportunityId) {\n $this->logger->info('opportunity id is set');\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if ($opportunity === null) {\n $this->logger->info('opportunity does not exist locally');\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n if ($stageId === null) {\n $this->logger->info('stage id is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $opportunity->stage ?? null;\n } else {\n $this->logger->info('looking for stage');\n /** @var ?Stage $opportunityStage */\n $opportunityStage = $team->crm\n ->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n // There is a chance we still cannot import this opportunity.\n if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {\n $this->logger->info('opportunity stage has changed');\n // Storage current stage on activity.\n $callStage = $opportunity->stage;\n\n dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing opportunity stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->name,\n $opportunityStage->name\n ),\n [\n 'userId' => $user->id_string,\n 'opportunityId' => $opportunity->id_string,\n ]\n );\n } else {\n $this->logger->info('opportunity stage has not changed');\n // Stage remains as current.\n $callStage = $opportunityStage;\n }\n }\n }\n\n if ($crmProviderId) {\n // Cast $crmProviderId to string otherwise it won't use database index for some records\n $linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();\n\n // Check if this activity has already been assigned to a different activity.\n if ($linkedActivity && $linkedActivity->id !== $activity->id) {\n throw new InvalidArgumentException(\n 'Sorry, the linked task has already been logged under a different call. '\n . 'Please choose another linked task.'\n );\n }\n }\n } catch (InvalidArgumentException $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($exception->getMessage());\n } catch (Exception $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorInternalError(\n 'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'\n );\n }\n }\n\n if ($categoryId) {\n $category = PlaybookCategory::uuid($categoryId);\n\n if ($category->playbook->team_id !== $team->id) {\n throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n $this->logger->info('Prospect data', [\n 'lead_id' => $lead?->getId(),\n 'account_id' => $account?->getId(),\n 'contact_id' => $contact?->getId(),\n 'opportunity_id' => $opportunity?->getId(),\n 'stage_id' => $stage?->getId(),\n ]);\n\n if ($title) {\n $activity->title = $title;\n }\n\n if ($summary) {\n $activity->summary = $summary;\n }\n\n if ($crmProviderId) {\n $activity->crm_provider_id = $crmProviderId;\n }\n\n if ($callStage) {\n $this->logger->info('Setting stage id', ['stageId' => $callStage->id]);\n $activity->stage_id = $callStage->id;\n }\n\n if ($lead) {\n $this->logger->info('Setting lead id', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n // If we are changed from an account > lead, unset the account data.\n $this->logger->info('Unsetting account id, opportunity id, contact id, value');\n $activity->account_id = null;\n $activity->opportunity_id = null;\n $activity->contact_id = null;\n $activity->value = null;\n }\n\n if ($account) {\n $this->logger->info('Setting account id', ['accountId' => $account->id]);\n $activity->account_id = $account->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('unsetting lead id');\n $activity->lead_id = null;\n\n // Unset the contact if switching different accounts. Will be set up below if still applicable.\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {\n $this->logger->info('Unsetting contact id');\n $activity->contact_id = null;\n }\n }\n\n if ($opportunity) {\n $this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);\n $this->logger->info('unsetting lead id');\n $activity->opportunity_id = $opportunity->id;\n $activity->value = $opportunity->value;\n\n // If we are changed from an lead > account, unset the lead data.\n $activity->lead_id = null;\n }\n\n if ($contact) {\n $this->logger->info('setting contact id', ['contactId' => $contact->id]);\n $activity->contact_id = $contact->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('Unsetting lead id');\n $activity->lead_id = null;\n }\n\n $activity->is_internal = $isInternal;\n $activity->save();\n $activity->refresh();\n\n $this->logger->notice('Activity saved', [\n 'activity_id' => $activity->getId(),\n 'lead_id' => $activity->lead_id,\n 'account_id' => $activity->account_id,\n 'contact_id' => $activity->contact_id,\n 'opportunity_id' => $activity->opportunity_id,\n 'stage_id' => $activity->stage_id,\n 'crm_provider_id' => $activity->getCrmProviderId(),\n ]);\n\n // Store entities as field data on the activity.\n $updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);\n\n if ($activity->isLoggable()) {\n // Follow-up Task or Event data.\n $followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);\n\n $this->logger->info('CRM LOG manual log triggered', [\n 'activityId' => $activity->getUuid(),\n 'followupData' => $followupData,\n 'userId' => $user->getUuid(),\n ]);\n\n // Store data in the CRM.\n // ++add check for crm_required\n $job = new SaveActivity($activity, $followupData);\n\n if ($updatedData) {\n $job->delay(Carbon::now()->addMinutes($jobDelay));\n }\n\n dispatch($job);\n\n // Manually dispatch log for Opportunity or Prospect added\n if ($activity->hasOpportunity() || $activity->hasProspect()) {\n event(new ActivityProspectAdded(\n activity: $activity,\n eventSource: 'manually-log-crm-data'\n ));\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.\n *\n * @param ServiceInterface $service\n * @param Activity $activity\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array\n {\n $updatedData = [];\n $existingData = $activity->data()->get();\n\n // We need to delete any existing data to overwrite with latest values.\n $activity->data()->delete();\n\n $layoutEntities = $layout->entities()\n ->with('field', 'parent')\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->get();\n\n /** @var LayoutEntity $entity */\n foreach ($layoutEntities as $entity) {\n // If the user has provided a value for this entity\n if (array_key_exists($entity->id_string, $entities)) {\n $value = $entities[$entity->id_string];\n\n // Convert raw data into values that the CRM can consume.\n if ($value) {\n $value = $service->normalizeValue($entity->field->type, $value);\n }\n\n // Check the field is part of the activity-summary section.\n if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {\n // This is the internal database ID, not the external CRM ID.\n $objectId = null;\n\n switch ($entity->field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $objectId = $activity->account_id;\n\n break;\n\n case Field::OBJECT_CONTACT:\n $objectId = $activity->contact_id;\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n $objectId = $activity->opportunity_id;\n\n break;\n\n case Field::OBJECT_LEAD:\n $objectId = $activity->lead_id;\n\n break;\n\n case Field::OBJECT_TASK:\n case Field::OBJECT_EVENT:\n $objectId = $activity->id;\n\n break;\n }\n\n if ($objectId) {\n /** @var FieldData $data */\n $data = $activity->data()->create([\n 'crm_layout_entity_id' => $entity->id,\n 'crm_field_id' => $entity->crm_field_id,\n 'object_type' => $entity->field->object_type,\n 'object_id' => $objectId,\n 'value' => $value,\n ]);\n\n // Never send read-only field data to the CRM.\n if ($entity->read_only === false && $entity->is_visible) {\n $existingValue = $existingData\n ->where('crm_layout_entity_id', $entity->id)\n ->where('crm_field_id', $entity->crm_field_id)\n ->where('object_type', $entity->field->object_type)\n ->where('object_id', $objectId)\n ->first();\n\n // If the field was actually changed, we need to reflect this in the CRM too.\n if ($existingValue === null || $existingValue->value !== $value) {\n $updatedData[] = $data->id;\n }\n }\n }\n }\n }\n }\n\n return $updatedData;\n }\n\n /**\n * Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.\n *\n * @param ServiceInterface $crmService\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array\n {\n $fieldData = [];\n foreach ($entities as $entityId => $value) {\n // Only bother with fields that have a value.\n if ($value) {\n // Extract the entity from the UUID. Check the field is valid and part of the follow-up section.\n $entity = $layout->entities()\n ->uuid($entityId, false)\n ->whereHas('parent', function ($query) {\n $query->where('label', 'follow-up');\n })\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->first();\n\n if ($entity) {\n // Convert raw data into values that the CRM can consume.\n $value = $crmService->normalizeValue($entity->field->type, $value);\n\n // Add the field and value to the payload.\n $fieldData += [\n $entity->field->crm_provider_id => $value,\n ];\n }\n }\n }\n\n return $fieldData;\n }\n\n /**\n * @param Activity $activity\n */\n private function validateSummary(Activity $activity): void\n {\n $team = $activity->user->team;\n $crmProvider = $team->crm->provider;\n $attributes = [];\n\n $rules = [\n 'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,\n 'title' => 'string|max:250',\n 'prospects' => 'required|array',\n 'opportunity_id' => new CrmReference($crmProvider),\n 'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',\n 'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator\n 'summary' => 'max:50000',\n 'nId' => 'exists:notifications,id',\n 'crm_id' => new CrmReference($crmProvider),\n 'entities' => 'array',\n 'is_internal' => 'boolean',\n ];\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));\n\n // Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.\n $entities = $layout->entities()\n ->where('read_only', 0)\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->whereHas('parent', function ($query) use ($activity) {\n if ($activity->isLoggable() === false) {\n $query->where('label', '<>', 'follow-up');\n }\n });\n\n $isInternal = $this->request->input('is_internal', false);\n\n foreach ($entities->get() as $entity) {\n $rules += $this->buildFieldValidator($entity, $isInternal);\n $attributes += $this->buildFieldMessage($entity);\n }\n\n $this->request->validate($rules, [], $attributes);\n }\n\n private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array\n {\n return [\n 'entities.' . $entity->id_string => $entity->getValidator($isInternal),\n ];\n }\n\n /**\n * @param LayoutEntity $entity\n *\n * @return array\n */\n private function buildFieldMessage(LayoutEntity $entity): array\n {\n $label = $entity->label;\n if ($label === null) {\n $label = $entity->field->label;\n }\n\n return [\n 'entities.' . $entity->id_string => $label,\n ];\n }\n\n public function search(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->debugLog(\n $user,\n 'User extracted from request',\n ['user' => $user->getId(), 'tz' => $user->getTimezone()]\n );\n\n $searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());\n\n $this->debugLog(\n $user,\n 'ActivitySearch criteria built',\n ['searchCriteria' => $searchCriteria]\n );\n\n $filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);\n\n $this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);\n\n $this->validateSearch($request, $filterSet);\n\n $this->debugLog($user, 'Request validated');\n\n $searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);\n\n /** @var Collection<Activity> $activities */\n $activities = $searchResponse['results'];\n\n $this->debugLog($user, 'Activities ES response extracted');\n\n $hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(\n $user->getTeamId(),\n TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),\n );\n\n if ($hideInternalMeetingsSetting?->getValue() === '1') {\n $activities = $activities->filter(function (Activity $activity) {\n if ($activity->is_internal && empty($activity->actual_start_time)) {\n return false;\n }\n\n return true;\n });\n }\n\n $this->debugLog($user, 'Internal meetings (?!) filtered');\n\n $this->response->getManager()\n ->parseIncludes([\n 'category',\n 'organizer.group',\n 'prospect',\n 'stage',\n 'opportunity',\n 'stats',\n 'scorecards',\n 'masterTrack',\n 'activeParticipants',\n 'notification',\n ])\n ->setSerializer(new JsonSerializer());\n\n $transformerExcludes = $this->request->input('exclude');\n if ($transformerExcludes) {\n $this->response->getManager()->parseExcludes($transformerExcludes);\n }\n\n $this->debugLog($user, 'Response Manager (?!) applied');\n\n $transformer = new ActivityTransformer();\n $transformer->setConsumer($user);\n\n $this->debugLog($user, 'Activity Transformer added');\n\n $resource = new \\League\\Fractal\\Resource\\Collection($activities, $transformer);\n $page = $searchCriteria->getPageNumber();\n\n $this->debugLog($user, 'Search criteria page number called', ['page' => $page]);\n\n $histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');\n\n $this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);\n\n return $this->response->withArray([\n 'pagination' => [\n 'total' => $searchResponse['totalHits'],\n 'current' => $page,\n 'prev' => max($page - 1, 1),\n 'next' => $page + 1,\n ],\n 'results' => $this->response->getManager()->createData($resource)->toArray(),\n 'histogram' => $histogram,\n ]);\n }\n\n private function debugLog(User $user, string $logMessage, ?array $context = []): void\n {\n // Debug for Learning People Only\n if ($user->getTeamId() !== 260) {\n return;\n }\n\n Log::notice(\n sprintf('[activity-search-controller] %s', $logMessage),\n $context\n );\n }\n\n /** @throws ValidationException */\n private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void\n {\n $rules = [\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ];\n\n if ($prefix !== null && mb_strpos($prefix, '.') !== false) {\n $rules[rtrim($prefix, '.')] = sprintf(\n 'required|array|max:%d',\n $filterSet->count()\n );\n }\n\n $validationRules = $filterSet->getValidationRules($prefix)\n ->merge($rules)\n ->all();\n\n $request->validate($validationRules);\n }\n\n public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $search = $this->updateOrCreateActivitySearch($request);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function updateActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('update', $search);\n\n $this->updateOrCreateActivitySearch($request, $search);\n\n return $this->response->withOk();\n }\n\n private function storeNamedSearchFilters(\n Collection $request,\n Search $search,\n FilterDefinitionCollection $filterSet,\n ?string $prefix = null,\n ): self {\n $arrayTypeProperties = $filterSet\n ->getPropertyTypes([\n FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,\n ])\n ->all();\n\n $supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);\n\n foreach ($supportedRequestProperties as $requestPropertyName) {\n if (! array_has($request, $requestPropertyName)) {\n continue;\n }\n\n /** @var string|string[] $propertyValue */\n $propertyValue = array_get($request, $requestPropertyName);\n $propertyName = $prefix === null\n ? $requestPropertyName\n : mb_substr($requestPropertyName, mb_strlen($prefix));\n\n $isArrayType = array_has($arrayTypeProperties, $propertyName);\n\n if (! $isArrayType) {\n /** @var string $requestPropertyValue */\n\n $search->filters()->updateOrCreate(\n [\n 'filter' => $propertyName,\n ],\n [\n 'value' => $propertyValue,\n ]\n );\n\n continue;\n }\n\n /** @var string[] $requestPropertyValue */\n\n /** @var SearchFilter[]|Collection $existingFilterValues */\n $existingFilterValuesKeyed = $search->filters()\n ->where('filter', $propertyName)\n ->get()\n ->keyBy('id');\n\n // Iterate over values provided as request parameters\n foreach ($propertyValue as $value) {\n /** @var SearchFilter|null $valueFilter */\n $valueFilter = $search->filters()\n ->where(\n [\n 'filter' => $propertyName,\n 'value' => $value,\n ]\n )\n ->first();\n\n if ($valueFilter !== null) {\n // Remove filter value pair from list to be deleted\n $existingFilterValuesKeyed->forget($valueFilter->id);\n } else {\n // Add new filter/value pair\n $search->filters()->updateOrCreate([\n 'filter' => $propertyName,\n 'value' => $value,\n ]);\n }\n }\n\n // Delete filter value pairs for this filter that no longer exist in request parameters\n foreach ($existingFilterValuesKeyed as $existingFilter) {\n $existingFilter->delete();\n }\n }\n\n /** @var Collection<int, SearchFilter> $filtersKeyed */\n $filtersKeyed = $search->filters()->get()->keyBy('filter');\n\n // wipe removed filters from this search\n foreach ($filtersKeyed as $filterName => $filter) {\n if (array_has($request, $prefix . $filterName)) {\n continue;\n }\n\n // Remove all filter values for this filter\n $search->filters()->where('filter', $filterName)->delete();\n }\n\n return $this;\n }\n\n /**\n * @throws AuthorizationException\n */\n public function fetchActivitySearch(\n Search $search,\n Request $request,\n SearchTransformer $searchTransformer,\n ): JsonResponse {\n $this->authorize('view', $search);\n\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection(\n $user->searches()->get(),\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n /**\n * Deletes a saved search\n *\n * @param Request $request\n * @param Search $search\n *\n * @throws Exception\n *\n * @return JsonResponse\n */\n public function deleteActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('delete', $search);\n\n // Orphan any AutomatedReports that use this search\n $search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);\n\n // Delete filters and the search itself\n $search->filters()->delete();\n $search->delete();\n\n return $this->response->withOk();\n }\n\n public function live(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n $user = $this->getUserFromRequest($request);\n\n $this->request->validate([\n 'sort_direction' => 'in:asc,desc',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ]);\n\n $activities = $repository->getLiveCoachingEligibleActivities(\n user: $user,\n lookBackMinutes: self::LOOK_BACK,\n limit: (int) $this->request->input('limit', 25),\n page: (int) $this->request->input('page', 1),\n sortBy: ['actual_start_time', 'scheduled_start_time'],\n sortDirection: (string) $this->request->input('sort_direction', 'asc'),\n );\n\n $this->response\n ->getManager()\n ->parseIncludes(['organizer.group', 'prospect'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($activities, new ActivityTransformer());\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function show(Activity $activity, ActivityService $activityService): JsonResponse\n {\n $this->authorize('show', $activity);\n\n $user = $activity->getUser();\n $team = $user->getTeam();\n\n // Sync the opportunity with the latest data if possible.\n if ($activity->opportunity_id) {\n try {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n if (! $user->isCrmRequired()) {\n $crmService->setUser($team->getOwner());\n } else {\n $crmService->setUser($user);\n }\n\n $crmService->syncOpportunity($activity->opportunity->crm_provider_id);\n } catch (Exception $exception) {\n // Move on.\n }\n }\n\n $activityData = $activityService->getActivityData($this->request->user(), $activity);\n\n return response()->json($activityData);\n }\n\n public function createRecording(Activity $activity)\n {\n $this->authorize('record', $activity);\n\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Tell Twilio to start recording this activity.\n if ($activity->recording_state === Activity::RECORDING_OFF) {\n $job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withCreated();\n }\n\n return $this->response->errorGone('Activity is already recording.');\n }\n\n public function updateRecording(Request $request, Activity $activity)\n {\n $this->authorize('record', $activity);\n\n $request->validate([\n 'preference' => 'boolean',\n 'state' => [\n 'string',\n Rule::in([\n Activity::RECORDING_IN_PROGRESS,\n Activity::RECORDING_PAUSED,\n ]),\n ],\n ]);\n\n if ($request->has('state')) {\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Toggle the recording state between paused and resumed.\n if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {\n $job = (new ToggleRecording($activity, $request->input('state')))\n ->onQueue(Constants::QUEUE_CONFERENCES);\n\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Recording is not toggleable.');\n }\n\n if ($request->has('preference')) {\n $activity->update([\n 'recording_preference' => $request->input('preference') ? 1 : 0,\n ]);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorWrongArgs('Something went wrong');\n }\n\n public function stopRecording(Activity $activity)\n {\n $this->authorize('stopRecord', $activity);\n\n // Tell Twilio to stop recording this activity.\n if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {\n $job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Activity is not recording.');\n }\n\n /**\n * Add activity to this user's favorites playlist\n *\n * @throws AuthorizationException\n */\n public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse\n {\n $this->authorize('favorite', $activity);\n\n $user = $this->getUserFromRequest($this->request);\n $favorite = $activity->wasFavoritedBy($user);\n $name = $activity->activity_title ?? '';\n\n // It needs to check at least one record.\n if (! $favorite) {\n $favoritePlaylist = $user->favoritePlaylist();\n\n $playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(\n $activity,\n $user,\n $favoritePlaylist\n );\n\n if ($playlistActivity !== null) {\n $playlistActivity->update(\n // Just update, don't sort.\n ['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],\n );\n } else {\n $playlistActivity = $activity->playlistActivities()->create([\n 'playlist_id' => $favoritePlaylist->getId(),\n 'user_id' => $user->getId(),\n 'start_time' => 0,\n 'name' => mb_strimwidth($name, 0, 100),\n ]);\n // Sort it on top.\n $playlistActivity->update(\n [\n 'sort' => $playlistActivityRepository->calculateNewSortOrder(\n null,\n $playlistActivity,\n ),\n ],\n );\n }\n\n $playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);\n\n return new JsonResponse([], JsonResponse::HTTP_CREATED);\n }\n\n return new JsonResponse(\n [\n 'error' => [\n 'code' => AbstractResponse::CODE_CONFLICT,\n 'http_code' => JsonResponse::HTTP_CONFLICT,\n 'message' => 'Resource Already Exists',\n ],\n ],\n JsonResponse::HTTP_CONFLICT,\n );\n }\n\n /**\n * Remove activity from this user's favorites playlist\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unfavorite(Activity $activity)\n {\n $user = $this->request->user();\n\n $favorites = $activity->favoritedBy($user);\n\n if ($favorites && $favorites->isEmpty()) {\n return $this->response->errorNotFound('Favorite not found.');\n }\n\n $this->authorize('unfavorite', [$activity, $favorites]);\n\n // When you unfavorite an activity,\n // it should remove all the activities in it, including snippets.\n $isDeleted = $favorites->each(function ($favorite) {\n $favorite->forceDelete();\n });\n\n if ($isDeleted) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not remove favorite.');\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function notify(Activity $activity)\n {\n $this->authorize('notify', $activity);\n\n $user = $this->request->user();\n\n $existingNotification = $activity->availabilityNotifications()\n ->where('user_id', $user->id)\n ->exists();\n\n if ($existingNotification) {\n return $this->response->errorWrongArgs('Notification is already configured.');\n }\n\n $notification = Activity\\AvailabilityNotification::create([\n 'user_id' => $user->id,\n 'activity_id' => $activity->id,\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($notification, new AvailabilityNotificationTransformer());\n }\n\n /**\n * @param Activity $activity\n * @param Activity\\AvailabilityNotification $notification\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unnotify(Activity $activity, Activity\\AvailabilityNotification $notification)\n {\n $this->authorize('unnotify', [$activity, $notification]);\n\n if ($notification->sent_at || $notification->delete()) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not delete notification.');\n }\n\n public function play(Request $request, Activity $activity)\n {\n $this->authorize('stream', $activity);\n\n $request->validate([\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $activity->plays()->create([\n 'user_id' => $user->getId(),\n 'start_time' => $request->input('start_time'),\n ]);\n\n return $this->response->withCreated();\n }\n\n /**\n * @param Activity $activity\n *\n * @return mixed\n */\n public function comment(Activity $activity)\n {\n return $this->newComment($activity);\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @return mixed\n */\n public function replyComment(Activity $activity, Comment $comment)\n {\n return $this->newComment($activity, $comment);\n }\n\n /**\n * @param Activity $activity\n * @param Comment|null $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n protected function newComment(Activity $activity, ?Comment $comment = null)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n 'type' => 'integer|between:0,3',\n 'visibility' => sprintf('nullable|integer|between:1,%d', count(Comment::getVisibilityLevels())),\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n $threadStartId = null;\n if ($comment) {\n $threadStartId = $comment->thread_start_id ?: $comment->id;\n }\n\n try {\n $newComment = Comment::create([\n 'parent_comment_id' => $comment->id ?? null,\n 'thread_start_id' => $threadStartId,\n 'activity_id' => $activity->id,\n 'user_id' => $this->request->user()->id,\n 'comment' => trim($this->request->input('comment')),\n 'start_time' => $this->request->input('start_time', 0),\n 'end_time' => $this->request->input('end_time', 0),\n 'type' => $this->request->input('type', Comment::TYPE_NEUTRAL),\n 'visibility' => $this->request->input('visibility', Comment::VISIBILITY_PUBLIC),\n ]);\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($newComment, new ActivityCommentTransformer());\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not create comment.' . $exception->getMessage());\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function updateComment(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n try {\n $comment->update([\n 'comment' => trim($this->request->input('comment')),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment.');\n }\n }\n\n public function updateCommentVisibility(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'visibility' => sprintf('integer|between:1,%d', count(Comment::getVisibilityLevels())),\n ]);\n\n $visibility = $this->request->input('visibility');\n\n if ($comment->parent !== null) {\n return $this->response->errorWrongArgs('Comment visibility can only be updated on top level comments.');\n }\n\n try {\n $this->activityCommentService->updateCommentVisibility($comment, $visibility);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment\\'s visibility.');\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function deleteComment(Activity $activity, Comment $comment)\n {\n $this->authorize('deleteComment', [$activity, $comment]);\n\n // Delete comment and any children.\n $comment->delete();\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function fetchComments()\n {\n $user = $this->request->user();\n $this->request->validate([\n 'forUserId' => 'uuid:users,team_id,' . $user->team_id,\n 'types' => 'array',\n 'types.*' => 'integer|between:0,3',\n ]);\n $forUser = null;\n\n $types = [Comment::TYPE_NEUTRAL, Comment::TYPE_GAME_CHANGER, Comment::TYPE_POSITIVE];\n $user = $this->request->user();\n if ($this->request->has('forUserId')) {\n $forUser = $user->team->users()->uuid($this->request->input('forUserId'));\n }\n\n $comments = Comment::query()\n ->whereHas('activity', static function (Builder $builder) use ($user, $forUser): void {\n $builder\n // I left feedback on my own activity; or\n ->where('activities.user_id', $user->getId());\n if ($forUser) {\n // I left feedback on any activity for this user.\n $builder->orWhere([\n 'user_id' => $user->getId(),\n 'activities.user_id' => $forUser->getId(),\n ]);\n }\n })\n ->whereIn('type', $this->request->input('types', $types))\n ->orderBy('created_at', 'desc')\n ->get();\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity', 'user'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($comments, new ActivityCommentTransformer());\n }\n\n public function deleteCoachingFeedback(Activity $activity, CoachingFeedback $coachingFeedback)\n {\n $this->authorize('deleteCoachingFeedback', [$activity, $coachingFeedback]);\n $activity = $coachingFeedback->getActivity();\n\n if ($coachingFeedback->delete()) {\n event(new UpdateSingleEntity(\n entityId: $activity->getId(),\n updateTarget: UpdateTargetEnum::ACTIVITY,\n purpose: 'delete-coaching-feedback',\n ));\n\n return $this->response->withOk();\n }\n\n return $this->response->withError('Delete operation failed. Contact support.', 500);\n }\n\n /**\n * Add new or update Coaching feedback\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws \\Illuminate\\Validation\\ValidationException\n *\n * @return mixed\n */\n public function putCoachingFeedback(Request $request, Activity $activity)\n {\n $user = $request->user();\n\n if (! $user instanceof User) {\n abort(403);\n }\n $teamId = $user->getTeamId();\n\n $this->authorize('coach', $activity);\n\n $this->request->validate([\n 'coach_id' => 'required|uuid:users,team_id,' . $teamId,\n 'coachee_id' => 'required|uuid:users,team_id,' . $teamId,\n 'visibility' => ['required', Rule::in(CoachingFeedback::VISIBILITIES)],\n 'coaching_sections.*.uuid' => 'required|uuid:coaching_sections',\n 'coaching_sections.*.score' => ['required', Rule::in(CoachingSectionFeedback::SCORES)],\n 'coaching_sections.*.summary' => 'string|max:10000',\n 'coaching_sections.*.criteria.*.uuid' => 'required|uuid:coaching_section_criteria',\n 'coaching_sections.*.criteria.*.note' => 'required|string|max:10000',\n 'sharedWithUsers' => [\n 'required_if:visibility,' . CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS,\n 'array',\n ],\n 'sharedWithUsers.*' => [\n 'uuid:users,team_id,' . $teamId,\n ],\n ]);\n\n /** @var User $coach */\n $coach = User::uuid($this->request->input('coach_id'));\n /** @var User $coachee */\n $coachee = User::uuid($this->request->input('coachee_id'));\n $coachingSectionFeedbacks = $this->request->input('coaching_sections');\n\n $previousRecord = $this->coachingFeedbackRepository->getOneForActivityByCoacheeAndCoach(\n $coachee->getId(),\n $coach->getId(),\n $activity->getId()\n );\n $recordIsNew = false;\n if ($previousRecord === null) {\n $recordIsNew = true;\n }\n\n if (! $coachee->isSameTeamId($coach)) {\n return $this->response->errorForbidden('User not member of your team.');\n }\n\n if (! is_array($coachingSectionFeedbacks) || count($coachingSectionFeedbacks) < 1) {\n return $this->response->withError('At least one Coaching Framework Section shall be scored.', 422);\n }\n\n if (! $activity->participants()->where('participants.user_id', $coachee->id)->exists()) {\n return $this->response->withError('Coached user did not participate activity.', 422);\n }\n\n $visibility = $this->request->input('visibility');\n\n $shouldSendNotification = $recordIsNew;\n if ($recordIsNew === false && $visibility !== $previousRecord->getVisibility()) {\n $shouldSendNotification = true;\n }\n\n /**\n * Create CoachingFeedback\n *\n * @var CoachingFeedback $coachingFeedback\n */\n $coachingFeedback = $activity->coachingFeedbacks()->updateOrCreate(\n [\n 'coach_id' => $coach->id,\n 'coachee_id' => $coachee->id,\n ],\n [\n 'framework_id' => $activity->category->id,\n 'visibility' => $visibility,\n ]\n );\n\n $sharedUserIds = [];\n if ($visibility === CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS) {\n foreach ($this->request->input('sharedWithUsers') as $sharedWithUserUuid) {\n /** @var User $user */\n $user = User::uuid($sharedWithUserUuid);\n $sharedUserIds[] = $user->getId();\n }\n }\n\n $syncResult = $coachingFeedback->customAccessUsers()->sync($sharedUserIds);\n\n $scores = [];\n\n\n /**\n * Create CoachingSectionsFeedbacks.\n *\n * @var CoachingSectionFeedback $coachingSectionFeedback\n */\n foreach ($coachingSectionFeedbacks as $coachingSectionFeedbackInput) {\n $coachingSection = CoachingSection::uuid($coachingSectionFeedbackInput['uuid']);\n $coachingSectionFeedback = $coachingFeedback->sectionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_id' => $coachingSection->id,\n ],\n [\n 'score' => array_get($coachingSectionFeedbackInput, 'score'),\n 'summary' => array_get($coachingSectionFeedbackInput, 'summary') ?? '',\n ]\n );\n\n $scores[] = array_get($coachingSectionFeedbackInput, 'score');\n\n $criteria = array_get($coachingSectionFeedbackInput, 'criteria');\n if (is_array($criteria) && ! empty($criteria)) {\n foreach ($criteria as $criteriaFeedbackInput) {\n $coachingSectionFeedback->criterionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_criterion_id' => CoachingSectionCriterion::uuid(array_get($criteriaFeedbackInput, 'uuid'))\n ->id,\n ],\n ['note' => array_get($criteriaFeedbackInput, 'note')],\n );\n }\n }\n }\n\n $coachingFeedback->average_score = array_sum($scores) / count($scores);\n\n if ($recordIsNew === false && $coachingFeedback->getAverageScore() !== $previousRecord->getAverageScore()) {\n $shouldSendNotification = true;\n }\n if (! empty($syncResult['attached']) || ! empty($syncResult['detached']) || ! empty($syncResult['updated'])) {\n $shouldSendNotification = true;\n }\n\n $coachingFeedback->save();\n // ensure updated at for coaching feedback on section feedback summary added.\n $coachingFeedback->touch();\n\n if ($shouldSendNotification) {\n event(new Coached($coachingFeedback));\n }\n\n Datadog::increment('jiminny.activity.score.update', 1, ['company' => $activity->user->team->slug]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n $coachingFeedbackTransformer = new CoachingFeedbackTransformer();\n $coachingFeedbackTransformer->setConsumer($this->getUserFromRequest($request));\n\n return $this->response->withItem($coachingFeedback, $coachingFeedbackTransformer);\n }\n\n\n /**\n * Retrieve category criteria for coaching.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachingSections(Activity $activity)\n {\n $this->authorize('coach', $activity);\n\n if ($activity->category === null) {\n return $this->response->errorUnprocessable('Category has not yet been assigned.');\n }\n\n $criteria = $activity\n ->category\n ->coachingSections()\n ->where('is_enabled', 1)\n ->orderBy('sequence', 'asc');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($criteria->get(), new CoachingSectionsTransformer());\n }\n\n /**\n * @throws AuthorizationException\n * @throws ValidationException\n *\n * @return mixed\n */\n public function addToPlaylist(Activity $activity, PlaylistTrackFactoryInterface $playlistTrackFactory)\n {\n $this->request->validate([\n 'playlists' => 'required|array',\n 'playlists.*' => 'uuid:playlists',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'name' => 'required|max:100',\n ]);\n\n $this->authorize('addToPlaylist', [$activity, $this->request->input('playlists')]);\n\n $startTime = $this->request->input('start_time');\n $endTime = $this->request->input('end_time');\n $name = $this->request->input('name');\n /** @var User $user */\n $user = $this->request->user();\n\n // Get playlist by uuid.\n foreach ($this->request->input('playlists') as $playlistId) {\n // Pull out the playlist model.\n $playlist = Playlist::uuid($playlistId);\n\n $playlistTrackFactory->createTrack($playlist, $user, [\n 'name' => $name,\n 'activity' => $activity,\n 'start_time' => $startTime,\n 'end_time' => $endTime,\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function share(Request $request, Activity $activity): JsonResponse\n {\n $this->authorize('share', $activity);\n\n $request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'recipients.*.type' => 'in:user,group',\n 'recipients.*.id' => 'string|max:40',\n 'share' => 'string|max:255',\n ]);\n\n $user = $request->user();\n\n $recipients = $request->get('recipients');\n $users = $this->userService->convertRecipientsToUsers($user, $recipients);\n\n $shareData = [\n 'from_user_id' => $user->id,\n 'note' => $request->input('note'),\n 'start_time' => $request->input('start_time'),\n 'end_time' => $request->input('end_time'),\n ];\n\n // Create a share object against a notification provider channel\n if ($request->input('share')) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'notification_provider_channel' => $request->input('share'),\n ]\n )\n );\n\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n\n // Create a share object against each recipient\n foreach ($users as $recipient) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'to_user_id' => $recipient->id,\n ]\n )\n );\n\n // If parent_share_id has been selected yet\n if (! isset($shareData['parent_share_id'])) {\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachRequest(Activity $activity)\n {\n $this->authorize('coachRequest', $activity);\n\n $this->request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'coachers.*.type' => 'required|in:user',\n 'coachers.*.id' => 'required',\n ]);\n\n $coachers = $this->request->get('coachers');\n $user = $this->request->user();\n $users = $this->userService->convertRecipientsToUsers($user, $coachers);\n\n foreach ($users as $coacher) {\n CoachRequest::create([\n 'user_id' => $coacher->id,\n 'activity_id' => $activity->id,\n 'note' => $this->request->get('note'),\n 'start_time' => $this->request->get('start_time'),\n 'end_time' => $this->request->get('end_time'),\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function createActivityTopicTriggers(Activity $activity, LoggerInterface $logger): HttpFoundation\\JsonResponse\n {\n $this->authorize('analyzeTopicTriggers', $activity);\n\n if (! $activity->hasTranscription()) {\n return new HttpFoundation\\JsonResponse(\n [\n 'error' => 'Transcription not found.',\n ],\n JsonResponse::HTTP_NOT_FOUND\n );\n }\n\n $logger->info(__METHOD__ . ': queued for analysis', [\n 'activity' => $activity->id_string,\n ]);\n\n dispatch(new ActivityAnalytics\\Job\\AnalyzeActivityTopicTriggers($activity));\n\n return new HttpFoundation\\JsonResponse(null, JsonResponse::HTTP_CREATED);\n }\n\n public function fetchActivityTopicTriggers(\n Activity $activity,\n LoggerInterface $logger,\n ActivityTopicTriggerTransformer $transformer\n ): HttpFoundation\\JsonResponse {\n $this->authorize('fetchTopicTriggers', $activity);\n\n $logger->debug(__METHOD__, [\n 'activity' => $activity->id_string,\n ]);\n\n if (! $activity->isProcessed()) {\n return new HttpFoundation\\JsonResponse([]);\n }\n\n $payload = [];\n\n if ($activity->hasTopicTriggers()) {\n $payload = $activity->getTopicTriggersSorted()\n ->map(\n static fn (Activity\\TopicTrigger $activityTopicTrigger): array\n => $transformer->transform($activityTopicTrigger)\n )\n ->values()\n ->all();\n }\n\n return new HttpFoundation\\JsonResponse($payload);\n }\n\n /**\n * @param Activity $activity\n * @param StatsTransformer $statsTransformer\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function stats(Activity $activity, StatsTransformer $statsTransformer)\n {\n $this->authorize('stream', $activity);\n\n if (! $activity->hasTranscription()) {\n return $this->response->errorNotFound('Waveform data is not yet generated.');\n }\n\n $this->response\n ->getManager()\n ->parseIncludes(['wavedata'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($activity, $statsTransformer);\n }\n\n public function destroy(Activity $activity)\n {\n $this->authorize('delete', $activity);\n\n $activity->delete();\n\n \\Log::info('Soft delete activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n\n return $this->response->withNoContent();\n }\n\n public function note(Activity $activity)\n {\n $this->authorize('note', $activity);\n\n $this->request->validate([\n 'note' => 'required|min:1|max:2000',\n 'time' => 'required|numeric|min:0|max:86400',\n ]);\n\n $note = $this->request->input('note');\n $time = $this->request->input('time');\n\n $this->activityService->setActivity($activity);\n $this->activityService->takeNote($this->getUser(), $note, $time);\n\n return $this->response->withCreated();\n }\n\n /**\n * Mark an activity as private.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPrivate(Activity $activity)\n {\n $this->authorize('markAsPrivate', $activity);\n\n if ($activity->is_private === false) {\n $activity->is_private = true;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * Mark an activity as public.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPublic(Activity $activity)\n {\n $this->authorize('markAsPublic', $activity);\n\n if ($activity->is_private) {\n $activity->is_private = false;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws LogicException\n */\n public function fetchCloudFrontS3MediaKeys(Activity $activity, PlaybackService $playbackService): JsonResponse\n {\n $masterTrack = $activity->masterTrack()->first();\n\n if (! $masterTrack instanceof Track) {\n throw new LogicException(sprintf('Master track not found for activity \"%s\"', $activity->getUuid()));\n }\n\n return $this->response->withArray(\n $playbackService->generateCookies(\n $masterTrack,\n $this->request->ip(),\n ),\n );\n }\n\n /**\n * @throws ValidationException\n */\n private function updateOrCreateActivitySearch(Request $request, ?Search $search = null): Search\n {\n $request->validate([\n 'name' => 'required|string|min:2|max:100',\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $searchName = $request->input('name');\n\n if ($search !== null) {\n $search->update([\n 'name' => $searchName,\n ]);\n\n return $search;\n }\n\n $request->validate([\n 'filters' => ['required', 'array', new MultidimensionalArrayMaxCharRule(limit: 255)],\n 'nudges' => 'array|max:' . count(Nudge::MAP_CHANNEL),\n 'nudges.*.channel' => 'required|in:' . implode(',', Nudge::MAP_CHANNEL),\n 'nudges.*.frequency' => 'required|in:' . implode(',', Nudge::MAP_FREQUENCY),\n 'nudges.*.expiresAt' => [\n 'required',\n 'date',\n 'after:today',\n 'before_or_equal:' . now()->addYear()->format('Y-m-d'),\n ],\n ]);\n\n $searchCriteria = Criteria::createFromRequest(\n Collection::make($request->input('filters', []))->all(),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($searchCriteria, $user);\n $this->validateSearch($request, $filterSet, 'filters.');\n\n /** @var Search $search */\n $search = Search::create([\n 'name' => $searchName,\n 'uuid' => Uuid::uuid4()->toString(),\n 'user_id' => $user->getId(),\n ]);\n\n Collection::make($request->input('nudges', []))\n ->each(fn (array $attributes): Nudge => $this->nudgeFactory->createNudge($search, $attributes));\n\n $this->storeNamedSearchFilters(Collection::make($request->all()), $search, $filterSet, 'filters.');\n\n return $search;\n }\n\n private function resolveAccount(\n Team $team,\n Contact $contact,\n ServiceInterface $crmService,\n array $prospects,\n ): ?Account {\n $this->logger->info('Resolving account from contact');\n $account = $contact->getAccount();\n\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS)) {\n $this->logger->info('Team does not have feature to link activity to multiple prospects');\n\n return $account;\n }\n\n $this->logger->info('Resolving account from prospect data');\n $accountData = array_filter(\n $prospects,\n static fn (array $prospectData): bool => $prospectData['type'] === 'account'\n );\n\n if (! empty($accountData)) {\n $this->logger->info('Found account data in prospects');\n $accountData = reset($accountData);\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountData['id'])->first();\n\n if (! $account instanceof Account) {\n $this->logger->info('Account not found in database, syncing from CRM');\n $account = $crmService->syncAccount($accountData['id']);\n }\n }\n\n $this->logger->info('Resolved account', ['account' => $account->getId()]);\n\n return $account;\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Http\\Controllers\\API;\n\nuse Carbon\\Carbon;\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Exception;\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Validation\\Rule;\nuse Illuminate\\Validation\\Rules\\In;\nuse Illuminate\\Validation\\ValidationException;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ActivityAnalytics;\nuse Jiminny\\Component\\ActivitySearch;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Contracts\\ES\\Events\\UpdateSingleEntity;\nuse Jiminny\\Contracts\\ES\\UpdateTargetEnum;\nuse Jiminny\\Contracts\\Nudge\\NudgeFactoryInterface;\nuse Jiminny\\Contracts\\Playlist\\PlaylistTrackFactoryInterface;\nuse Jiminny\\Contracts\\Repositories\\PlaylistActivityRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Enums\\TeamSetting;\nuse Jiminny\\Events\\Activities\\AiAutomation\\ActivityProspectAdded;\nuse Jiminny\\Events\\Activities\\Coaching\\Coached;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Controllers\\CommentContextInterface;\nuse Jiminny\\Http\\Responses\\Api\\AbstractResponse;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\ActivityCommentTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTopicTriggerTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTransformer;\nuse Jiminny\\Http\\Transformers\\AvailabilityNotificationTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingFeedbackTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingSectionsTransformer;\nuse Jiminny\\Http\\Transformers\\SearchTransformer;\nuse Jiminny\\Http\\Transformers\\StatsTransformer;\nuse Jiminny\\Jobs\\Crm\\SaveActivity;\nuse Jiminny\\Jobs\\Crm\\UpdateStage;\nuse Jiminny\\Jobs\\Telephony\\StartRecording;\nuse Jiminny\\Jobs\\Telephony\\StopRecording;\nuse Jiminny\\Jobs\\Telephony\\ToggleRecording;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\CoachingFeedback;\nuse Jiminny\\Models\\CoachingSection;\nuse Jiminny\\Models\\CoachingSectionCriterion;\nuse Jiminny\\Models\\CoachingSectionFeedback;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\LanguageDialect;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Nudge;\nuse Jiminny\\Models\\PlaybookCategory;\nuse Jiminny\\Models\\Playlist;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\Track;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\CoachingFeedbackRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Rules\\MultidimensionalArrayMaxCharRule;\nuse Jiminny\\Services\\ActivityService;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Services\\PlaybackService;\nuse Jiminny\\Services\\UserService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\nuse Ramsey\\Uuid\\Uuid;\nuse Sentry;\nuse Symfony\\Component\\HttpFoundation;\n\nfinal class ActivityController extends Controller implements CommentContextInterface\n{\n // Number of minutes to look back on activities. i.e. a timeout on activity duration.\n private const int LOOK_BACK = 180;\n\n public function __construct(\n private ProviderRegistry $providerRegistry,\n private ActivityService $activityService,\n Response $response,\n private UserService $userService,\n private ActivitySearch\\Service\\ActivitySearch $activitySearch,\n private NudgeFactoryInterface $nudgeFactory,\n private ActivityCommentService $activityCommentService,\n private LoggerInterface $logger,\n private readonly CoachingFeedbackRepository $coachingFeedbackRepository,\n private readonly TeamRepository $teamRepository,\n ) {\n parent::__construct($response);\n }\n\n public static function getCommentImplementation(): string\n {\n return Comment::class;\n }\n\n public function delete()\n {\n $this->request->validate([\n '*' => 'uuid:activities',\n ]);\n\n $deletedIds = [];\n foreach ($this->request->all() as $activityId) {\n $activity = Activity::idOrUuId($activityId);\n\n try {\n if ($this->authorize('delete', $activity)) {\n $activity->delete();\n $deletedIds[] = $activityId;\n\n \\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n }\n } catch (AuthorizationException $authorizationException) {\n // They didn't have permission.\n }\n }\n\n return $this->response->withArray($deletedIds);\n }\n\n public function update(Request $request, Activity $activity)\n {\n $this->authorize('updateMetadata', $activity);\n\n $request->validate([\n 'title' => 'string|max:250',\n 'category_id' => 'uuid:playbook_categories',\n 'language' => [\n new In(\n LanguageDialect::query()\n ->with('language')\n ->cursor()\n ->map(static function (LanguageDialect $languageDialect): string {\n return $languageDialect->getLanguageLocale();\n })\n ->all()\n ),\n ],\n ]);\n\n if ($request->has('title')) {\n $activity->title = $request->input('title');\n }\n\n if ($request->has('category_id')) {\n $category = PlaybookCategory::uuid($request->input('category_id'));\n\n if ($category->playbook->team_id !== $request->user()->team_id) {\n return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n if ($request->has('language')) {\n if (! $activity->isInProgress()) {\n return $this->response->withError(\n 'Activity language can only be set while the meeting is in progress.',\n 400\n );\n }\n\n $activity->setLanguageCode($request->input('language'));\n }\n\n $activity->save();\n\n return $this->response->withOk();\n }\n\n // XXX: This should be merged with the update method.\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws SocialAccountTokenInvalidException\n *\n * @return mixed\n */\n public function summarize(Activity $activity): mixed\n {\n $this->logger->info('[Log Activity] Summarizing activity ', [\n 'activityId' => $activity->getUuid(),\n 'payload' => $this->request->all(),\n ]);\n $this->authorize('update', $activity);\n\n $this->logger->info('[Log Activity] Validating summary');\n // Validate the payload.\n $this->validateSummary($activity);\n\n // All objects must belong to this team.\n /** @var User $user */\n $user = $this->request->user();\n $team = $user->getTeam();\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n try {\n $crmUser = $user;\n if ($user->isCrmRequired() === false) {\n $crmUser = $team->owner;\n }\n $crmService->setUser($crmUser);\n } catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());\n }\n\n $rawEntities = $this->request->input('entities');\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid(\n $this->request->input('layout_id')\n );\n\n // Delay execution of CRM jobs to avoid locking issues.\n $jobDelay = 0;\n\n // If we have arrived from a notification, mark it as read.\n $notificationId = $this->request->input('nId');\n if ($notificationId) {\n $notification = $user->unreadNotifications->where('id', $notificationId)->first();\n\n if ($notification) {\n $notification->markAsRead();\n }\n }\n\n $title = $this->request->input('title');\n $prospects = $this->request->input('prospects');\n $opportunityId = $this->request->input('opportunity_id');\n $stageId = $this->request->input('stage_id');\n $categoryId = $this->request->input('category_id');\n $summary = $this->request->input('summary');\n $crmProviderId = $this->request->input('crm_id');\n $isInternal = $this->request->input('is_internal') ?? false;\n\n $lead = null;\n $category = null;\n $account = null;\n $contact = null;\n $opportunity = null;\n $stage = null;\n $callStage = null;\n\n foreach ($prospects as $prospectData) {\n $objectId = $prospectData['id'];\n\n if ($objectId === null) {\n continue;\n }\n\n $objectType = $prospectData['type'];\n $this->logger->info('debug', ['prospect_data' => $prospectData]);\n\n try {\n if ($objectType === null) {\n $this->logger->info('no object type');\n if ($crmService instanceof SupportsObjectTypeParseInterface) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n }\n\n switch ($objectType) {\n case 'lead':\n $this->logger->info('Processing lead');\n /** @var Lead|null $lead */\n $lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();\n\n // Lead does not exist locally, import it.\n if ($lead === null) {\n $this->logger->info('Lead does not exist locally');\n /** @var Lead $lead */\n $lead = $crmService->syncLead($objectId);\n }\n\n $this->logger->info('Lead found', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n if ($stageId === null) {\n $this->logger->info('Stage ID is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $lead->stage;\n\n break;\n }\n\n $this->logger->info('Looking for stage');\n // Determine if they have changed the stage.\n /** @var Stage $stage */\n $stage = $team->crm->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_LEAD)\n ->firstOrFail();\n\n $this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);\n if ($lead->stage_id && $lead->stage_id !== $stage->id) {\n $this->logger->info('Stage has changed');\n // Storage current stage on activity.\n $callStage = $lead->stage;\n\n // The stage has changed, update in remote CRM.\n dispatch(new UpdateStage($activity, $lead, $callStage, $stage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing lead stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->getName(),\n $stage->getName()\n ),\n [\n 'user' => $user->getUuid(),\n 'lead' => $lead->getUuid(),\n ]\n );\n } else {\n $this->logger->info('Stage has not changed');\n // Stage remains as current.\n $callStage = $stage;\n }\n\n break;\n\n case 'account':\n $this->logger->info('Processing account');\n // If the object is not a lead, it should be an account.\n $account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();\n\n // Account does not exist locally, import it.\n if ($account === null) {\n $this->logger->info('Account does not exist locally');\n $account = $crmService->syncAccount($objectId);\n }\n\n $this->logger->info('Account found', ['accountId' => $account->id]);\n\n break;\n case 'contact':\n $this->logger->info('processing contact');\n $contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $this->logger->info('contact does not exist locally');\n $contact = $crmService->syncContact($objectId);\n }\n\n $this->logger->info('resolving account');\n $account = $this->resolveAccount($team, $contact, $crmService, $prospects);\n\n break;\n }\n\n // If they have specified an opportunity, retrieve this with stage.\n if ($opportunityId) {\n $this->logger->info('opportunity id is set');\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if ($opportunity === null) {\n $this->logger->info('opportunity does not exist locally');\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n if ($stageId === null) {\n $this->logger->info('stage id is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $opportunity->stage ?? null;\n } else {\n $this->logger->info('looking for stage');\n /** @var ?Stage $opportunityStage */\n $opportunityStage = $team->crm\n ->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n // There is a chance we still cannot import this opportunity.\n if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {\n $this->logger->info('opportunity stage has changed');\n // Storage current stage on activity.\n $callStage = $opportunity->stage;\n\n dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing opportunity stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->name,\n $opportunityStage->name\n ),\n [\n 'userId' => $user->id_string,\n 'opportunityId' => $opportunity->id_string,\n ]\n );\n } else {\n $this->logger->info('opportunity stage has not changed');\n // Stage remains as current.\n $callStage = $opportunityStage;\n }\n }\n }\n\n if ($crmProviderId) {\n // Cast $crmProviderId to string otherwise it won't use database index for some records\n $linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();\n\n // Check if this activity has already been assigned to a different activity.\n if ($linkedActivity && $linkedActivity->id !== $activity->id) {\n throw new InvalidArgumentException(\n 'Sorry, the linked task has already been logged under a different call. '\n . 'Please choose another linked task.'\n );\n }\n }\n } catch (InvalidArgumentException $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($exception->getMessage());\n } catch (Exception $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorInternalError(\n 'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'\n );\n }\n }\n\n if ($categoryId) {\n $category = PlaybookCategory::uuid($categoryId);\n\n if ($category->playbook->team_id !== $team->id) {\n throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n $this->logger->info('Prospect data', [\n 'lead_id' => $lead?->getId(),\n 'account_id' => $account?->getId(),\n 'contact_id' => $contact?->getId(),\n 'opportunity_id' => $opportunity?->getId(),\n 'stage_id' => $stage?->getId(),\n ]);\n\n if ($title) {\n $activity->title = $title;\n }\n\n if ($summary) {\n $activity->summary = $summary;\n }\n\n if ($crmProviderId) {\n $activity->crm_provider_id = $crmProviderId;\n }\n\n if ($callStage) {\n $this->logger->info('Setting stage id', ['stageId' => $callStage->id]);\n $activity->stage_id = $callStage->id;\n }\n\n if ($lead) {\n $this->logger->info('Setting lead id', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n // If we are changed from an account > lead, unset the account data.\n $this->logger->info('Unsetting account id, opportunity id, contact id, value');\n $activity->account_id = null;\n $activity->opportunity_id = null;\n $activity->contact_id = null;\n $activity->value = null;\n }\n\n if ($account) {\n $this->logger->info('Setting account id', ['accountId' => $account->id]);\n $activity->account_id = $account->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('unsetting lead id');\n $activity->lead_id = null;\n\n // Unset the contact if switching different accounts. Will be set up below if still applicable.\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {\n $this->logger->info('Unsetting contact id');\n $activity->contact_id = null;\n }\n }\n\n if ($opportunity) {\n $this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);\n $this->logger->info('unsetting lead id');\n $activity->opportunity_id = $opportunity->id;\n $activity->value = $opportunity->value;\n\n // If we are changed from an lead > account, unset the lead data.\n $activity->lead_id = null;\n }\n\n if ($contact) {\n $this->logger->info('setting contact id', ['contactId' => $contact->id]);\n $activity->contact_id = $contact->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('Unsetting lead id');\n $activity->lead_id = null;\n }\n\n $activity->is_internal = $isInternal;\n $activity->save();\n $activity->refresh();\n\n $this->logger->notice('Activity saved', [\n 'activity_id' => $activity->getId(),\n 'lead_id' => $activity->lead_id,\n 'account_id' => $activity->account_id,\n 'contact_id' => $activity->contact_id,\n 'opportunity_id' => $activity->opportunity_id,\n 'stage_id' => $activity->stage_id,\n 'crm_provider_id' => $activity->getCrmProviderId(),\n ]);\n\n // Store entities as field data on the activity.\n $updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);\n\n if ($activity->isLoggable()) {\n // Follow-up Task or Event data.\n $followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);\n\n $this->logger->info('CRM LOG manual log triggered', [\n 'activityId' => $activity->getUuid(),\n 'followupData' => $followupData,\n 'userId' => $user->getUuid(),\n ]);\n\n // Store data in the CRM.\n // ++add check for crm_required\n $job = new SaveActivity($activity, $followupData);\n\n if ($updatedData) {\n $job->delay(Carbon::now()->addMinutes($jobDelay));\n }\n\n dispatch($job);\n\n // Manually dispatch log for Opportunity or Prospect added\n if ($activity->hasOpportunity() || $activity->hasProspect()) {\n event(new ActivityProspectAdded(\n activity: $activity,\n eventSource: 'manually-log-crm-data'\n ));\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.\n *\n * @param ServiceInterface $service\n * @param Activity $activity\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array\n {\n $updatedData = [];\n $existingData = $activity->data()->get();\n\n // We need to delete any existing data to overwrite with latest values.\n $activity->data()->delete();\n\n $layoutEntities = $layout->entities()\n ->with('field', 'parent')\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->get();\n\n /** @var LayoutEntity $entity */\n foreach ($layoutEntities as $entity) {\n // If the user has provided a value for this entity\n if (array_key_exists($entity->id_string, $entities)) {\n $value = $entities[$entity->id_string];\n\n // Convert raw data into values that the CRM can consume.\n if ($value) {\n $value = $service->normalizeValue($entity->field->type, $value);\n }\n\n // Check the field is part of the activity-summary section.\n if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {\n // This is the internal database ID, not the external CRM ID.\n $objectId = null;\n\n switch ($entity->field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $objectId = $activity->account_id;\n\n break;\n\n case Field::OBJECT_CONTACT:\n $objectId = $activity->contact_id;\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n $objectId = $activity->opportunity_id;\n\n break;\n\n case Field::OBJECT_LEAD:\n $objectId = $activity->lead_id;\n\n break;\n\n case Field::OBJECT_TASK:\n case Field::OBJECT_EVENT:\n $objectId = $activity->id;\n\n break;\n }\n\n if ($objectId) {\n /** @var FieldData $data */\n $data = $activity->data()->create([\n 'crm_layout_entity_id' => $entity->id,\n 'crm_field_id' => $entity->crm_field_id,\n 'object_type' => $entity->field->object_type,\n 'object_id' => $objectId,\n 'value' => $value,\n ]);\n\n // Never send read-only field data to the CRM.\n if ($entity->read_only === false && $entity->is_visible) {\n $existingValue = $existingData\n ->where('crm_layout_entity_id', $entity->id)\n ->where('crm_field_id', $entity->crm_field_id)\n ->where('object_type', $entity->field->object_type)\n ->where('object_id', $objectId)\n ->first();\n\n // If the field was actually changed, we need to reflect this in the CRM too.\n if ($existingValue === null || $existingValue->value !== $value) {\n $updatedData[] = $data->id;\n }\n }\n }\n }\n }\n }\n\n return $updatedData;\n }\n\n /**\n * Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.\n *\n * @param ServiceInterface $crmService\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array\n {\n $fieldData = [];\n foreach ($entities as $entityId => $value) {\n // Only bother with fields that have a value.\n if ($value) {\n // Extract the entity from the UUID. Check the field is valid and part of the follow-up section.\n $entity = $layout->entities()\n ->uuid($entityId, false)\n ->whereHas('parent', function ($query) {\n $query->where('label', 'follow-up');\n })\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->first();\n\n if ($entity) {\n // Convert raw data into values that the CRM can consume.\n $value = $crmService->normalizeValue($entity->field->type, $value);\n\n // Add the field and value to the payload.\n $fieldData += [\n $entity->field->crm_provider_id => $value,\n ];\n }\n }\n }\n\n return $fieldData;\n }\n\n /**\n * @param Activity $activity\n */\n private function validateSummary(Activity $activity): void\n {\n $team = $activity->user->team;\n $crmProvider = $team->crm->provider;\n $attributes = [];\n\n $rules = [\n 'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,\n 'title' => 'string|max:250',\n 'prospects' => 'required|array',\n 'opportunity_id' => new CrmReference($crmProvider),\n 'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',\n 'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator\n 'summary' => 'max:50000',\n 'nId' => 'exists:notifications,id',\n 'crm_id' => new CrmReference($crmProvider),\n 'entities' => 'array',\n 'is_internal' => 'boolean',\n ];\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));\n\n // Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.\n $entities = $layout->entities()\n ->where('read_only', 0)\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->whereHas('parent', function ($query) use ($activity) {\n if ($activity->isLoggable() === false) {\n $query->where('label', '<>', 'follow-up');\n }\n });\n\n $isInternal = $this->request->input('is_internal', false);\n\n foreach ($entities->get() as $entity) {\n $rules += $this->buildFieldValidator($entity, $isInternal);\n $attributes += $this->buildFieldMessage($entity);\n }\n\n $this->request->validate($rules, [], $attributes);\n }\n\n private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array\n {\n return [\n 'entities.' . $entity->id_string => $entity->getValidator($isInternal),\n ];\n }\n\n /**\n * @param LayoutEntity $entity\n *\n * @return array\n */\n private function buildFieldMessage(LayoutEntity $entity): array\n {\n $label = $entity->label;\n if ($label === null) {\n $label = $entity->field->label;\n }\n\n return [\n 'entities.' . $entity->id_string => $label,\n ];\n }\n\n public function search(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->debugLog(\n $user,\n 'User extracted from request',\n ['user' => $user->getId(), 'tz' => $user->getTimezone()]\n );\n\n $searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());\n\n $this->debugLog(\n $user,\n 'ActivitySearch criteria built',\n ['searchCriteria' => $searchCriteria]\n );\n\n $filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);\n\n $this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);\n\n $this->validateSearch($request, $filterSet);\n\n $this->debugLog($user, 'Request validated');\n\n $searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);\n\n /** @var Collection<Activity> $activities */\n $activities = $searchResponse['results'];\n\n $this->debugLog($user, 'Activities ES response extracted');\n\n $hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(\n $user->getTeamId(),\n TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),\n );\n\n if ($hideInternalMeetingsSetting?->getValue() === '1') {\n $activities = $activities->filter(function (Activity $activity) {\n if ($activity->is_internal && empty($activity->actual_start_time)) {\n return false;\n }\n\n return true;\n });\n }\n\n $this->debugLog($user, 'Internal meetings (?!) filtered');\n\n $this->response->getManager()\n ->parseIncludes([\n 'category',\n 'organizer.group',\n 'prospect',\n 'stage',\n 'opportunity',\n 'stats',\n 'scorecards',\n 'masterTrack',\n 'activeParticipants',\n 'notification',\n ])\n ->setSerializer(new JsonSerializer());\n\n $transformerExcludes = $this->request->input('exclude');\n if ($transformerExcludes) {\n $this->response->getManager()->parseExcludes($transformerExcludes);\n }\n\n $this->debugLog($user, 'Response Manager (?!) applied');\n\n $transformer = new ActivityTransformer();\n $transformer->setConsumer($user);\n\n $this->debugLog($user, 'Activity Transformer added');\n\n $resource = new \\League\\Fractal\\Resource\\Collection($activities, $transformer);\n $page = $searchCriteria->getPageNumber();\n\n $this->debugLog($user, 'Search criteria page number called', ['page' => $page]);\n\n $histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');\n\n $this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);\n\n return $this->response->withArray([\n 'pagination' => [\n 'total' => $searchResponse['totalHits'],\n 'current' => $page,\n 'prev' => max($page - 1, 1),\n 'next' => $page + 1,\n ],\n 'results' => $this->response->getManager()->createData($resource)->toArray(),\n 'histogram' => $histogram,\n ]);\n }\n\n private function debugLog(User $user, string $logMessage, ?array $context = []): void\n {\n // Debug for Learning People Only\n if ($user->getTeamId() !== 260) {\n return;\n }\n\n Log::notice(\n sprintf('[activity-search-controller] %s', $logMessage),\n $context\n );\n }\n\n /** @throws ValidationException */\n private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void\n {\n $rules = [\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ];\n\n if ($prefix !== null && mb_strpos($prefix, '.') !== false) {\n $rules[rtrim($prefix, '.')] = sprintf(\n 'required|array|max:%d',\n $filterSet->count()\n );\n }\n\n $validationRules = $filterSet->getValidationRules($prefix)\n ->merge($rules)\n ->all();\n\n $request->validate($validationRules);\n }\n\n public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $search = $this->updateOrCreateActivitySearch($request);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function updateActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('update', $search);\n\n $this->updateOrCreateActivitySearch($request, $search);\n\n return $this->response->withOk();\n }\n\n private function storeNamedSearchFilters(\n Collection $request,\n Search $search,\n FilterDefinitionCollection $filterSet,\n ?string $prefix = null,\n ): self {\n $arrayTypeProperties = $filterSet\n ->getPropertyTypes([\n FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,\n ])\n ->all();\n\n $supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);\n\n foreach ($supportedRequestProperties as $requestPropertyName) {\n if (! array_has($request, $requestPropertyName)) {\n continue;\n }\n\n /** @var string|string[] $propertyValue */\n $propertyValue = array_get($request, $requestPropertyName);\n $propertyName = $prefix === null\n ? $requestPropertyName\n : mb_substr($requestPropertyName, mb_strlen($prefix));\n\n $isArrayType = array_has($arrayTypeProperties, $propertyName);\n\n if (! $isArrayType) {\n /** @var string $requestPropertyValue */\n\n $search->filters()->updateOrCreate(\n [\n 'filter' => $propertyName,\n ],\n [\n 'value' => $propertyValue,\n ]\n );\n\n continue;\n }\n\n /** @var string[] $requestPropertyValue */\n\n /** @var SearchFilter[]|Collection $existingFilterValues */\n $existingFilterValuesKeyed = $search->filters()\n ->where('filter', $propertyName)\n ->get()\n ->keyBy('id');\n\n // Iterate over values provided as request parameters\n foreach ($propertyValue as $value) {\n /** @var SearchFilter|null $valueFilter */\n $valueFilter = $search->filters()\n ->where(\n [\n 'filter' => $propertyName,\n 'value' => $value,\n ]\n )\n ->first();\n\n if ($valueFilter !== null) {\n // Remove filter value pair from list to be deleted\n $existingFilterValuesKeyed->forget($valueFilter->id);\n } else {\n // Add new filter/value pair\n $search->filters()->updateOrCreate([\n 'filter' => $propertyName,\n 'value' => $value,\n ]);\n }\n }\n\n // Delete filter value pairs for this filter that no longer exist in request parameters\n foreach ($existingFilterValuesKeyed as $existingFilter) {\n $existingFilter->delete();\n }\n }\n\n /** @var Collection<int, SearchFilter> $filtersKeyed */\n $filtersKeyed = $search->filters()->get()->keyBy('filter');\n\n // wipe removed filters from this search\n foreach ($filtersKeyed as $filterName => $filter) {\n if (array_has($request, $prefix . $filterName)) {\n continue;\n }\n\n // Remove all filter values for this filter\n $search->filters()->where('filter', $filterName)->delete();\n }\n\n return $this;\n }\n\n /**\n * @throws AuthorizationException\n */\n public function fetchActivitySearch(\n Search $search,\n Request $request,\n SearchTransformer $searchTransformer,\n ): JsonResponse {\n $this->authorize('view', $search);\n\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection(\n $user->searches()->get(),\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n /**\n * Deletes a saved search\n *\n * @param Request $request\n * @param Search $search\n *\n * @throws Exception\n *\n * @return JsonResponse\n */\n public function deleteActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('delete', $search);\n\n // Orphan any AutomatedReports that use this search\n $search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);\n\n // Delete filters and the search itself\n $search->filters()->delete();\n $search->delete();\n\n return $this->response->withOk();\n }\n\n public function live(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n $user = $this->getUserFromRequest($request);\n\n $this->request->validate([\n 'sort_direction' => 'in:asc,desc',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ]);\n\n $activities = $repository->getLiveCoachingEligibleActivities(\n user: $user,\n lookBackMinutes: self::LOOK_BACK,\n limit: (int) $this->request->input('limit', 25),\n page: (int) $this->request->input('page', 1),\n sortBy: ['actual_start_time', 'scheduled_start_time'],\n sortDirection: (string) $this->request->input('sort_direction', 'asc'),\n );\n\n $this->response\n ->getManager()\n ->parseIncludes(['organizer.group', 'prospect'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($activities, new ActivityTransformer());\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function show(Activity $activity, ActivityService $activityService): JsonResponse\n {\n $this->authorize('show', $activity);\n\n $user = $activity->getUser();\n $team = $user->getTeam();\n\n // Sync the opportunity with the latest data if possible.\n if ($activity->opportunity_id) {\n try {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n if (! $user->isCrmRequired()) {\n $crmService->setUser($team->getOwner());\n } else {\n $crmService->setUser($user);\n }\n\n $crmService->syncOpportunity($activity->opportunity->crm_provider_id);\n } catch (Exception $exception) {\n // Move on.\n }\n }\n\n $activityData = $activityService->getActivityData($this->request->user(), $activity);\n\n return response()->json($activityData);\n }\n\n public function createRecording(Activity $activity)\n {\n $this->authorize('record', $activity);\n\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Tell Twilio to start recording this activity.\n if ($activity->recording_state === Activity::RECORDING_OFF) {\n $job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withCreated();\n }\n\n return $this->response->errorGone('Activity is already recording.');\n }\n\n public function updateRecording(Request $request, Activity $activity)\n {\n $this->authorize('record', $activity);\n\n $request->validate([\n 'preference' => 'boolean',\n 'state' => [\n 'string',\n Rule::in([\n Activity::RECORDING_IN_PROGRESS,\n Activity::RECORDING_PAUSED,\n ]),\n ],\n ]);\n\n if ($request->has('state')) {\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Toggle the recording state between paused and resumed.\n if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {\n $job = (new ToggleRecording($activity, $request->input('state')))\n ->onQueue(Constants::QUEUE_CONFERENCES);\n\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Recording is not toggleable.');\n }\n\n if ($request->has('preference')) {\n $activity->update([\n 'recording_preference' => $request->input('preference') ? 1 : 0,\n ]);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorWrongArgs('Something went wrong');\n }\n\n public function stopRecording(Activity $activity)\n {\n $this->authorize('stopRecord', $activity);\n\n // Tell Twilio to stop recording this activity.\n if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {\n $job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Activity is not recording.');\n }\n\n /**\n * Add activity to this user's favorites playlist\n *\n * @throws AuthorizationException\n */\n public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse\n {\n $this->authorize('favorite', $activity);\n\n $user = $this->getUserFromRequest($this->request);\n $favorite = $activity->wasFavoritedBy($user);\n $name = $activity->activity_title ?? '';\n\n // It needs to check at least one record.\n if (! $favorite) {\n $favoritePlaylist = $user->favoritePlaylist();\n\n $playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(\n $activity,\n $user,\n $favoritePlaylist\n );\n\n if ($playlistActivity !== null) {\n $playlistActivity->update(\n // Just update, don't sort.\n ['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],\n );\n } else {\n $playlistActivity = $activity->playlistActivities()->create([\n 'playlist_id' => $favoritePlaylist->getId(),\n 'user_id' => $user->getId(),\n 'start_time' => 0,\n 'name' => mb_strimwidth($name, 0, 100),\n ]);\n // Sort it on top.\n $playlistActivity->update(\n [\n 'sort' => $playlistActivityRepository->calculateNewSortOrder(\n null,\n $playlistActivity,\n ),\n ],\n );\n }\n\n $playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);\n\n return new JsonResponse([], JsonResponse::HTTP_CREATED);\n }\n\n return new JsonResponse(\n [\n 'error' => [\n 'code' => AbstractResponse::CODE_CONFLICT,\n 'http_code' => JsonResponse::HTTP_CONFLICT,\n 'message' => 'Resource Already Exists',\n ],\n ],\n JsonResponse::HTTP_CONFLICT,\n );\n }\n\n /**\n * Remove activity from this user's favorites playlist\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unfavorite(Activity $activity)\n {\n $user = $this->request->user();\n\n $favorites = $activity->favoritedBy($user);\n\n if ($favorites && $favorites->isEmpty()) {\n return $this->response->errorNotFound('Favorite not found.');\n }\n\n $this->authorize('unfavorite', [$activity, $favorites]);\n\n // When you unfavorite an activity,\n // it should remove all the activities in it, including snippets.\n $isDeleted = $favorites->each(function ($favorite) {\n $favorite->forceDelete();\n });\n\n if ($isDeleted) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not remove favorite.');\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function notify(Activity $activity)\n {\n $this->authorize('notify', $activity);\n\n $user = $this->request->user();\n\n $existingNotification = $activity->availabilityNotifications()\n ->where('user_id', $user->id)\n ->exists();\n\n if ($existingNotification) {\n return $this->response->errorWrongArgs('Notification is already configured.');\n }\n\n $notification = Activity\\AvailabilityNotification::create([\n 'user_id' => $user->id,\n 'activity_id' => $activity->id,\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($notification, new AvailabilityNotificationTransformer());\n }\n\n /**\n * @param Activity $activity\n * @param Activity\\AvailabilityNotification $notification\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unnotify(Activity $activity, Activity\\AvailabilityNotification $notification)\n {\n $this->authorize('unnotify', [$activity, $notification]);\n\n if ($notification->sent_at || $notification->delete()) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not delete notification.');\n }\n\n public function play(Request $request, Activity $activity)\n {\n $this->authorize('stream', $activity);\n\n $request->validate([\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $activity->plays()->create([\n 'user_id' => $user->getId(),\n 'start_time' => $request->input('start_time'),\n ]);\n\n return $this->response->withCreated();\n }\n\n /**\n * @param Activity $activity\n *\n * @return mixed\n */\n public function comment(Activity $activity)\n {\n return $this->newComment($activity);\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @return mixed\n */\n public function replyComment(Activity $activity, Comment $comment)\n {\n return $this->newComment($activity, $comment);\n }\n\n /**\n * @param Activity $activity\n * @param Comment|null $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n protected function newComment(Activity $activity, ?Comment $comment = null)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n 'type' => 'integer|between:0,3',\n 'visibility' => sprintf('nullable|integer|between:1,%d', count(Comment::getVisibilityLevels())),\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n $threadStartId = null;\n if ($comment) {\n $threadStartId = $comment->thread_start_id ?: $comment->id;\n }\n\n try {\n $newComment = Comment::create([\n 'parent_comment_id' => $comment->id ?? null,\n 'thread_start_id' => $threadStartId,\n 'activity_id' => $activity->id,\n 'user_id' => $this->request->user()->id,\n 'comment' => trim($this->request->input('comment')),\n 'start_time' => $this->request->input('start_time', 0),\n 'end_time' => $this->request->input('end_time', 0),\n 'type' => $this->request->input('type', Comment::TYPE_NEUTRAL),\n 'visibility' => $this->request->input('visibility', Comment::VISIBILITY_PUBLIC),\n ]);\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($newComment, new ActivityCommentTransformer());\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not create comment.' . $exception->getMessage());\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function updateComment(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n try {\n $comment->update([\n 'comment' => trim($this->request->input('comment')),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment.');\n }\n }\n\n public function updateCommentVisibility(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'visibility' => sprintf('integer|between:1,%d', count(Comment::getVisibilityLevels())),\n ]);\n\n $visibility = $this->request->input('visibility');\n\n if ($comment->parent !== null) {\n return $this->response->errorWrongArgs('Comment visibility can only be updated on top level comments.');\n }\n\n try {\n $this->activityCommentService->updateCommentVisibility($comment, $visibility);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment\\'s visibility.');\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function deleteComment(Activity $activity, Comment $comment)\n {\n $this->authorize('deleteComment', [$activity, $comment]);\n\n // Delete comment and any children.\n $comment->delete();\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function fetchComments()\n {\n $user = $this->request->user();\n $this->request->validate([\n 'forUserId' => 'uuid:users,team_id,' . $user->team_id,\n 'types' => 'array',\n 'types.*' => 'integer|between:0,3',\n ]);\n $forUser = null;\n\n $types = [Comment::TYPE_NEUTRAL, Comment::TYPE_GAME_CHANGER, Comment::TYPE_POSITIVE];\n $user = $this->request->user();\n if ($this->request->has('forUserId')) {\n $forUser = $user->team->users()->uuid($this->request->input('forUserId'));\n }\n\n $comments = Comment::query()\n ->whereHas('activity', static function (Builder $builder) use ($user, $forUser): void {\n $builder\n // I left feedback on my own activity; or\n ->where('activities.user_id', $user->getId());\n if ($forUser) {\n // I left feedback on any activity for this user.\n $builder->orWhere([\n 'user_id' => $user->getId(),\n 'activities.user_id' => $forUser->getId(),\n ]);\n }\n })\n ->whereIn('type', $this->request->input('types', $types))\n ->orderBy('created_at', 'desc')\n ->get();\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity', 'user'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($comments, new ActivityCommentTransformer());\n }\n\n public function deleteCoachingFeedback(Activity $activity, CoachingFeedback $coachingFeedback)\n {\n $this->authorize('deleteCoachingFeedback', [$activity, $coachingFeedback]);\n $activity = $coachingFeedback->getActivity();\n\n if ($coachingFeedback->delete()) {\n event(new UpdateSingleEntity(\n entityId: $activity->getId(),\n updateTarget: UpdateTargetEnum::ACTIVITY,\n purpose: 'delete-coaching-feedback',\n ));\n\n return $this->response->withOk();\n }\n\n return $this->response->withError('Delete operation failed. Contact support.', 500);\n }\n\n /**\n * Add new or update Coaching feedback\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws \\Illuminate\\Validation\\ValidationException\n *\n * @return mixed\n */\n public function putCoachingFeedback(Request $request, Activity $activity)\n {\n $user = $request->user();\n\n if (! $user instanceof User) {\n abort(403);\n }\n $teamId = $user->getTeamId();\n\n $this->authorize('coach', $activity);\n\n $this->request->validate([\n 'coach_id' => 'required|uuid:users,team_id,' . $teamId,\n 'coachee_id' => 'required|uuid:users,team_id,' . $teamId,\n 'visibility' => ['required', Rule::in(CoachingFeedback::VISIBILITIES)],\n 'coaching_sections.*.uuid' => 'required|uuid:coaching_sections',\n 'coaching_sections.*.score' => ['required', Rule::in(CoachingSectionFeedback::SCORES)],\n 'coaching_sections.*.summary' => 'string|max:10000',\n 'coaching_sections.*.criteria.*.uuid' => 'required|uuid:coaching_section_criteria',\n 'coaching_sections.*.criteria.*.note' => 'required|string|max:10000',\n 'sharedWithUsers' => [\n 'required_if:visibility,' . CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS,\n 'array',\n ],\n 'sharedWithUsers.*' => [\n 'uuid:users,team_id,' . $teamId,\n ],\n ]);\n\n /** @var User $coach */\n $coach = User::uuid($this->request->input('coach_id'));\n /** @var User $coachee */\n $coachee = User::uuid($this->request->input('coachee_id'));\n $coachingSectionFeedbacks = $this->request->input('coaching_sections');\n\n $previousRecord = $this->coachingFeedbackRepository->getOneForActivityByCoacheeAndCoach(\n $coachee->getId(),\n $coach->getId(),\n $activity->getId()\n );\n $recordIsNew = false;\n if ($previousRecord === null) {\n $recordIsNew = true;\n }\n\n if (! $coachee->isSameTeamId($coach)) {\n return $this->response->errorForbidden('User not member of your team.');\n }\n\n if (! is_array($coachingSectionFeedbacks) || count($coachingSectionFeedbacks) < 1) {\n return $this->response->withError('At least one Coaching Framework Section shall be scored.', 422);\n }\n\n if (! $activity->participants()->where('participants.user_id', $coachee->id)->exists()) {\n return $this->response->withError('Coached user did not participate activity.', 422);\n }\n\n $visibility = $this->request->input('visibility');\n\n $shouldSendNotification = $recordIsNew;\n if ($recordIsNew === false && $visibility !== $previousRecord->getVisibility()) {\n $shouldSendNotification = true;\n }\n\n /**\n * Create CoachingFeedback\n *\n * @var CoachingFeedback $coachingFeedback\n */\n $coachingFeedback = $activity->coachingFeedbacks()->updateOrCreate(\n [\n 'coach_id' => $coach->id,\n 'coachee_id' => $coachee->id,\n ],\n [\n 'framework_id' => $activity->category->id,\n 'visibility' => $visibility,\n ]\n );\n\n $sharedUserIds = [];\n if ($visibility === CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS) {\n foreach ($this->request->input('sharedWithUsers') as $sharedWithUserUuid) {\n /** @var User $user */\n $user = User::uuid($sharedWithUserUuid);\n $sharedUserIds[] = $user->getId();\n }\n }\n\n $syncResult = $coachingFeedback->customAccessUsers()->sync($sharedUserIds);\n\n $scores = [];\n\n\n /**\n * Create CoachingSectionsFeedbacks.\n *\n * @var CoachingSectionFeedback $coachingSectionFeedback\n */\n foreach ($coachingSectionFeedbacks as $coachingSectionFeedbackInput) {\n $coachingSection = CoachingSection::uuid($coachingSectionFeedbackInput['uuid']);\n $coachingSectionFeedback = $coachingFeedback->sectionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_id' => $coachingSection->id,\n ],\n [\n 'score' => array_get($coachingSectionFeedbackInput, 'score'),\n 'summary' => array_get($coachingSectionFeedbackInput, 'summary') ?? '',\n ]\n );\n\n $scores[] = array_get($coachingSectionFeedbackInput, 'score');\n\n $criteria = array_get($coachingSectionFeedbackInput, 'criteria');\n if (is_array($criteria) && ! empty($criteria)) {\n foreach ($criteria as $criteriaFeedbackInput) {\n $coachingSectionFeedback->criterionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_criterion_id' => CoachingSectionCriterion::uuid(array_get($criteriaFeedbackInput, 'uuid'))\n ->id,\n ],\n ['note' => array_get($criteriaFeedbackInput, 'note')],\n );\n }\n }\n }\n\n $coachingFeedback->average_score = array_sum($scores) / count($scores);\n\n if ($recordIsNew === false && $coachingFeedback->getAverageScore() !== $previousRecord->getAverageScore()) {\n $shouldSendNotification = true;\n }\n if (! empty($syncResult['attached']) || ! empty($syncResult['detached']) || ! empty($syncResult['updated'])) {\n $shouldSendNotification = true;\n }\n\n $coachingFeedback->save();\n // ensure updated at for coaching feedback on section feedback summary added.\n $coachingFeedback->touch();\n\n if ($shouldSendNotification) {\n event(new Coached($coachingFeedback));\n }\n\n Datadog::increment('jiminny.activity.score.update', 1, ['company' => $activity->user->team->slug]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n $coachingFeedbackTransformer = new CoachingFeedbackTransformer();\n $coachingFeedbackTransformer->setConsumer($this->getUserFromRequest($request));\n\n return $this->response->withItem($coachingFeedback, $coachingFeedbackTransformer);\n }\n\n\n /**\n * Retrieve category criteria for coaching.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachingSections(Activity $activity)\n {\n $this->authorize('coach', $activity);\n\n if ($activity->category === null) {\n return $this->response->errorUnprocessable('Category has not yet been assigned.');\n }\n\n $criteria = $activity\n ->category\n ->coachingSections()\n ->where('is_enabled', 1)\n ->orderBy('sequence', 'asc');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($criteria->get(), new CoachingSectionsTransformer());\n }\n\n /**\n * @throws AuthorizationException\n * @throws ValidationException\n *\n * @return mixed\n */\n public function addToPlaylist(Activity $activity, PlaylistTrackFactoryInterface $playlistTrackFactory)\n {\n $this->request->validate([\n 'playlists' => 'required|array',\n 'playlists.*' => 'uuid:playlists',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'name' => 'required|max:100',\n ]);\n\n $this->authorize('addToPlaylist', [$activity, $this->request->input('playlists')]);\n\n $startTime = $this->request->input('start_time');\n $endTime = $this->request->input('end_time');\n $name = $this->request->input('name');\n /** @var User $user */\n $user = $this->request->user();\n\n // Get playlist by uuid.\n foreach ($this->request->input('playlists') as $playlistId) {\n // Pull out the playlist model.\n $playlist = Playlist::uuid($playlistId);\n\n $playlistTrackFactory->createTrack($playlist, $user, [\n 'name' => $name,\n 'activity' => $activity,\n 'start_time' => $startTime,\n 'end_time' => $endTime,\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function share(Request $request, Activity $activity): JsonResponse\n {\n $this->authorize('share', $activity);\n\n $request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'recipients.*.type' => 'in:user,group',\n 'recipients.*.id' => 'string|max:40',\n 'share' => 'string|max:255',\n ]);\n\n $user = $request->user();\n\n $recipients = $request->get('recipients');\n $users = $this->userService->convertRecipientsToUsers($user, $recipients);\n\n $shareData = [\n 'from_user_id' => $user->id,\n 'note' => $request->input('note'),\n 'start_time' => $request->input('start_time'),\n 'end_time' => $request->input('end_time'),\n ];\n\n // Create a share object against a notification provider channel\n if ($request->input('share')) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'notification_provider_channel' => $request->input('share'),\n ]\n )\n );\n\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n\n // Create a share object against each recipient\n foreach ($users as $recipient) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'to_user_id' => $recipient->id,\n ]\n )\n );\n\n // If parent_share_id has been selected yet\n if (! isset($shareData['parent_share_id'])) {\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachRequest(Activity $activity)\n {\n $this->authorize('coachRequest', $activity);\n\n $this->request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'coachers.*.type' => 'required|in:user',\n 'coachers.*.id' => 'required',\n ]);\n\n $coachers = $this->request->get('coachers');\n $user = $this->request->user();\n $users = $this->userService->convertRecipientsToUsers($user, $coachers);\n\n foreach ($users as $coacher) {\n CoachRequest::create([\n 'user_id' => $coacher->id,\n 'activity_id' => $activity->id,\n 'note' => $this->request->get('note'),\n 'start_time' => $this->request->get('start_time'),\n 'end_time' => $this->request->get('end_time'),\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function createActivityTopicTriggers(Activity $activity, LoggerInterface $logger): HttpFoundation\\JsonResponse\n {\n $this->authorize('analyzeTopicTriggers', $activity);\n\n if (! $activity->hasTranscription()) {\n return new HttpFoundation\\JsonResponse(\n [\n 'error' => 'Transcription not found.',\n ],\n JsonResponse::HTTP_NOT_FOUND\n );\n }\n\n $logger->info(__METHOD__ . ': queued for analysis', [\n 'activity' => $activity->id_string,\n ]);\n\n dispatch(new ActivityAnalytics\\Job\\AnalyzeActivityTopicTriggers($activity));\n\n return new HttpFoundation\\JsonResponse(null, JsonResponse::HTTP_CREATED);\n }\n\n public function fetchActivityTopicTriggers(\n Activity $activity,\n LoggerInterface $logger,\n ActivityTopicTriggerTransformer $transformer\n ): HttpFoundation\\JsonResponse {\n $this->authorize('fetchTopicTriggers', $activity);\n\n $logger->debug(__METHOD__, [\n 'activity' => $activity->id_string,\n ]);\n\n if (! $activity->isProcessed()) {\n return new HttpFoundation\\JsonResponse([]);\n }\n\n $payload = [];\n\n if ($activity->hasTopicTriggers()) {\n $payload = $activity->getTopicTriggersSorted()\n ->map(\n static fn (Activity\\TopicTrigger $activityTopicTrigger): array\n => $transformer->transform($activityTopicTrigger)\n )\n ->values()\n ->all();\n }\n\n return new HttpFoundation\\JsonResponse($payload);\n }\n\n /**\n * @param Activity $activity\n * @param StatsTransformer $statsTransformer\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function stats(Activity $activity, StatsTransformer $statsTransformer)\n {\n $this->authorize('stream', $activity);\n\n if (! $activity->hasTranscription()) {\n return $this->response->errorNotFound('Waveform data is not yet generated.');\n }\n\n $this->response\n ->getManager()\n ->parseIncludes(['wavedata'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($activity, $statsTransformer);\n }\n\n public function destroy(Activity $activity)\n {\n $this->authorize('delete', $activity);\n\n $activity->delete();\n\n \\Log::info('Soft delete activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n\n return $this->response->withNoContent();\n }\n\n public function note(Activity $activity)\n {\n $this->authorize('note', $activity);\n\n $this->request->validate([\n 'note' => 'required|min:1|max:2000',\n 'time' => 'required|numeric|min:0|max:86400',\n ]);\n\n $note = $this->request->input('note');\n $time = $this->request->input('time');\n\n $this->activityService->setActivity($activity);\n $this->activityService->takeNote($this->getUser(), $note, $time);\n\n return $this->response->withCreated();\n }\n\n /**\n * Mark an activity as private.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPrivate(Activity $activity)\n {\n $this->authorize('markAsPrivate', $activity);\n\n if ($activity->is_private === false) {\n $activity->is_private = true;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * Mark an activity as public.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPublic(Activity $activity)\n {\n $this->authorize('markAsPublic', $activity);\n\n if ($activity->is_private) {\n $activity->is_private = false;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws LogicException\n */\n public function fetchCloudFrontS3MediaKeys(Activity $activity, PlaybackService $playbackService): JsonResponse\n {\n $masterTrack = $activity->masterTrack()->first();\n\n if (! $masterTrack instanceof Track) {\n throw new LogicException(sprintf('Master track not found for activity \"%s\"', $activity->getUuid()));\n }\n\n return $this->response->withArray(\n $playbackService->generateCookies(\n $masterTrack,\n $this->request->ip(),\n ),\n );\n }\n\n /**\n * @throws ValidationException\n */\n private function updateOrCreateActivitySearch(Request $request, ?Search $search = null): Search\n {\n $request->validate([\n 'name' => 'required|string|min:2|max:100',\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $searchName = $request->input('name');\n\n if ($search !== null) {\n $search->update([\n 'name' => $searchName,\n ]);\n\n return $search;\n }\n\n $request->validate([\n 'filters' => ['required', 'array', new MultidimensionalArrayMaxCharRule(limit: 255)],\n 'nudges' => 'array|max:' . count(Nudge::MAP_CHANNEL),\n 'nudges.*.channel' => 'required|in:' . implode(',', Nudge::MAP_CHANNEL),\n 'nudges.*.frequency' => 'required|in:' . implode(',', Nudge::MAP_FREQUENCY),\n 'nudges.*.expiresAt' => [\n 'required',\n 'date',\n 'after:today',\n 'before_or_equal:' . now()->addYear()->format('Y-m-d'),\n ],\n ]);\n\n $searchCriteria = Criteria::createFromRequest(\n Collection::make($request->input('filters', []))->all(),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($searchCriteria, $user);\n $this->validateSearch($request, $filterSet, 'filters.');\n\n /** @var Search $search */\n $search = Search::create([\n 'name' => $searchName,\n 'uuid' => Uuid::uuid4()->toString(),\n 'user_id' => $user->getId(),\n ]);\n\n Collection::make($request->input('nudges', []))\n ->each(fn (array $attributes): Nudge => $this->nudgeFactory->createNudge($search, $attributes));\n\n $this->storeNamedSearchFilters(Collection::make($request->all()), $search, $filterSet, 'filters.');\n\n return $search;\n }\n\n private function resolveAccount(\n Team $team,\n Contact $contact,\n ServiceInterface $crmService,\n array $prospects,\n ): ?Account {\n $this->logger->info('Resolving account from contact');\n $account = $contact->getAccount();\n\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS)) {\n $this->logger->info('Team does not have feature to link activity to multiple prospects');\n\n return $account;\n }\n\n $this->logger->info('Resolving account from prospect data');\n $accountData = array_filter(\n $prospects,\n static fn (array $prospectData): bool => $prospectData['type'] === 'account'\n );\n\n if (! empty($accountData)) {\n $this->logger->info('Found account data in prospects');\n $accountData = reset($accountData);\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountData['id'])->first();\n\n if (! $account instanceof Account) {\n $this->logger->info('Account not found in database, syncing from CRM');\n $account = $crmService->syncAccount($accountData['id']);\n }\n }\n\n $this->logger->info('Resolved account', ['account' => $account->getId()]);\n\n return $account;\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":"40","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"40","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"64","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","depth":4,"on_screen":true,"value":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","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}]...
|
-7287184300264252456
|
-8385861013499833196
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use Carbon\Carbon;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\In;
use Illuminate\Validation\ValidationException;
use InvalidArgumentException;
use Jiminny\Component\ActivityAnalytics;
use Jiminny\Component\ActivitySearch;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Queue\Constants;
use Jiminny\Contracts\ES\Events\UpdateSingleEntity;
use Jiminny\Contracts\ES\UpdateTargetEnum;
use Jiminny\Contracts\Nudge\NudgeFactoryInterface;
use Jiminny\Contracts\Playlist\PlaylistTrackFactoryInterface;
use Jiminny\Contracts\Repositories\PlaylistActivityRepository;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Enums\TeamSetting;
use Jiminny\Events\Activities\AiAutomation\ActivityProspectAdded;
use Jiminny\Events\Activities\Coaching\Coached;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Controllers\CommentContextInterface;
use Jiminny\Http\Responses\Api\AbstractResponse;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\ActivityCommentTransformer;
use Jiminny\Http\Transformers\ActivityTopicTriggerTransformer;
use Jiminny\Http\Transformers\ActivityTransformer;
use Jiminny\Http\Transformers\AvailabilityNotificationTransformer;
use Jiminny\Http\Transformers\CoachingFeedbackTransformer;
use Jiminny\Http\Transformers\CoachingSectionsTransformer;
use Jiminny\Http\Transformers\SearchTransformer;
use Jiminny\Http\Transformers\StatsTransformer;
use Jiminny\Jobs\Crm\SaveActivity;
use Jiminny\Jobs\Crm\UpdateStage;
use Jiminny\Jobs\Telephony\StartRecording;
use Jiminny\Jobs\Telephony\StopRecording;
use Jiminny\Jobs\Telephony\ToggleRecording;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\CoachingFeedback;
use Jiminny\Models\CoachingSection;
use Jiminny\Models\CoachingSectionCriterion;
use Jiminny\Models\CoachingSectionFeedback;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\LanguageDialect;
use Jiminny\Models\Lead;
use Jiminny\Models\Nudge;
use Jiminny\Models\PlaybookCategory;
use Jiminny\Models\Playlist;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\Track;
use Jiminny\Models\User;
use Jiminny\Repositories\CoachingFeedbackRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Rules\CrmReference;
use Jiminny\Rules\MultidimensionalArrayMaxCharRule;
use Jiminny\Services\ActivityService;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Services\PlaybackService;
use Jiminny\Services\UserService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
use Ramsey\Uuid\Uuid;
use Sentry;
use Symfony\Component\HttpFoundation;
final class ActivityController extends Controller implements CommentContextInterface
{
// Number of minutes to look back on activities. i.e. a timeout on activity duration.
private const int LOOK_BACK = 180;
public function __construct(
private ProviderRegistry $providerRegistry,
private ActivityService $activityService,
Response $response,
private UserService $userService,
private ActivitySearch\Service\ActivitySearch $activitySearch,
private NudgeFactoryInterface $nudgeFactory,
private ActivityCommentService $activityCommentService,
private LoggerInterface $logger,
private readonly CoachingFeedbackRepository $coachingFeedbackRepository,
private readonly TeamRepository $teamRepository,
) {
parent::__construct($response);
}
public static function getCommentImplementation(): string
{
return Comment::class;
}
public function delete()
{
$this->request->validate([
'*' => 'uuid:activities',
]);
$deletedIds = [];
foreach ($this->request->all() as $activityId) {
$activity = Activity::idOrUuId($activityId);
try {
if ($this->authorize('delete', $activity)) {
$activity->delete();
$deletedIds[] = $activityId;
\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);
}
} catch (AuthorizationException $authorizationException) {
// They didn't have permission.
}
}
return $this->response->withArray($deletedIds);
}
public function update(Request $request, Activity $activity)
{
$this->authorize('updateMetadata', $activity);
$request->validate([
'title' => 'string|max:250',
'category_id' => 'uuid:playbook_categories',
'language' => [
new In(
LanguageDialect::query()
->with('language')
->cursor()
->map(static function (LanguageDialect $languageDialect): string {
return $languageDialect->getLanguageLocale();
})
->all()
),
],
]);
if ($request->has('title')) {
$activity->title = $request->input('title');
}
if ($request->has('category_id')) {
$category = PlaybookCategory::uuid($request->input('category_id'));
if ($category->playbook->team_id !== $request->user()->team_id) {
return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
if ($request->has('language')) {
if (! $activity->isInProgress()) {
return $this->response->withError(
'Activity language can only be set while the meeting is in progress.',
400
);
}
$activity->setLanguageCode($request->input('language'));
}
$activity->save();
return $this->response->withOk();
}
// XXX: This should be merged with the update method.
/**
* @param Activity $activity
*
* @throws AuthorizationException
* @throws SocialAccountTokenInvalidException
*
* @return mixed
*/
public function summarize(Activity $activity): mixed
{
$this->logger->info('[Log Activity] Summarizing activity ', [
'activityId' => $activity->getUuid(),
'payload' => $this->request->all(),
]);
$this->authorize('update', $activity);
$this->logger->info('[Log Activity] Validating summary');
// Validate the payload.
$this->validateSummary($activity);
// All objects must belong to this team.
/** @var User $user */
$user = $this->request->user();
$team = $user->getTeam();
$crmService = $this->providerRegistry->get($team->crm->provider);
try {
$crmUser = $user;
if ($user->isCrmRequired() === false) {
$crmUser = $team->owner;
}
$crmService->setUser($crmUser);
} catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());
}
$rawEntities = $this->request->input('entities');
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid(
$this->request->input('layout_id')
);
// Delay execution of CRM jobs to avoid locking issues.
$jobDelay = 0;
// If we have arrived from a notification, mark it as read.
$notificationId = $this->request->input('nId');
if ($notificationId) {
$notification = $user->unreadNotifications->where('id', $notificationId)->first();
if ($notification) {
$notification->markAsRead();
}
}
$title = $this->request->input('title');
$prospects = $this->request->input('prospects');
$opportunityId = $this->request->input('opportunity_id');
$stageId = $this->request->input('stage_id');
$categoryId = $this->request->input('category_id');
$summary = $this->request->input('summary');
$crmProviderId = $this->request->input('crm_id');
$isInternal = $this->request->input('is_internal') ?? false;
$lead = null;
$category = null;
$account = null;
$contact = null;
$opportunity = null;
$stage = null;
$callStage = null;
foreach ($prospects as $prospectData) {
$objectId = $prospectData['id'];
if ($objectId === null) {
continue;
}
$objectType = $prospectData['type'];
$this->logger->info('debug', ['prospect_data' => $prospectData]);
try {
if ($objectType === null) {
$this->logger->info('no object type');
if ($crmService instanceof SupportsObjectTypeParseInterface) {
$objectType = $crmService->parseObjectType($objectId);
}
}
switch ($objectType) {
case 'lead':
$this->logger->info('Processing lead');
/** @var Lead|null $lead */
$lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();
// Lead does not exist locally, import it.
if ($lead === null) {
$this->logger->info('Lead does not exist locally');
/** @var Lead $lead */
$lead = $crmService->syncLead($objectId);
}
$this->logger->info('Lead found', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
if ($stageId === null) {
$this->logger->info('Stage ID is null');
// If it was not provided, just assume it is the current stage.
$callStage = $lead->stage;
break;
}
$this->logger->info('Looking for stage');
// Determine if they have changed the stage.
/** @var Stage $stage */
$stage = $team->crm->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_LEAD)
->firstOrFail();
$this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);
if ($lead->stage_id && $lead->stage_id !== $stage->id) {
$this->logger->info('Stage has changed');
// Storage current stage on activity.
$callStage = $lead->stage;
// The stage has changed, update in remote CRM.
dispatch(new UpdateStage($activity, $lead, $callStage, $stage));
$this->logger->info(
sprintf(
'[%s] User changing lead stage from %s to %s',
$crmService->getDisplayName(),
$callStage->getName(),
$stage->getName()
),
[
'user' => $user->getUuid(),
'lead' => $lead->getUuid(),
]
);
} else {
$this->logger->info('Stage has not changed');
// Stage remains as current.
$callStage = $stage;
}
break;
case 'account':
$this->logger->info('Processing account');
// If the object is not a lead, it should be an account.
$account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();
// Account does not exist locally, import it.
if ($account === null) {
$this->logger->info('Account does not exist locally');
$account = $crmService->syncAccount($objectId);
}
$this->logger->info('Account found', ['accountId' => $account->id]);
break;
case 'contact':
$this->logger->info('processing contact');
$contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$this->logger->info('contact does not exist locally');
$contact = $crmService->syncContact($objectId);
}
$this->logger->info('resolving account');
$account = $this->resolveAccount($team, $contact, $crmService, $prospects);
break;
}
// If they have specified an opportunity, retrieve this with stage.
if ($opportunityId) {
$this->logger->info('opportunity id is set');
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if ($opportunity === null) {
$this->logger->info('opportunity does not exist locally');
$opportunity = $crmService->syncOpportunity($opportunityId);
}
if ($stageId === null) {
$this->logger->info('stage id is null');
// If it was not provided, just assume it is the current stage.
$callStage = $opportunity->stage ?? null;
} else {
$this->logger->info('looking for stage');
/** @var ?Stage $opportunityStage */
$opportunityStage = $team->crm
->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
// There is a chance we still cannot import this opportunity.
if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {
$this->logger->info('opportunity stage has changed');
// Storage current stage on activity.
$callStage = $opportunity->stage;
dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));
$this->logger->info(
sprintf(
'[%s] User changing opportunity stage from %s to %s',
$crmService->getDisplayName(),
$callStage->name,
$opportunityStage->name
),
[
'userId' => $user->id_string,
'opportunityId' => $opportunity->id_string,
]
);
} else {
$this->logger->info('opportunity stage has not changed');
// Stage remains as current.
$callStage = $opportunityStage;
}
}
}
if ($crmProviderId) {
// Cast $crmProviderId to string otherwise it won't use database index for some records
$linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();
// Check if this activity has already been assigned to a different activity.
if ($linkedActivity && $linkedActivity->id !== $activity->id) {
throw new InvalidArgumentException(
'Sorry, the linked task has already been logged under a different call. '
. 'Please choose another linked task.'
);
}
}
} catch (InvalidArgumentException $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($exception->getMessage());
} catch (Exception $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorInternalError(
'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'
);
}
}
if ($categoryId) {
$category = PlaybookCategory::uuid($categoryId);
if ($category->playbook->team_id !== $team->id) {
throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
$this->logger->info('Prospect data', [
'lead_id' => $lead?->getId(),
'account_id' => $account?->getId(),
'contact_id' => $contact?->getId(),
'opportunity_id' => $opportunity?->getId(),
'stage_id' => $stage?->getId(),
]);
if ($title) {
$activity->title = $title;
}
if ($summary) {
$activity->summary = $summary;
}
if ($crmProviderId) {
$activity->crm_provider_id = $crmProviderId;
}
if ($callStage) {
$this->logger->info('Setting stage id', ['stageId' => $callStage->id]);
$activity->stage_id = $callStage->id;
}
if ($lead) {
$this->logger->info('Setting lead id', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
// If we are changed from an account > lead, unset the account data.
$this->logger->info('Unsetting account id, opportunity id, contact id, value');
$activity->account_id = null;
$activity->opportunity_id = null;
$activity->contact_id = null;
$activity->value = null;
}
if ($account) {
$this->logger->info('Setting account id', ['accountId' => $account->id]);
$activity->account_id = $account->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('unsetting lead id');
$activity->lead_id = null;
// Unset the contact if switching different accounts. Will be set up below if still applicable.
if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {
$this->logger->info('Unsetting contact id');
$activity->contact_id = null;
}
}
if ($opportunity) {
$this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);
$this->logger->info('unsetting lead id');
$activity->opportunity_id = $opportunity->id;
$activity->value = $opportunity->value;
// If we are changed from an lead > account, unset the lead data.
$activity->lead_id = null;
}
if ($contact) {
$this->logger->info('setting contact id', ['contactId' => $contact->id]);
$activity->contact_id = $contact->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('Unsetting lead id');
$activity->lead_id = null;
}
$activity->is_internal = $isInternal;
$activity->save();
$activity->refresh();
$this->logger->notice('Activity saved', [
'activity_id' => $activity->getId(),
'lead_id' => $activity->lead_id,
'account_id' => $activity->account_id,
'contact_id' => $activity->contact_id,
'opportunity_id' => $activity->opportunity_id,
'stage_id' => $activity->stage_id,
'crm_provider_id' => $activity->getCrmProviderId(),
]);
// Store entities as field data on the activity.
$updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);
if ($activity->isLoggable()) {
// Follow-up Task or Event data.
$followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);
$this->logger->info('CRM LOG manual log triggered', [
'activityId' => $activity->getUuid(),
'followupData' => $followupData,
'userId' => $user->getUuid(),
]);
// Store data in the CRM.
// ++add check for crm_required
$job = new SaveActivity($activity, $followupData);
if ($updatedData) {
$job->delay(Carbon::now()->addMinutes($jobDelay));
}
dispatch($job);
// Manually dispatch log for Opportunity or Prospect added
if ($activity->hasOpportunity() || $activity->hasProspect()) {
event(new ActivityProspectAdded(
activity: $activity,
eventSource: 'manually-log-crm-data'
));
}
}
return $this->response->withOk();
}
/**
* Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.
*
* @param ServiceInterface $service
* @param Activity $activity
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array
{
$updatedData = [];
$existingData = $activity->data()->get();
// We need to delete any existing data to overwrite with latest values.
$activity->data()->delete();
$layoutEntities = $layout->entities()
->with('field', 'parent')
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->get();
/** @var LayoutEntity $entity */
foreach ($layoutEntities as $entity) {
// If the user has provided a value for this entity
if (array_key_exists($entity->id_string, $entities)) {
$value = $entities[$entity->id_string];
// Convert raw data into values that the CRM can consume.
if ($value) {
$value = $service->normalizeValue($entity->field->type, $value);
}
// Check the field is part of the activity-summary section.
if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {
// This is the internal database ID, not the external CRM ID.
$objectId = null;
switch ($entity->field->object_type) {
case Field::OBJECT_ACCOUNT:
$objectId = $activity->account_id;
break;
case Field::OBJECT_CONTACT:
$objectId = $activity->contact_id;
break;
case Field::OBJECT_OPPORTUNITY:
$objectId = $activity->opportunity_id;
break;
case Field::OBJECT_LEAD:
$objectId = $activity->lead_id;
break;
case Field::OBJECT_TASK:
case Field::OBJECT_EVENT:
$objectId = $activity->id;
break;
}
if ($objectId) {
/** @var FieldData $data */
$data = $activity->data()->create([
'crm_layout_entity_id' => $entity->id,
'crm_field_id' => $entity->crm_field_id,
'object_type' => $entity->field->object_type,
'object_id' => $objectId,
'value' => $value,
]);
// Never send read-only field data to the CRM.
if ($entity->read_only === false && $entity->is_visible) {
$existingValue = $existingData
->where('crm_layout_entity_id', $entity->id)
->where('crm_field_id', $entity->crm_field_id)
->where('object_type', $entity->field->object_type)
->where('object_id', $objectId)
->first();
// If the field was actually changed, we need to reflect this in the CRM too.
if ($existingValue === null || $existingValue->value !== $value) {
$updatedData[] = $data->id;
}
}
}
}
}
}
return $updatedData;
}
/**
* Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.
*
* @param ServiceInterface $crmService
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array
{
$fieldData = [];
foreach ($entities as $entityId => $value) {
// Only bother with fields that have a value.
if ($value) {
// Extract the entity from the UUID. Check the field is valid and part of the follow-up section.
$entity = $layout->entities()
->uuid($entityId, false)
->whereHas('parent', function ($query) {
$query->where('label', 'follow-up');
})
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->first();
if ($entity) {
// Convert raw data into values that the CRM can consume.
$value = $crmService->normalizeValue($entity->field->type, $value);
// Add the field and value to the payload.
$fieldData += [
$entity->field->crm_provider_id => $value,
];
}
}
}
return $fieldData;
}
/**
* @param Activity $activity
*/
private function validateSummary(Activity $activity): void
{
$team = $activity->user->team;
$crmProvider = $team->crm->provider;
$attributes = [];
$rules = [
'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,
'title' => 'string|max:250',
'prospects' => 'required|array',
'opportunity_id' => new CrmReference($crmProvider),
'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',
'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator
'summary' => 'max:50000',
'nId' => 'exists:notifications,id',
'crm_id' => new CrmReference($crmProvider),
'entities' => 'array',
'is_internal' => 'boolean',
];
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));
// Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.
$entities = $layout->entities()
->where('read_only', 0)
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->whereHas('parent', function ($query) use ($activity) {
if ($activity->isLoggable() === false) {
$query->where('label', '<>', 'follow-up');
}
});
$isInternal = $this->request->input('is_internal', false);
foreach ($entities->get() as $entity) {
$rules += $this->buildFieldValidator($entity, $isInternal);
$attributes += $this->buildFieldMessage($entity);
}
$this->request->validate($rules, [], $attributes);
}
private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array
{
return [
'entities.' . $entity->id_string => $entity->getValidator($isInternal),
];
}
/**
* @param LayoutEntity $entity
*
* @return array
*/
private function buildFieldMessage(LayoutEntity $entity): array
{
$label = $entity->label;
if ($label === null) {
$label = $entity->field->label;
}
return [
'entities.' . $entity->id_string => $label,
];
}
public function search(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->debugLog(
$user,
'User extracted from request',
['user' => $user->getId(), 'tz' => $user->getTimezone()]
);
$searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());
$this->debugLog(
$user,
'ActivitySearch criteria built',
['searchCriteria' => $searchCriteria]
);
$filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);
$this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);
$this->validateSearch($request, $filterSet);
$this->debugLog($user, 'Request validated');
$searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);
/** @var Collection<Activity> $activities */
$activities = $searchResponse['results'];
$this->debugLog($user, 'Activities ES response extracted');
$hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(
$user->getTeamId(),
TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),
);
if ($hideInternalMeetingsSetting?->getValue() === '1') {
$activities = $activities->filter(function (Activity $activity) {
if ($activity->is_internal && empty($activity->actual_start_time)) {
return false;
}
return true;
});
}
$this->debugLog($user, 'Internal meetings (?!) filtered');
$this->response->getManager()
->parseIncludes([
'category',
'organizer.group',
'prospect',
'stage',
'opportunity',
'stats',
'scorecards',
'masterTrack',
'activeParticipants',
'notification',
])
->setSerializer(new JsonSerializer());
$transformerExcludes = $this->request->input('exclude');
if ($transformerExcludes) {
$this->response->getManager()->parseExcludes($transformerExcludes);
}
$this->debugLog($user, 'Response Manager (?!) applied');
$transformer = new ActivityTransformer();
$transformer->setConsumer($user);
$this->debugLog($user, 'Activity Transformer added');
$resource = new \League\Fractal\Resource\Collection($activities, $transformer);
$page = $searchCriteria->getPageNumber();
$this->debugLog($user, 'Search criteria page number called', ['page' => $page]);
$histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');
$this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);
return $this->response->withArray([
'pagination' => [
'total' => $searchResponse['totalHits'],
'current' => $page,
'prev' => max($page - 1, 1),
'next' => $page + 1,
],
'results' => $this->response->getManager()->createData($resource)->toArray(),
'histogram' => $histogram,
]);
}
private function debugLog(User $user, string $logMessage, ?array $context = []): void
{
// Debug for Learning People Only
if ($user->getTeamId() !== 260) {
return;
}
Log::notice(
sprintf('[activity-search-controller] %s', $logMessage),
$context
);
}
/** @throws ValidationException */
private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void
{
$rules = [
'exclude' => 'array',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
];
if ($prefix !== null && mb_strpos($prefix, '.') !== false) {
$rules[rtrim($prefix, '.')] = sprintf(
'required|array|max:%d',
$filterSet->count()
);
}
$validationRules = $filterSet->getValidationRules($prefix)
->merge($rules)
->all();
$request->validate($validationRules);
}
public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$search = $this->updateOrCreateActivitySearch($request);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function updateActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('update', $search);
$this->updateOrCreateActivitySearch($request, $search);
return $this->response->withOk();
}
private function storeNamedSearchFilters(
Collection $request,
Search $search,
FilterDefinitionCollection $filterSet,
?string $prefix = null,
): self {
$arrayTypeProperties = $filterSet
->getPropertyTypes([
FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,
])
->all();
$supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);
foreach ($supportedRequestProperties as $requestPropertyName) {
if (! array_has($request, $requestPropertyName)) {
continue;
}
/** @var string|string[] $propertyValue */
$propertyValue = array_get($request, $requestPropertyName);
$propertyName = $prefix === null
? $requestPropertyName
: mb_substr($requestPropertyName, mb_strlen($prefix));
$isArrayType = array_has($arrayTypeProperties, $propertyName);
if (! $isArrayType) {
/** @var string $requestPropertyValue */
$search->filters()->updateOrCreate(
[
'filter' => $propertyName,
],
[
'value' => $propertyValue,
]
);
continue;
}
/** @var string[] $requestPropertyValue */
/** @var SearchFilter[]|Collection $existingFilterValues */
$existingFilterValuesKeyed = $search->filters()
->where('filter', $propertyName)
->get()
->keyBy('id');
// Iterate over values provided as request parameters
foreach ($propertyValue as $value) {
/** @var SearchFilter|null $valueFilter */
$valueFilter = $search->filters()
->where(
[
'filter' => $propertyName,
'value' => $value,
]
)
->first();
if ($valueFilter !== null) {
// Remove filter value pair from list to be deleted
$existingFilterValuesKeyed->forget($valueFilter->id);
} else {
// Add new filter/value pair
$search->filters()->updateOrCreate([
'filter' => $propertyName,
'value' => $value,
]);
}
}
// Delete filter value pairs for this filter that no longer exist in request parameters
foreach ($existingFilterValuesKeyed as $existingFilter) {
$existingFilter->delete();
}
}
/** @var Collection<int, SearchFilter> $filtersKeyed */
$filtersKeyed = $search->filters()->get()->keyBy('filter');
// wipe removed filters from this search
foreach ($filtersKeyed as $filterName => $filter) {
if (array_has($request, $prefix . $filterName)) {
continue;
}
// Remove all filter values for this filter
$search->filters()->where('filter', $filterName)->delete();
}
return $this;
}
/**
* @throws AuthorizationException
*/
public function fetchActivitySearch(
Search $search,
Request $request,
SearchTransformer $searchTransformer,
): JsonResponse {
$this->authorize('view', $search);
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withCollection(
$user->searches()->get(),
$searchTransformer
->withConsumer($user)
);
}
/**
* Deletes a saved search
*
* @param Request $request
* @param Search $search
*
* @throws Exception
*
* @return JsonResponse
*/
public function deleteActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('delete', $search);
// Orphan any AutomatedReports that use this search
$search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);
// Delete filters and the search itself
$search->filters()->delete();
$search->delete();
return $this->response->withOk();
}
public function live(Request $request, ElasticActivityRepository $repository): JsonResponse
{
$user = $this->getUserFromRequest($request);
$this->request->validate([
'sort_direction' => 'in:asc,desc',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
]);
$activities = $repository->getLiveCoachingEligibleActivities(
user: $user,
lookBackMinutes: self::LOOK_BACK,
limit: (int) $this->request->input('limit', 25),
page: (int) $this->request->input('page', 1),
sortBy: ['actual_start_time', 'scheduled_start_time'],
sortDirection: (string) $this->request->input('sort_direction', 'asc'),
);
$this->response
->getManager()
->parseIncludes(['organizer.group', 'prospect'])
->setSerializer(new JsonSerializer());
return $this->response->withCollection($activities, new ActivityTransformer());
}
/**
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function show(Activity $activity, ActivityService $activityService): JsonResponse
{
$this->authorize('show', $activity);
$user = $activity->getUser();
$team = $user->getTeam();
// Sync the opportunity with the latest data if possible.
if ($activity->opportunity_id) {
try {
$crmService = $this->providerRegistry->get($team->crm->provider);
if (! $user->isCrmRequired()) {
$crmService->setUser($team->getOwner());
} else {
$crmService->setUser($user);
}
$crmService->syncOpportunity($activity->opportunity->crm_provider_id);
} catch (Exception $exception) {
// Move on.
}
}
$activityData = $activityService->getActivityData($this->request->user(), $activity);
return response()->json($activityData);
}
public function createRecording(Activity $activity)
{
$this->authorize('record', $activity);
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Tell Twilio to start recording this activity.
if ($activity->recording_state === Activity::RECORDING_OFF) {
$job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withCreated();
}
return $this->response->errorGone('Activity is already recording.');
}
public function updateRecording(Request $request, Activity $activity)
{
$this->authorize('record', $activity);
$request->validate([
'preference' => 'boolean',
'state' => [
'string',
Rule::in([
Activity::RECORDING_IN_PROGRESS,
Activity::RECORDING_PAUSED,
]),
],
]);
if ($request->has('state')) {
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Toggle the recording state between paused and resumed.
if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {
$job = (new ToggleRecording($activity, $request->input('state')))
->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Recording is not toggleable.');
}
if ($request->has('preference')) {
$activity->update([
'recording_preference' => $request->input('preference') ? 1 : 0,
]);
return $this->response->withOk();
}
return $this->response->errorWrongArgs('Something went wrong');
}
public function stopRecording(Activity $activity)
{
$this->authorize('stopRecord', $activity);
// Tell Twilio to stop recording this activity.
if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {
$job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Activity is not recording.');
}
/**
* Add activity to this user's favorites playlist
*
* @throws AuthorizationException
*/
public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse
{
$this->authorize('favorite', $activity);
$user = $this->getUserFromRequest($this->request);
$favorite = $activity->wasFavoritedBy($user);
$name = $activity->activity_title ?? '';
// It needs to check at least one record.
if (! $favorite) {
$favoritePlaylist = $user->favoritePlaylist();
$playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(
$activity,
$user,
$favoritePlaylist
);
if ($playlistActivity !== null) {
$playlistActivity->update(
// Just update, don't sort.
['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],
);
} else {
$playlistActivity = $activity->playlistActivities()->create([
'playlist_id' => $favoritePlaylist->getId(),
'user_id' => $user->getId(),
'start_time' => 0,
'name' => mb_strimwidth($name, 0, 100),
]);
// Sort it on top.
$playlistActivity->update(
[
'sort' => $playlistActivityRepository->calculateNewSortOrder(
null,
$playlistActivity,
),
],
);
}
$playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);
return new JsonResponse([], JsonResponse::HTTP_CREATED);
}
return new JsonResponse(
[
'error' => [
'code' => AbstractResponse::CODE_CONFLICT,
'http_code' => JsonResponse::HTTP_CONFLICT,
'message' => 'Resource Already Exists',
],
],
JsonResponse::HTTP_CONFLICT,
);
}
/**
* Remove activity from this user's favorites playlist
*
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function unfavorite(Activity $activity)
{
$user = $t...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
32848
|
1255
|
31
|
2026-05-13T09:39:45.598611+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665185598_m2.jpg...
|
PhpStorm
|
faVsco.js – ActivityController.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use Carbon\Carbon;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\In;
use Illuminate\Validation\ValidationException;
use InvalidArgumentException;
use Jiminny\Component\ActivityAnalytics;
use Jiminny\Component\ActivitySearch;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Queue\Constants;
use Jiminny\Contracts\ES\Events\UpdateSingleEntity;
use Jiminny\Contracts\ES\UpdateTargetEnum;
use Jiminny\Contracts\Nudge\NudgeFactoryInterface;
use Jiminny\Contracts\Playlist\PlaylistTrackFactoryInterface;
use Jiminny\Contracts\Repositories\PlaylistActivityRepository;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Enums\TeamSetting;
use Jiminny\Events\Activities\AiAutomation\ActivityProspectAdded;
use Jiminny\Events\Activities\Coaching\Coached;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Controllers\CommentContextInterface;
use Jiminny\Http\Responses\Api\AbstractResponse;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\ActivityCommentTransformer;
use Jiminny\Http\Transformers\ActivityTopicTriggerTransformer;
use Jiminny\Http\Transformers\ActivityTransformer;
use Jiminny\Http\Transformers\AvailabilityNotificationTransformer;
use Jiminny\Http\Transformers\CoachingFeedbackTransformer;
use Jiminny\Http\Transformers\CoachingSectionsTransformer;
use Jiminny\Http\Transformers\SearchTransformer;
use Jiminny\Http\Transformers\StatsTransformer;
use Jiminny\Jobs\Crm\SaveActivity;
use Jiminny\Jobs\Crm\UpdateStage;
use Jiminny\Jobs\Telephony\StartRecording;
use Jiminny\Jobs\Telephony\StopRecording;
use Jiminny\Jobs\Telephony\ToggleRecording;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\CoachingFeedback;
use Jiminny\Models\CoachingSection;
use Jiminny\Models\CoachingSectionCriterion;
use Jiminny\Models\CoachingSectionFeedback;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\LanguageDialect;
use Jiminny\Models\Lead;
use Jiminny\Models\Nudge;
use Jiminny\Models\PlaybookCategory;
use Jiminny\Models\Playlist;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\Track;
use Jiminny\Models\User;
use Jiminny\Repositories\CoachingFeedbackRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Rules\CrmReference;
use Jiminny\Rules\MultidimensionalArrayMaxCharRule;
use Jiminny\Services\ActivityService;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Services\PlaybackService;
use Jiminny\Services\UserService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
use Ramsey\Uuid\Uuid;
use Sentry;
use Symfony\Component\HttpFoundation;
final class ActivityController extends Controller implements CommentContextInterface
{
// Number of minutes to look back on activities. i.e. a timeout on activity duration.
private const int LOOK_BACK = 180;
public function __construct(
private ProviderRegistry $providerRegistry,
private ActivityService $activityService,
Response $response,
private UserService $userService,
private ActivitySearch\Service\ActivitySearch $activitySearch,
private NudgeFactoryInterface $nudgeFactory,
private ActivityCommentService $activityCommentService,
private LoggerInterface $logger,
private readonly CoachingFeedbackRepository $coachingFeedbackRepository,
private readonly TeamRepository $teamRepository,
) {
parent::__construct($response);
}
public static function getCommentImplementation(): string
{
return Comment::class;
}
public function delete()
{
$this->request->validate([
'*' => 'uuid:activities',
]);
$deletedIds = [];
foreach ($this->request->all() as $activityId) {
$activity = Activity::idOrUuId($activityId);
try {
if ($this->authorize('delete', $activity)) {
$activity->delete();
$deletedIds[] = $activityId;
\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);
}
} catch (AuthorizationException $authorizationException) {
// They didn't have permission.
}
}
return $this->response->withArray($deletedIds);
}
public function update(Request $request, Activity $activity)
{
$this->authorize('updateMetadata', $activity);
$request->validate([
'title' => 'string|max:250',
'category_id' => 'uuid:playbook_categories',
'language' => [
new In(
LanguageDialect::query()
->with('language')
->cursor()
->map(static function (LanguageDialect $languageDialect): string {
return $languageDialect->getLanguageLocale();
})
->all()
),
],
]);
if ($request->has('title')) {
$activity->title = $request->input('title');
}
if ($request->has('category_id')) {
$category = PlaybookCategory::uuid($request->input('category_id'));
if ($category->playbook->team_id !== $request->user()->team_id) {
return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
if ($request->has('language')) {
if (! $activity->isInProgress()) {
return $this->response->withError(
'Activity language can only be set while the meeting is in progress.',
400
);
}
$activity->setLanguageCode($request->input('language'));
}
$activity->save();
return $this->response->withOk();
}
// XXX: This should be merged with the update method.
/**
* @param Activity $activity
*
* @throws AuthorizationException
* @throws SocialAccountTokenInvalidException
*
* @return mixed
*/
public function summarize(Activity $activity): mixed
{
$this->logger->info('[Log Activity] Summarizing activity ', [
'activityId' => $activity->getUuid(),
'payload' => $this->request->all(),
]);
$this->authorize('update', $activity);
$this->logger->info('[Log Activity] Validating summary');
// Validate the payload.
$this->validateSummary($activity);
// All objects must belong to this team.
/** @var User $user */
$user = $this->request->user();
$team = $user->getTeam();
$crmService = $this->providerRegistry->get($team->crm->provider);
try {
$crmUser = $user;
if ($user->isCrmRequired() === false) {
$crmUser = $team->owner;
}
$crmService->setUser($crmUser);
} catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());
}
$rawEntities = $this->request->input('entities');
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid(
$this->request->input('layout_id')
);
// Delay execution of CRM jobs to avoid locking issues.
$jobDelay = 0;
// If we have arrived from a notification, mark it as read.
$notificationId = $this->request->input('nId');
if ($notificationId) {
$notification = $user->unreadNotifications->where('id', $notificationId)->first();
if ($notification) {
$notification->markAsRead();
}
}
$title = $this->request->input('title');
$prospects = $this->request->input('prospects');
$opportunityId = $this->request->input('opportunity_id');
$stageId = $this->request->input('stage_id');
$categoryId = $this->request->input('category_id');
$summary = $this->request->input('summary');
$crmProviderId = $this->request->input('crm_id');
$isInternal = $this->request->input('is_internal') ?? false;
$lead = null;
$category = null;
$account = null;
$contact = null;
$opportunity = null;
$stage = null;
$callStage = null;
foreach ($prospects as $prospectData) {
$objectId = $prospectData['id'];
if ($objectId === null) {
continue;
}
$objectType = $prospectData['type'];
$this->logger->info('debug', ['prospect_data' => $prospectData]);
try {
if ($objectType === null) {
$this->logger->info('no object type');
if ($crmService instanceof SupportsObjectTypeParseInterface) {
$objectType = $crmService->parseObjectType($objectId);
}
}
switch ($objectType) {
case 'lead':
$this->logger->info('Processing lead');
/** @var Lead|null $lead */
$lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();
// Lead does not exist locally, import it.
if ($lead === null) {
$this->logger->info('Lead does not exist locally');
/** @var Lead $lead */
$lead = $crmService->syncLead($objectId);
}
$this->logger->info('Lead found', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
if ($stageId === null) {
$this->logger->info('Stage ID is null');
// If it was not provided, just assume it is the current stage.
$callStage = $lead->stage;
break;
}
$this->logger->info('Looking for stage');
// Determine if they have changed the stage.
/** @var Stage $stage */
$stage = $team->crm->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_LEAD)
->firstOrFail();
$this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);
if ($lead->stage_id && $lead->stage_id !== $stage->id) {
$this->logger->info('Stage has changed');
// Storage current stage on activity.
$callStage = $lead->stage;
// The stage has changed, update in remote CRM.
dispatch(new UpdateStage($activity, $lead, $callStage, $stage));
$this->logger->info(
sprintf(
'[%s] User changing lead stage from %s to %s',
$crmService->getDisplayName(),
$callStage->getName(),
$stage->getName()
),
[
'user' => $user->getUuid(),
'lead' => $lead->getUuid(),
]
);
} else {
$this->logger->info('Stage has not changed');
// Stage remains as current.
$callStage = $stage;
}
break;
case 'account':
$this->logger->info('Processing account');
// If the object is not a lead, it should be an account.
$account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();
// Account does not exist locally, import it.
if ($account === null) {
$this->logger->info('Account does not exist locally');
$account = $crmService->syncAccount($objectId);
}
$this->logger->info('Account found', ['accountId' => $account->id]);
break;
case 'contact':
$this->logger->info('processing contact');
$contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$this->logger->info('contact does not exist locally');
$contact = $crmService->syncContact($objectId);
}
$this->logger->info('resolving account');
$account = $this->resolveAccount($team, $contact, $crmService, $prospects);
break;
}
// If they have specified an opportunity, retrieve this with stage.
if ($opportunityId) {
$this->logger->info('opportunity id is set');
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if ($opportunity === null) {
$this->logger->info('opportunity does not exist locally');
$opportunity = $crmService->syncOpportunity($opportunityId);
}
if ($stageId === null) {
$this->logger->info('stage id is null');
// If it was not provided, just assume it is the current stage.
$callStage = $opportunity->stage ?? null;
} else {
$this->logger->info('looking for stage');
/** @var ?Stage $opportunityStage */
$opportunityStage = $team->crm
->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
// There is a chance we still cannot import this opportunity.
if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {
$this->logger->info('opportunity stage has changed');
// Storage current stage on activity.
$callStage = $opportunity->stage;
dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));
$this->logger->info(
sprintf(
'[%s] User changing opportunity stage from %s to %s',
$crmService->getDisplayName(),
$callStage->name,
$opportunityStage->name
),
[
'userId' => $user->id_string,
'opportunityId' => $opportunity->id_string,
]
);
} else {
$this->logger->info('opportunity stage has not changed');
// Stage remains as current.
$callStage = $opportunityStage;
}
}
}
if ($crmProviderId) {
// Cast $crmProviderId to string otherwise it won't use database index for some records
$linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();
// Check if this activity has already been assigned to a different activity.
if ($linkedActivity && $linkedActivity->id !== $activity->id) {
throw new InvalidArgumentException(
'Sorry, the linked task has already been logged under a different call. '
. 'Please choose another linked task.'
);
}
}
} catch (InvalidArgumentException $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($exception->getMessage());
} catch (Exception $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorInternalError(
'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'
);
}
}
if ($categoryId) {
$category = PlaybookCategory::uuid($categoryId);
if ($category->playbook->team_id !== $team->id) {
throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
$this->logger->info('Prospect data', [
'lead_id' => $lead?->getId(),
'account_id' => $account?->getId(),
'contact_id' => $contact?->getId(),
'opportunity_id' => $opportunity?->getId(),
'stage_id' => $stage?->getId(),
]);
if ($title) {
$activity->title = $title;
}
if ($summary) {
$activity->summary = $summary;
}
if ($crmProviderId) {
$activity->crm_provider_id = $crmProviderId;
}
if ($callStage) {
$this->logger->info('Setting stage id', ['stageId' => $callStage->id]);
$activity->stage_id = $callStage->id;
}
if ($lead) {
$this->logger->info('Setting lead id', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
// If we are changed from an account > lead, unset the account data.
$this->logger->info('Unsetting account id, opportunity id, contact id, value');
$activity->account_id = null;
$activity->opportunity_id = null;
$activity->contact_id = null;
$activity->value = null;
}
if ($account) {
$this->logger->info('Setting account id', ['accountId' => $account->id]);
$activity->account_id = $account->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('unsetting lead id');
$activity->lead_id = null;
// Unset the contact if switching different accounts. Will be set up below if still applicable.
if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {
$this->logger->info('Unsetting contact id');
$activity->contact_id = null;
}
}
if ($opportunity) {
$this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);
$this->logger->info('unsetting lead id');
$activity->opportunity_id = $opportunity->id;
$activity->value = $opportunity->value;
// If we are changed from an lead > account, unset the lead data.
$activity->lead_id = null;
}
if ($contact) {
$this->logger->info('setting contact id', ['contactId' => $contact->id]);
$activity->contact_id = $contact->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('Unsetting lead id');
$activity->lead_id = null;
}
$activity->is_internal = $isInternal;
$activity->save();
$activity->refresh();
$this->logger->notice('Activity saved', [
'activity_id' => $activity->getId(),
'lead_id' => $activity->lead_id,
'account_id' => $activity->account_id,
'contact_id' => $activity->contact_id,
'opportunity_id' => $activity->opportunity_id,
'stage_id' => $activity->stage_id,
'crm_provider_id' => $activity->getCrmProviderId(),
]);
// Store entities as field data on the activity.
$updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);
if ($activity->isLoggable()) {
// Follow-up Task or Event data.
$followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);
$this->logger->info('CRM LOG manual log triggered', [
'activityId' => $activity->getUuid(),
'followupData' => $followupData,
'userId' => $user->getUuid(),
]);
// Store data in the CRM.
// ++add check for crm_required
$job = new SaveActivity($activity, $followupData);
if ($updatedData) {
$job->delay(Carbon::now()->addMinutes($jobDelay));
}
dispatch($job);
// Manually dispatch log for Opportunity or Prospect added
if ($activity->hasOpportunity() || $activity->hasProspect()) {
event(new ActivityProspectAdded(
activity: $activity,
eventSource: 'manually-log-crm-data'
));
}
}
return $this->response->withOk();
}
/**
* Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.
*
* @param ServiceInterface $service
* @param Activity $activity
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array
{
$updatedData = [];
$existingData = $activity->data()->get();
// We need to delete any existing data to overwrite with latest values.
$activity->data()->delete();
$layoutEntities = $layout->entities()
->with('field', 'parent')
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->get();
/** @var LayoutEntity $entity */
foreach ($layoutEntities as $entity) {
// If the user has provided a value for this entity
if (array_key_exists($entity->id_string, $entities)) {
$value = $entities[$entity->id_string];
// Convert raw data into values that the CRM can consume.
if ($value) {
$value = $service->normalizeValue($entity->field->type, $value);
}
// Check the field is part of the activity-summary section.
if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {
// This is the internal database ID, not the external CRM ID.
$objectId = null;
switch ($entity->field->object_type) {
case Field::OBJECT_ACCOUNT:
$objectId = $activity->account_id;
break;
case Field::OBJECT_CONTACT:
$objectId = $activity->contact_id;
break;
case Field::OBJECT_OPPORTUNITY:
$objectId = $activity->opportunity_id;
break;
case Field::OBJECT_LEAD:
$objectId = $activity->lead_id;
break;
case Field::OBJECT_TASK:
case Field::OBJECT_EVENT:
$objectId = $activity->id;
break;
}
if ($objectId) {
/** @var FieldData $data */
$data = $activity->data()->create([
'crm_layout_entity_id' => $entity->id,
'crm_field_id' => $entity->crm_field_id,
'object_type' => $entity->field->object_type,
'object_id' => $objectId,
'value' => $value,
]);
// Never send read-only field data to the CRM.
if ($entity->read_only === false && $entity->is_visible) {
$existingValue = $existingData
->where('crm_layout_entity_id', $entity->id)
->where('crm_field_id', $entity->crm_field_id)
->where('object_type', $entity->field->object_type)
->where('object_id', $objectId)
->first();
// If the field was actually changed, we need to reflect this in the CRM too.
if ($existingValue === null || $existingValue->value !== $value) {
$updatedData[] = $data->id;
}
}
}
}
}
}
return $updatedData;
}
/**
* Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.
*
* @param ServiceInterface $crmService
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array
{
$fieldData = [];
foreach ($entities as $entityId => $value) {
// Only bother with fields that have a value.
if ($value) {
// Extract the entity from the UUID. Check the field is valid and part of the follow-up section.
$entity = $layout->entities()
->uuid($entityId, false)
->whereHas('parent', function ($query) {
$query->where('label', 'follow-up');
})
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->first();
if ($entity) {
// Convert raw data into values that the CRM can consume.
$value = $crmService->normalizeValue($entity->field->type, $value);
// Add the field and value to the payload.
$fieldData += [
$entity->field->crm_provider_id => $value,
];
}
}
}
return $fieldData;
}
/**
* @param Activity $activity
*/
private function validateSummary(Activity $activity): void
{
$team = $activity->user->team;
$crmProvider = $team->crm->provider;
$attributes = [];
$rules = [
'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,
'title' => 'string|max:250',
'prospects' => 'required|array',
'opportunity_id' => new CrmReference($crmProvider),
'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',
'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator
'summary' => 'max:50000',
'nId' => 'exists:notifications,id',
'crm_id' => new CrmReference($crmProvider),
'entities' => 'array',
'is_internal' => 'boolean',
];
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));
// Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.
$entities = $layout->entities()
->where('read_only', 0)
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->whereHas('parent', function ($query) use ($activity) {
if ($activity->isLoggable() === false) {
$query->where('label', '<>', 'follow-up');
}
});
$isInternal = $this->request->input('is_internal', false);
foreach ($entities->get() as $entity) {
$rules += $this->buildFieldValidator($entity, $isInternal);
$attributes += $this->buildFieldMessage($entity);
}
$this->request->validate($rules, [], $attributes);
}
private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array
{
return [
'entities.' . $entity->id_string => $entity->getValidator($isInternal),
];
}
/**
* @param LayoutEntity $entity
*
* @return array
*/
private function buildFieldMessage(LayoutEntity $entity): array
{
$label = $entity->label;
if ($label === null) {
$label = $entity->field->label;
}
return [
'entities.' . $entity->id_string => $label,
];
}
public function search(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->debugLog(
$user,
'User extracted from request',
['user' => $user->getId(), 'tz' => $user->getTimezone()]
);
$searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());
$this->debugLog(
$user,
'ActivitySearch criteria built',
['searchCriteria' => $searchCriteria]
);
$filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);
$this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);
$this->validateSearch($request, $filterSet);
$this->debugLog($user, 'Request validated');
$searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);
/** @var Collection<Activity> $activities */
$activities = $searchResponse['results'];
$this->debugLog($user, 'Activities ES response extracted');
$hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(
$user->getTeamId(),
TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),
);
if ($hideInternalMeetingsSetting?->getValue() === '1') {
$activities = $activities->filter(function (Activity $activity) {
if ($activity->is_internal && empty($activity->actual_start_time)) {
return false;
}
return true;
});
}
$this->debugLog($user, 'Internal meetings (?!) filtered');
$this->response->getManager()
->parseIncludes([
'category',
'organizer.group',
'prospect',
'stage',
'opportunity',
'stats',
'scorecards',
'masterTrack',
'activeParticipants',
'notification',
])
->setSerializer(new JsonSerializer());
$transformerExcludes = $this->request->input('exclude');
if ($transformerExcludes) {
$this->response->getManager()->parseExcludes($transformerExcludes);
}
$this->debugLog($user, 'Response Manager (?!) applied');
$transformer = new ActivityTransformer();
$transformer->setConsumer($user);
$this->debugLog($user, 'Activity Transformer added');
$resource = new \League\Fractal\Resource\Collection($activities, $transformer);
$page = $searchCriteria->getPageNumber();
$this->debugLog($user, 'Search criteria page number called', ['page' => $page]);
$histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');
$this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);
return $this->response->withArray([
'pagination' => [
'total' => $searchResponse['totalHits'],
'current' => $page,
'prev' => max($page - 1, 1),
'next' => $page + 1,
],
'results' => $this->response->getManager()->createData($resource)->toArray(),
'histogram' => $histogram,
]);
}
private function debugLog(User $user, string $logMessage, ?array $context = []): void
{
// Debug for Learning People Only
if ($user->getTeamId() !== 260) {
return;
}
Log::notice(
sprintf('[activity-search-controller] %s', $logMessage),
$context
);
}
/** @throws ValidationException */
private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void
{
$rules = [
'exclude' => 'array',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
];
if ($prefix !== null && mb_strpos($prefix, '.') !== false) {
$rules[rtrim($prefix, '.')] = sprintf(
'required|array|max:%d',
$filterSet->count()
);
}
$validationRules = $filterSet->getValidationRules($prefix)
->merge($rules)
->all();
$request->validate($validationRules);
}
public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$search = $this->updateOrCreateActivitySearch($request);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function updateActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('update', $search);
$this->updateOrCreateActivitySearch($request, $search);
return $this->response->withOk();
}
private function storeNamedSearchFilters(
Collection $request,
Search $search,
FilterDefinitionCollection $filterSet,
?string $prefix = null,
): self {
$arrayTypeProperties = $filterSet
->getPropertyTypes([
FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,
])
->all();
$supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);
foreach ($supportedRequestProperties as $requestPropertyName) {
if (! array_has($request, $requestPropertyName)) {
continue;
}
/** @var string|string[] $propertyValue */
$propertyValue = array_get($request, $requestPropertyName);
$propertyName = $prefix === null
? $requestPropertyName
: mb_substr($requestPropertyName, mb_strlen($prefix));
$isArrayType = array_has($arrayTypeProperties, $propertyName);
if (! $isArrayType) {
/** @var string $requestPropertyValue */
$search->filters()->updateOrCreate(
[
'filter' => $propertyName,
],
[
'value' => $propertyValue,
]
);
continue;
}
/** @var string[] $requestPropertyValue */
/** @var SearchFilter[]|Collection $existingFilterValues */
$existingFilterValuesKeyed = $search->filters()
->where('filter', $propertyName)
->get()
->keyBy('id');
// Iterate over values provided as request parameters
foreach ($propertyValue as $value) {
/** @var SearchFilter|null $valueFilter */
$valueFilter = $search->filters()
->where(
[
'filter' => $propertyName,
'value' => $value,
]
)
->first();
if ($valueFilter !== null) {
// Remove filter value pair from list to be deleted
$existingFilterValuesKeyed->forget($valueFilter->id);
} else {
// Add new filter/value pair
$search->filters()->updateOrCreate([
'filter' => $propertyName,
'value' => $value,
]);
}
}
// Delete filter value pairs for this filter that no longer exist in request parameters
foreach ($existingFilterValuesKeyed as $existingFilter) {
$existingFilter->delete();
}
}
/** @var Collection<int, SearchFilter> $filtersKeyed */
$filtersKeyed = $search->filters()->get()->keyBy('filter');
// wipe removed filters from this search
foreach ($filtersKeyed as $filterName => $filter) {
if (array_has($request, $prefix . $filterName)) {
continue;
}
// Remove all filter values for this filter
$search->filters()->where('filter', $filterName)->delete();
}
return $this;
}
/**
* @throws AuthorizationException
*/
public function fetchActivitySearch(
Search $search,
Request $request,
SearchTransformer $searchTransformer,
): JsonResponse {
$this->authorize('view', $search);
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withCollection(
$user->searches()->get(),
$searchTransformer
->withConsumer($user)
);
}
/**
* Deletes a saved search
*
* @param Request $request
* @param Search $search
*
* @throws Exception
*
* @return JsonResponse
*/
public function deleteActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('delete', $search);
// Orphan any AutomatedReports that use this search
$search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);
// Delete filters and the search itself
$search->filters()->delete();
$search->delete();
return $this->response->withOk();
}
public function live(Request $request, ElasticActivityRepository $repository): JsonResponse
{
$user = $this->getUserFromRequest($request);
$this->request->validate([
'sort_direction' => 'in:asc,desc',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
]);
$activities = $repository->getLiveCoachingEligibleActivities(
user: $user,
lookBackMinutes: self::LOOK_BACK,
limit: (int) $this->request->input('limit', 25),
page: (int) $this->request->input('page', 1),
sortBy: ['actual_start_time', 'scheduled_start_time'],
sortDirection: (string) $this->request->input('sort_direction', 'asc'),
);
$this->response
->getManager()
->parseIncludes(['organizer.group', 'prospect'])
->setSerializer(new JsonSerializer());
return $this->response->withCollection($activities, new ActivityTransformer());
}
/**
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function show(Activity $activity, ActivityService $activityService): JsonResponse
{
$this->authorize('show', $activity);
$user = $activity->getUser();
$team = $user->getTeam();
// Sync the opportunity with the latest data if possible.
if ($activity->opportunity_id) {
try {
$crmService = $this->providerRegistry->get($team->crm->provider);
if (! $user->isCrmRequired()) {
$crmService->setUser($team->getOwner());
} else {
$crmService->setUser($user);
}
$crmService->syncOpportunity($activity->opportunity->crm_provider_id);
} catch (Exception $exception) {
// Move on.
}
}
$activityData = $activityService->getActivityData($this->request->user(), $activity);
return response()->json($activityData);
}
public function createRecording(Activity $activity)
{
$this->authorize('record', $activity);
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Tell Twilio to start recording this activity.
if ($activity->recording_state === Activity::RECORDING_OFF) {
$job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withCreated();
}
return $this->response->errorGone('Activity is already recording.');
}
public function updateRecording(Request $request, Activity $activity)
{
$this->authorize('record', $activity);
$request->validate([
'preference' => 'boolean',
'state' => [
'string',
Rule::in([
Activity::RECORDING_IN_PROGRESS,
Activity::RECORDING_PAUSED,
]),
],
]);
if ($request->has('state')) {
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Toggle the recording state between paused and resumed.
if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {
$job = (new ToggleRecording($activity, $request->input('state')))
->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Recording is not toggleable.');
}
if ($request->has('preference')) {
$activity->update([
'recording_preference' => $request->input('preference') ? 1 : 0,
]);
return $this->response->withOk();
}
return $this->response->errorWrongArgs('Something went wrong');
}
public function stopRecording(Activity $activity)
{
$this->authorize('stopRecord', $activity);
// Tell Twilio to stop recording this activity.
if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {
$job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Activity is not recording.');
}
/**
* Add activity to this user's favorites playlist
*
* @throws AuthorizationException
*/
public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse
{
$this->authorize('favorite', $activity);
$user = $this->getUserFromRequest($this->request);
$favorite = $activity->wasFavoritedBy($user);
$name = $activity->activity_title ?? '';
// It needs to check at least one record.
if (! $favorite) {
$favoritePlaylist = $user->favoritePlaylist();
$playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(
$activity,
$user,
$favoritePlaylist
);
if ($playlistActivity !== null) {
$playlistActivity->update(
// Just update, don't sort.
['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],
);
} else {
$playlistActivity = $activity->playlistActivities()->create([
'playlist_id' => $favoritePlaylist->getId(),
'user_id' => $user->getId(),
'start_time' => 0,
'name' => mb_strimwidth($name, 0, 100),
]);
// Sort it on top.
$playlistActivity->update(
[
'sort' => $playlistActivityRepository->calculateNewSortOrder(
null,
$playlistActivity,
),
],
);
}
$playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);
return new JsonResponse([], JsonResponse::HTTP_CREATED);
}
return new JsonResponse(
[
'error' => [
'code' => AbstractResponse::CODE_CONFLICT,
'http_code' => JsonResponse::HTTP_CONFLICT,
'message' => 'Resource Already Exists',
],
],
JsonResponse::HTTP_CONFLICT,
);
}
/**
* Remove activity from this user's favorites playlist
*
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function unfavorite(Activity $activity)
{
$user = $t...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.034242023,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Analyzing…","depth":4,"bounds":{"left":0.37200797,"top":0.07581804,"width":0.019946808,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.39361703,"top":0.074221864,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.40093085,"top":0.074221864,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Http\\Controllers\\API;\n\nuse Carbon\\Carbon;\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Exception;\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Validation\\Rule;\nuse Illuminate\\Validation\\Rules\\In;\nuse Illuminate\\Validation\\ValidationException;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ActivityAnalytics;\nuse Jiminny\\Component\\ActivitySearch;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Contracts\\ES\\Events\\UpdateSingleEntity;\nuse Jiminny\\Contracts\\ES\\UpdateTargetEnum;\nuse Jiminny\\Contracts\\Nudge\\NudgeFactoryInterface;\nuse Jiminny\\Contracts\\Playlist\\PlaylistTrackFactoryInterface;\nuse Jiminny\\Contracts\\Repositories\\PlaylistActivityRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Enums\\TeamSetting;\nuse Jiminny\\Events\\Activities\\AiAutomation\\ActivityProspectAdded;\nuse Jiminny\\Events\\Activities\\Coaching\\Coached;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Controllers\\CommentContextInterface;\nuse Jiminny\\Http\\Responses\\Api\\AbstractResponse;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\ActivityCommentTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTopicTriggerTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTransformer;\nuse Jiminny\\Http\\Transformers\\AvailabilityNotificationTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingFeedbackTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingSectionsTransformer;\nuse Jiminny\\Http\\Transformers\\SearchTransformer;\nuse Jiminny\\Http\\Transformers\\StatsTransformer;\nuse Jiminny\\Jobs\\Crm\\SaveActivity;\nuse Jiminny\\Jobs\\Crm\\UpdateStage;\nuse Jiminny\\Jobs\\Telephony\\StartRecording;\nuse Jiminny\\Jobs\\Telephony\\StopRecording;\nuse Jiminny\\Jobs\\Telephony\\ToggleRecording;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\CoachingFeedback;\nuse Jiminny\\Models\\CoachingSection;\nuse Jiminny\\Models\\CoachingSectionCriterion;\nuse Jiminny\\Models\\CoachingSectionFeedback;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\LanguageDialect;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Nudge;\nuse Jiminny\\Models\\PlaybookCategory;\nuse Jiminny\\Models\\Playlist;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\Track;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\CoachingFeedbackRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Rules\\MultidimensionalArrayMaxCharRule;\nuse Jiminny\\Services\\ActivityService;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Services\\PlaybackService;\nuse Jiminny\\Services\\UserService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\nuse Ramsey\\Uuid\\Uuid;\nuse Sentry;\nuse Symfony\\Component\\HttpFoundation;\n\nfinal class ActivityController extends Controller implements CommentContextInterface\n{\n // Number of minutes to look back on activities. i.e. a timeout on activity duration.\n private const int LOOK_BACK = 180;\n\n public function __construct(\n private ProviderRegistry $providerRegistry,\n private ActivityService $activityService,\n Response $response,\n private UserService $userService,\n private ActivitySearch\\Service\\ActivitySearch $activitySearch,\n private NudgeFactoryInterface $nudgeFactory,\n private ActivityCommentService $activityCommentService,\n private LoggerInterface $logger,\n private readonly CoachingFeedbackRepository $coachingFeedbackRepository,\n private readonly TeamRepository $teamRepository,\n ) {\n parent::__construct($response);\n }\n\n public static function getCommentImplementation(): string\n {\n return Comment::class;\n }\n\n public function delete()\n {\n $this->request->validate([\n '*' => 'uuid:activities',\n ]);\n\n $deletedIds = [];\n foreach ($this->request->all() as $activityId) {\n $activity = Activity::idOrUuId($activityId);\n\n try {\n if ($this->authorize('delete', $activity)) {\n $activity->delete();\n $deletedIds[] = $activityId;\n\n \\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n }\n } catch (AuthorizationException $authorizationException) {\n // They didn't have permission.\n }\n }\n\n return $this->response->withArray($deletedIds);\n }\n\n public function update(Request $request, Activity $activity)\n {\n $this->authorize('updateMetadata', $activity);\n\n $request->validate([\n 'title' => 'string|max:250',\n 'category_id' => 'uuid:playbook_categories',\n 'language' => [\n new In(\n LanguageDialect::query()\n ->with('language')\n ->cursor()\n ->map(static function (LanguageDialect $languageDialect): string {\n return $languageDialect->getLanguageLocale();\n })\n ->all()\n ),\n ],\n ]);\n\n if ($request->has('title')) {\n $activity->title = $request->input('title');\n }\n\n if ($request->has('category_id')) {\n $category = PlaybookCategory::uuid($request->input('category_id'));\n\n if ($category->playbook->team_id !== $request->user()->team_id) {\n return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n if ($request->has('language')) {\n if (! $activity->isInProgress()) {\n return $this->response->withError(\n 'Activity language can only be set while the meeting is in progress.',\n 400\n );\n }\n\n $activity->setLanguageCode($request->input('language'));\n }\n\n $activity->save();\n\n return $this->response->withOk();\n }\n\n // XXX: This should be merged with the update method.\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws SocialAccountTokenInvalidException\n *\n * @return mixed\n */\n public function summarize(Activity $activity): mixed\n {\n $this->logger->info('[Log Activity] Summarizing activity ', [\n 'activityId' => $activity->getUuid(),\n 'payload' => $this->request->all(),\n ]);\n $this->authorize('update', $activity);\n\n $this->logger->info('[Log Activity] Validating summary');\n // Validate the payload.\n $this->validateSummary($activity);\n\n // All objects must belong to this team.\n /** @var User $user */\n $user = $this->request->user();\n $team = $user->getTeam();\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n try {\n $crmUser = $user;\n if ($user->isCrmRequired() === false) {\n $crmUser = $team->owner;\n }\n $crmService->setUser($crmUser);\n } catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());\n }\n\n $rawEntities = $this->request->input('entities');\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid(\n $this->request->input('layout_id')\n );\n\n // Delay execution of CRM jobs to avoid locking issues.\n $jobDelay = 0;\n\n // If we have arrived from a notification, mark it as read.\n $notificationId = $this->request->input('nId');\n if ($notificationId) {\n $notification = $user->unreadNotifications->where('id', $notificationId)->first();\n\n if ($notification) {\n $notification->markAsRead();\n }\n }\n\n $title = $this->request->input('title');\n $prospects = $this->request->input('prospects');\n $opportunityId = $this->request->input('opportunity_id');\n $stageId = $this->request->input('stage_id');\n $categoryId = $this->request->input('category_id');\n $summary = $this->request->input('summary');\n $crmProviderId = $this->request->input('crm_id');\n $isInternal = $this->request->input('is_internal') ?? false;\n\n $lead = null;\n $category = null;\n $account = null;\n $contact = null;\n $opportunity = null;\n $stage = null;\n $callStage = null;\n\n foreach ($prospects as $prospectData) {\n $objectId = $prospectData['id'];\n\n if ($objectId === null) {\n continue;\n }\n\n $objectType = $prospectData['type'];\n $this->logger->info('debug', ['prospect_data' => $prospectData]);\n\n try {\n if ($objectType === null) {\n $this->logger->info('no object type');\n if ($crmService instanceof SupportsObjectTypeParseInterface) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n }\n\n switch ($objectType) {\n case 'lead':\n $this->logger->info('Processing lead');\n /** @var Lead|null $lead */\n $lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();\n\n // Lead does not exist locally, import it.\n if ($lead === null) {\n $this->logger->info('Lead does not exist locally');\n /** @var Lead $lead */\n $lead = $crmService->syncLead($objectId);\n }\n\n $this->logger->info('Lead found', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n if ($stageId === null) {\n $this->logger->info('Stage ID is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $lead->stage;\n\n break;\n }\n\n $this->logger->info('Looking for stage');\n // Determine if they have changed the stage.\n /** @var Stage $stage */\n $stage = $team->crm->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_LEAD)\n ->firstOrFail();\n\n $this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);\n if ($lead->stage_id && $lead->stage_id !== $stage->id) {\n $this->logger->info('Stage has changed');\n // Storage current stage on activity.\n $callStage = $lead->stage;\n\n // The stage has changed, update in remote CRM.\n dispatch(new UpdateStage($activity, $lead, $callStage, $stage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing lead stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->getName(),\n $stage->getName()\n ),\n [\n 'user' => $user->getUuid(),\n 'lead' => $lead->getUuid(),\n ]\n );\n } else {\n $this->logger->info('Stage has not changed');\n // Stage remains as current.\n $callStage = $stage;\n }\n\n break;\n\n case 'account':\n $this->logger->info('Processing account');\n // If the object is not a lead, it should be an account.\n $account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();\n\n // Account does not exist locally, import it.\n if ($account === null) {\n $this->logger->info('Account does not exist locally');\n $account = $crmService->syncAccount($objectId);\n }\n\n $this->logger->info('Account found', ['accountId' => $account->id]);\n\n break;\n case 'contact':\n $this->logger->info('processing contact');\n $contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $this->logger->info('contact does not exist locally');\n $contact = $crmService->syncContact($objectId);\n }\n\n $this->logger->info('resolving account');\n $account = $this->resolveAccount($team, $contact, $crmService, $prospects);\n\n break;\n }\n\n // If they have specified an opportunity, retrieve this with stage.\n if ($opportunityId) {\n $this->logger->info('opportunity id is set');\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if ($opportunity === null) {\n $this->logger->info('opportunity does not exist locally');\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n if ($stageId === null) {\n $this->logger->info('stage id is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $opportunity->stage ?? null;\n } else {\n $this->logger->info('looking for stage');\n /** @var ?Stage $opportunityStage */\n $opportunityStage = $team->crm\n ->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n // There is a chance we still cannot import this opportunity.\n if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {\n $this->logger->info('opportunity stage has changed');\n // Storage current stage on activity.\n $callStage = $opportunity->stage;\n\n dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing opportunity stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->name,\n $opportunityStage->name\n ),\n [\n 'userId' => $user->id_string,\n 'opportunityId' => $opportunity->id_string,\n ]\n );\n } else {\n $this->logger->info('opportunity stage has not changed');\n // Stage remains as current.\n $callStage = $opportunityStage;\n }\n }\n }\n\n if ($crmProviderId) {\n // Cast $crmProviderId to string otherwise it won't use database index for some records\n $linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();\n\n // Check if this activity has already been assigned to a different activity.\n if ($linkedActivity && $linkedActivity->id !== $activity->id) {\n throw new InvalidArgumentException(\n 'Sorry, the linked task has already been logged under a different call. '\n . 'Please choose another linked task.'\n );\n }\n }\n } catch (InvalidArgumentException $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($exception->getMessage());\n } catch (Exception $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorInternalError(\n 'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'\n );\n }\n }\n\n if ($categoryId) {\n $category = PlaybookCategory::uuid($categoryId);\n\n if ($category->playbook->team_id !== $team->id) {\n throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n $this->logger->info('Prospect data', [\n 'lead_id' => $lead?->getId(),\n 'account_id' => $account?->getId(),\n 'contact_id' => $contact?->getId(),\n 'opportunity_id' => $opportunity?->getId(),\n 'stage_id' => $stage?->getId(),\n ]);\n\n if ($title) {\n $activity->title = $title;\n }\n\n if ($summary) {\n $activity->summary = $summary;\n }\n\n if ($crmProviderId) {\n $activity->crm_provider_id = $crmProviderId;\n }\n\n if ($callStage) {\n $this->logger->info('Setting stage id', ['stageId' => $callStage->id]);\n $activity->stage_id = $callStage->id;\n }\n\n if ($lead) {\n $this->logger->info('Setting lead id', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n // If we are changed from an account > lead, unset the account data.\n $this->logger->info('Unsetting account id, opportunity id, contact id, value');\n $activity->account_id = null;\n $activity->opportunity_id = null;\n $activity->contact_id = null;\n $activity->value = null;\n }\n\n if ($account) {\n $this->logger->info('Setting account id', ['accountId' => $account->id]);\n $activity->account_id = $account->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('unsetting lead id');\n $activity->lead_id = null;\n\n // Unset the contact if switching different accounts. Will be set up below if still applicable.\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {\n $this->logger->info('Unsetting contact id');\n $activity->contact_id = null;\n }\n }\n\n if ($opportunity) {\n $this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);\n $this->logger->info('unsetting lead id');\n $activity->opportunity_id = $opportunity->id;\n $activity->value = $opportunity->value;\n\n // If we are changed from an lead > account, unset the lead data.\n $activity->lead_id = null;\n }\n\n if ($contact) {\n $this->logger->info('setting contact id', ['contactId' => $contact->id]);\n $activity->contact_id = $contact->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('Unsetting lead id');\n $activity->lead_id = null;\n }\n\n $activity->is_internal = $isInternal;\n $activity->save();\n $activity->refresh();\n\n $this->logger->notice('Activity saved', [\n 'activity_id' => $activity->getId(),\n 'lead_id' => $activity->lead_id,\n 'account_id' => $activity->account_id,\n 'contact_id' => $activity->contact_id,\n 'opportunity_id' => $activity->opportunity_id,\n 'stage_id' => $activity->stage_id,\n 'crm_provider_id' => $activity->getCrmProviderId(),\n ]);\n\n // Store entities as field data on the activity.\n $updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);\n\n if ($activity->isLoggable()) {\n // Follow-up Task or Event data.\n $followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);\n\n $this->logger->info('CRM LOG manual log triggered', [\n 'activityId' => $activity->getUuid(),\n 'followupData' => $followupData,\n 'userId' => $user->getUuid(),\n ]);\n\n // Store data in the CRM.\n // ++add check for crm_required\n $job = new SaveActivity($activity, $followupData);\n\n if ($updatedData) {\n $job->delay(Carbon::now()->addMinutes($jobDelay));\n }\n\n dispatch($job);\n\n // Manually dispatch log for Opportunity or Prospect added\n if ($activity->hasOpportunity() || $activity->hasProspect()) {\n event(new ActivityProspectAdded(\n activity: $activity,\n eventSource: 'manually-log-crm-data'\n ));\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.\n *\n * @param ServiceInterface $service\n * @param Activity $activity\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array\n {\n $updatedData = [];\n $existingData = $activity->data()->get();\n\n // We need to delete any existing data to overwrite with latest values.\n $activity->data()->delete();\n\n $layoutEntities = $layout->entities()\n ->with('field', 'parent')\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->get();\n\n /** @var LayoutEntity $entity */\n foreach ($layoutEntities as $entity) {\n // If the user has provided a value for this entity\n if (array_key_exists($entity->id_string, $entities)) {\n $value = $entities[$entity->id_string];\n\n // Convert raw data into values that the CRM can consume.\n if ($value) {\n $value = $service->normalizeValue($entity->field->type, $value);\n }\n\n // Check the field is part of the activity-summary section.\n if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {\n // This is the internal database ID, not the external CRM ID.\n $objectId = null;\n\n switch ($entity->field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $objectId = $activity->account_id;\n\n break;\n\n case Field::OBJECT_CONTACT:\n $objectId = $activity->contact_id;\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n $objectId = $activity->opportunity_id;\n\n break;\n\n case Field::OBJECT_LEAD:\n $objectId = $activity->lead_id;\n\n break;\n\n case Field::OBJECT_TASK:\n case Field::OBJECT_EVENT:\n $objectId = $activity->id;\n\n break;\n }\n\n if ($objectId) {\n /** @var FieldData $data */\n $data = $activity->data()->create([\n 'crm_layout_entity_id' => $entity->id,\n 'crm_field_id' => $entity->crm_field_id,\n 'object_type' => $entity->field->object_type,\n 'object_id' => $objectId,\n 'value' => $value,\n ]);\n\n // Never send read-only field data to the CRM.\n if ($entity->read_only === false && $entity->is_visible) {\n $existingValue = $existingData\n ->where('crm_layout_entity_id', $entity->id)\n ->where('crm_field_id', $entity->crm_field_id)\n ->where('object_type', $entity->field->object_type)\n ->where('object_id', $objectId)\n ->first();\n\n // If the field was actually changed, we need to reflect this in the CRM too.\n if ($existingValue === null || $existingValue->value !== $value) {\n $updatedData[] = $data->id;\n }\n }\n }\n }\n }\n }\n\n return $updatedData;\n }\n\n /**\n * Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.\n *\n * @param ServiceInterface $crmService\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array\n {\n $fieldData = [];\n foreach ($entities as $entityId => $value) {\n // Only bother with fields that have a value.\n if ($value) {\n // Extract the entity from the UUID. Check the field is valid and part of the follow-up section.\n $entity = $layout->entities()\n ->uuid($entityId, false)\n ->whereHas('parent', function ($query) {\n $query->where('label', 'follow-up');\n })\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->first();\n\n if ($entity) {\n // Convert raw data into values that the CRM can consume.\n $value = $crmService->normalizeValue($entity->field->type, $value);\n\n // Add the field and value to the payload.\n $fieldData += [\n $entity->field->crm_provider_id => $value,\n ];\n }\n }\n }\n\n return $fieldData;\n }\n\n /**\n * @param Activity $activity\n */\n private function validateSummary(Activity $activity): void\n {\n $team = $activity->user->team;\n $crmProvider = $team->crm->provider;\n $attributes = [];\n\n $rules = [\n 'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,\n 'title' => 'string|max:250',\n 'prospects' => 'required|array',\n 'opportunity_id' => new CrmReference($crmProvider),\n 'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',\n 'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator\n 'summary' => 'max:50000',\n 'nId' => 'exists:notifications,id',\n 'crm_id' => new CrmReference($crmProvider),\n 'entities' => 'array',\n 'is_internal' => 'boolean',\n ];\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));\n\n // Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.\n $entities = $layout->entities()\n ->where('read_only', 0)\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->whereHas('parent', function ($query) use ($activity) {\n if ($activity->isLoggable() === false) {\n $query->where('label', '<>', 'follow-up');\n }\n });\n\n $isInternal = $this->request->input('is_internal', false);\n\n foreach ($entities->get() as $entity) {\n $rules += $this->buildFieldValidator($entity, $isInternal);\n $attributes += $this->buildFieldMessage($entity);\n }\n\n $this->request->validate($rules, [], $attributes);\n }\n\n private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array\n {\n return [\n 'entities.' . $entity->id_string => $entity->getValidator($isInternal),\n ];\n }\n\n /**\n * @param LayoutEntity $entity\n *\n * @return array\n */\n private function buildFieldMessage(LayoutEntity $entity): array\n {\n $label = $entity->label;\n if ($label === null) {\n $label = $entity->field->label;\n }\n\n return [\n 'entities.' . $entity->id_string => $label,\n ];\n }\n\n public function search(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->debugLog(\n $user,\n 'User extracted from request',\n ['user' => $user->getId(), 'tz' => $user->getTimezone()]\n );\n\n $searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());\n\n $this->debugLog(\n $user,\n 'ActivitySearch criteria built',\n ['searchCriteria' => $searchCriteria]\n );\n\n $filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);\n\n $this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);\n\n $this->validateSearch($request, $filterSet);\n\n $this->debugLog($user, 'Request validated');\n\n $searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);\n\n /** @var Collection<Activity> $activities */\n $activities = $searchResponse['results'];\n\n $this->debugLog($user, 'Activities ES response extracted');\n\n $hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(\n $user->getTeamId(),\n TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),\n );\n\n if ($hideInternalMeetingsSetting?->getValue() === '1') {\n $activities = $activities->filter(function (Activity $activity) {\n if ($activity->is_internal && empty($activity->actual_start_time)) {\n return false;\n }\n\n return true;\n });\n }\n\n $this->debugLog($user, 'Internal meetings (?!) filtered');\n\n $this->response->getManager()\n ->parseIncludes([\n 'category',\n 'organizer.group',\n 'prospect',\n 'stage',\n 'opportunity',\n 'stats',\n 'scorecards',\n 'masterTrack',\n 'activeParticipants',\n 'notification',\n ])\n ->setSerializer(new JsonSerializer());\n\n $transformerExcludes = $this->request->input('exclude');\n if ($transformerExcludes) {\n $this->response->getManager()->parseExcludes($transformerExcludes);\n }\n\n $this->debugLog($user, 'Response Manager (?!) applied');\n\n $transformer = new ActivityTransformer();\n $transformer->setConsumer($user);\n\n $this->debugLog($user, 'Activity Transformer added');\n\n $resource = new \\League\\Fractal\\Resource\\Collection($activities, $transformer);\n $page = $searchCriteria->getPageNumber();\n\n $this->debugLog($user, 'Search criteria page number called', ['page' => $page]);\n\n $histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');\n\n $this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);\n\n return $this->response->withArray([\n 'pagination' => [\n 'total' => $searchResponse['totalHits'],\n 'current' => $page,\n 'prev' => max($page - 1, 1),\n 'next' => $page + 1,\n ],\n 'results' => $this->response->getManager()->createData($resource)->toArray(),\n 'histogram' => $histogram,\n ]);\n }\n\n private function debugLog(User $user, string $logMessage, ?array $context = []): void\n {\n // Debug for Learning People Only\n if ($user->getTeamId() !== 260) {\n return;\n }\n\n Log::notice(\n sprintf('[activity-search-controller] %s', $logMessage),\n $context\n );\n }\n\n /** @throws ValidationException */\n private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void\n {\n $rules = [\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ];\n\n if ($prefix !== null && mb_strpos($prefix, '.') !== false) {\n $rules[rtrim($prefix, '.')] = sprintf(\n 'required|array|max:%d',\n $filterSet->count()\n );\n }\n\n $validationRules = $filterSet->getValidationRules($prefix)\n ->merge($rules)\n ->all();\n\n $request->validate($validationRules);\n }\n\n public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $search = $this->updateOrCreateActivitySearch($request);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function updateActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('update', $search);\n\n $this->updateOrCreateActivitySearch($request, $search);\n\n return $this->response->withOk();\n }\n\n private function storeNamedSearchFilters(\n Collection $request,\n Search $search,\n FilterDefinitionCollection $filterSet,\n ?string $prefix = null,\n ): self {\n $arrayTypeProperties = $filterSet\n ->getPropertyTypes([\n FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,\n ])\n ->all();\n\n $supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);\n\n foreach ($supportedRequestProperties as $requestPropertyName) {\n if (! array_has($request, $requestPropertyName)) {\n continue;\n }\n\n /** @var string|string[] $propertyValue */\n $propertyValue = array_get($request, $requestPropertyName);\n $propertyName = $prefix === null\n ? $requestPropertyName\n : mb_substr($requestPropertyName, mb_strlen($prefix));\n\n $isArrayType = array_has($arrayTypeProperties, $propertyName);\n\n if (! $isArrayType) {\n /** @var string $requestPropertyValue */\n\n $search->filters()->updateOrCreate(\n [\n 'filter' => $propertyName,\n ],\n [\n 'value' => $propertyValue,\n ]\n );\n\n continue;\n }\n\n /** @var string[] $requestPropertyValue */\n\n /** @var SearchFilter[]|Collection $existingFilterValues */\n $existingFilterValuesKeyed = $search->filters()\n ->where('filter', $propertyName)\n ->get()\n ->keyBy('id');\n\n // Iterate over values provided as request parameters\n foreach ($propertyValue as $value) {\n /** @var SearchFilter|null $valueFilter */\n $valueFilter = $search->filters()\n ->where(\n [\n 'filter' => $propertyName,\n 'value' => $value,\n ]\n )\n ->first();\n\n if ($valueFilter !== null) {\n // Remove filter value pair from list to be deleted\n $existingFilterValuesKeyed->forget($valueFilter->id);\n } else {\n // Add new filter/value pair\n $search->filters()->updateOrCreate([\n 'filter' => $propertyName,\n 'value' => $value,\n ]);\n }\n }\n\n // Delete filter value pairs for this filter that no longer exist in request parameters\n foreach ($existingFilterValuesKeyed as $existingFilter) {\n $existingFilter->delete();\n }\n }\n\n /** @var Collection<int, SearchFilter> $filtersKeyed */\n $filtersKeyed = $search->filters()->get()->keyBy('filter');\n\n // wipe removed filters from this search\n foreach ($filtersKeyed as $filterName => $filter) {\n if (array_has($request, $prefix . $filterName)) {\n continue;\n }\n\n // Remove all filter values for this filter\n $search->filters()->where('filter', $filterName)->delete();\n }\n\n return $this;\n }\n\n /**\n * @throws AuthorizationException\n */\n public function fetchActivitySearch(\n Search $search,\n Request $request,\n SearchTransformer $searchTransformer,\n ): JsonResponse {\n $this->authorize('view', $search);\n\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection(\n $user->searches()->get(),\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n /**\n * Deletes a saved search\n *\n * @param Request $request\n * @param Search $search\n *\n * @throws Exception\n *\n * @return JsonResponse\n */\n public function deleteActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('delete', $search);\n\n // Orphan any AutomatedReports that use this search\n $search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);\n\n // Delete filters and the search itself\n $search->filters()->delete();\n $search->delete();\n\n return $this->response->withOk();\n }\n\n public function live(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n $user = $this->getUserFromRequest($request);\n\n $this->request->validate([\n 'sort_direction' => 'in:asc,desc',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ]);\n\n $activities = $repository->getLiveCoachingEligibleActivities(\n user: $user,\n lookBackMinutes: self::LOOK_BACK,\n limit: (int) $this->request->input('limit', 25),\n page: (int) $this->request->input('page', 1),\n sortBy: ['actual_start_time', 'scheduled_start_time'],\n sortDirection: (string) $this->request->input('sort_direction', 'asc'),\n );\n\n $this->response\n ->getManager()\n ->parseIncludes(['organizer.group', 'prospect'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($activities, new ActivityTransformer());\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function show(Activity $activity, ActivityService $activityService): JsonResponse\n {\n $this->authorize('show', $activity);\n\n $user = $activity->getUser();\n $team = $user->getTeam();\n\n // Sync the opportunity with the latest data if possible.\n if ($activity->opportunity_id) {\n try {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n if (! $user->isCrmRequired()) {\n $crmService->setUser($team->getOwner());\n } else {\n $crmService->setUser($user);\n }\n\n $crmService->syncOpportunity($activity->opportunity->crm_provider_id);\n } catch (Exception $exception) {\n // Move on.\n }\n }\n\n $activityData = $activityService->getActivityData($this->request->user(), $activity);\n\n return response()->json($activityData);\n }\n\n public function createRecording(Activity $activity)\n {\n $this->authorize('record', $activity);\n\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Tell Twilio to start recording this activity.\n if ($activity->recording_state === Activity::RECORDING_OFF) {\n $job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withCreated();\n }\n\n return $this->response->errorGone('Activity is already recording.');\n }\n\n public function updateRecording(Request $request, Activity $activity)\n {\n $this->authorize('record', $activity);\n\n $request->validate([\n 'preference' => 'boolean',\n 'state' => [\n 'string',\n Rule::in([\n Activity::RECORDING_IN_PROGRESS,\n Activity::RECORDING_PAUSED,\n ]),\n ],\n ]);\n\n if ($request->has('state')) {\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Toggle the recording state between paused and resumed.\n if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {\n $job = (new ToggleRecording($activity, $request->input('state')))\n ->onQueue(Constants::QUEUE_CONFERENCES);\n\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Recording is not toggleable.');\n }\n\n if ($request->has('preference')) {\n $activity->update([\n 'recording_preference' => $request->input('preference') ? 1 : 0,\n ]);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorWrongArgs('Something went wrong');\n }\n\n public function stopRecording(Activity $activity)\n {\n $this->authorize('stopRecord', $activity);\n\n // Tell Twilio to stop recording this activity.\n if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {\n $job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Activity is not recording.');\n }\n\n /**\n * Add activity to this user's favorites playlist\n *\n * @throws AuthorizationException\n */\n public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse\n {\n $this->authorize('favorite', $activity);\n\n $user = $this->getUserFromRequest($this->request);\n $favorite = $activity->wasFavoritedBy($user);\n $name = $activity->activity_title ?? '';\n\n // It needs to check at least one record.\n if (! $favorite) {\n $favoritePlaylist = $user->favoritePlaylist();\n\n $playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(\n $activity,\n $user,\n $favoritePlaylist\n );\n\n if ($playlistActivity !== null) {\n $playlistActivity->update(\n // Just update, don't sort.\n ['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],\n );\n } else {\n $playlistActivity = $activity->playlistActivities()->create([\n 'playlist_id' => $favoritePlaylist->getId(),\n 'user_id' => $user->getId(),\n 'start_time' => 0,\n 'name' => mb_strimwidth($name, 0, 100),\n ]);\n // Sort it on top.\n $playlistActivity->update(\n [\n 'sort' => $playlistActivityRepository->calculateNewSortOrder(\n null,\n $playlistActivity,\n ),\n ],\n );\n }\n\n $playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);\n\n return new JsonResponse([], JsonResponse::HTTP_CREATED);\n }\n\n return new JsonResponse(\n [\n 'error' => [\n 'code' => AbstractResponse::CODE_CONFLICT,\n 'http_code' => JsonResponse::HTTP_CONFLICT,\n 'message' => 'Resource Already Exists',\n ],\n ],\n JsonResponse::HTTP_CONFLICT,\n );\n }\n\n /**\n * Remove activity from this user's favorites playlist\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unfavorite(Activity $activity)\n {\n $user = $this->request->user();\n\n $favorites = $activity->favoritedBy($user);\n\n if ($favorites && $favorites->isEmpty()) {\n return $this->response->errorNotFound('Favorite not found.');\n }\n\n $this->authorize('unfavorite', [$activity, $favorites]);\n\n // When you unfavorite an activity,\n // it should remove all the activities in it, including snippets.\n $isDeleted = $favorites->each(function ($favorite) {\n $favorite->forceDelete();\n });\n\n if ($isDeleted) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not remove favorite.');\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function notify(Activity $activity)\n {\n $this->authorize('notify', $activity);\n\n $user = $this->request->user();\n\n $existingNotification = $activity->availabilityNotifications()\n ->where('user_id', $user->id)\n ->exists();\n\n if ($existingNotification) {\n return $this->response->errorWrongArgs('Notification is already configured.');\n }\n\n $notification = Activity\\AvailabilityNotification::create([\n 'user_id' => $user->id,\n 'activity_id' => $activity->id,\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($notification, new AvailabilityNotificationTransformer());\n }\n\n /**\n * @param Activity $activity\n * @param Activity\\AvailabilityNotification $notification\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unnotify(Activity $activity, Activity\\AvailabilityNotification $notification)\n {\n $this->authorize('unnotify', [$activity, $notification]);\n\n if ($notification->sent_at || $notification->delete()) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not delete notification.');\n }\n\n public function play(Request $request, Activity $activity)\n {\n $this->authorize('stream', $activity);\n\n $request->validate([\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $activity->plays()->create([\n 'user_id' => $user->getId(),\n 'start_time' => $request->input('start_time'),\n ]);\n\n return $this->response->withCreated();\n }\n\n /**\n * @param Activity $activity\n *\n * @return mixed\n */\n public function comment(Activity $activity)\n {\n return $this->newComment($activity);\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @return mixed\n */\n public function replyComment(Activity $activity, Comment $comment)\n {\n return $this->newComment($activity, $comment);\n }\n\n /**\n * @param Activity $activity\n * @param Comment|null $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n protected function newComment(Activity $activity, ?Comment $comment = null)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n 'type' => 'integer|between:0,3',\n 'visibility' => sprintf('nullable|integer|between:1,%d', count(Comment::getVisibilityLevels())),\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n $threadStartId = null;\n if ($comment) {\n $threadStartId = $comment->thread_start_id ?: $comment->id;\n }\n\n try {\n $newComment = Comment::create([\n 'parent_comment_id' => $comment->id ?? null,\n 'thread_start_id' => $threadStartId,\n 'activity_id' => $activity->id,\n 'user_id' => $this->request->user()->id,\n 'comment' => trim($this->request->input('comment')),\n 'start_time' => $this->request->input('start_time', 0),\n 'end_time' => $this->request->input('end_time', 0),\n 'type' => $this->request->input('type', Comment::TYPE_NEUTRAL),\n 'visibility' => $this->request->input('visibility', Comment::VISIBILITY_PUBLIC),\n ]);\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($newComment, new ActivityCommentTransformer());\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not create comment.' . $exception->getMessage());\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function updateComment(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n try {\n $comment->update([\n 'comment' => trim($this->request->input('comment')),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment.');\n }\n }\n\n public function updateCommentVisibility(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'visibility' => sprintf('integer|between:1,%d', count(Comment::getVisibilityLevels())),\n ]);\n\n $visibility = $this->request->input('visibility');\n\n if ($comment->parent !== null) {\n return $this->response->errorWrongArgs('Comment visibility can only be updated on top level comments.');\n }\n\n try {\n $this->activityCommentService->updateCommentVisibility($comment, $visibility);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment\\'s visibility.');\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function deleteComment(Activity $activity, Comment $comment)\n {\n $this->authorize('deleteComment', [$activity, $comment]);\n\n // Delete comment and any children.\n $comment->delete();\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function fetchComments()\n {\n $user = $this->request->user();\n $this->request->validate([\n 'forUserId' => 'uuid:users,team_id,' . $user->team_id,\n 'types' => 'array',\n 'types.*' => 'integer|between:0,3',\n ]);\n $forUser = null;\n\n $types = [Comment::TYPE_NEUTRAL, Comment::TYPE_GAME_CHANGER, Comment::TYPE_POSITIVE];\n $user = $this->request->user();\n if ($this->request->has('forUserId')) {\n $forUser = $user->team->users()->uuid($this->request->input('forUserId'));\n }\n\n $comments = Comment::query()\n ->whereHas('activity', static function (Builder $builder) use ($user, $forUser): void {\n $builder\n // I left feedback on my own activity; or\n ->where('activities.user_id', $user->getId());\n if ($forUser) {\n // I left feedback on any activity for this user.\n $builder->orWhere([\n 'user_id' => $user->getId(),\n 'activities.user_id' => $forUser->getId(),\n ]);\n }\n })\n ->whereIn('type', $this->request->input('types', $types))\n ->orderBy('created_at', 'desc')\n ->get();\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity', 'user'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($comments, new ActivityCommentTransformer());\n }\n\n public function deleteCoachingFeedback(Activity $activity, CoachingFeedback $coachingFeedback)\n {\n $this->authorize('deleteCoachingFeedback', [$activity, $coachingFeedback]);\n $activity = $coachingFeedback->getActivity();\n\n if ($coachingFeedback->delete()) {\n event(new UpdateSingleEntity(\n entityId: $activity->getId(),\n updateTarget: UpdateTargetEnum::ACTIVITY,\n purpose: 'delete-coaching-feedback',\n ));\n\n return $this->response->withOk();\n }\n\n return $this->response->withError('Delete operation failed. Contact support.', 500);\n }\n\n /**\n * Add new or update Coaching feedback\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws \\Illuminate\\Validation\\ValidationException\n *\n * @return mixed\n */\n public function putCoachingFeedback(Request $request, Activity $activity)\n {\n $user = $request->user();\n\n if (! $user instanceof User) {\n abort(403);\n }\n $teamId = $user->getTeamId();\n\n $this->authorize('coach', $activity);\n\n $this->request->validate([\n 'coach_id' => 'required|uuid:users,team_id,' . $teamId,\n 'coachee_id' => 'required|uuid:users,team_id,' . $teamId,\n 'visibility' => ['required', Rule::in(CoachingFeedback::VISIBILITIES)],\n 'coaching_sections.*.uuid' => 'required|uuid:coaching_sections',\n 'coaching_sections.*.score' => ['required', Rule::in(CoachingSectionFeedback::SCORES)],\n 'coaching_sections.*.summary' => 'string|max:10000',\n 'coaching_sections.*.criteria.*.uuid' => 'required|uuid:coaching_section_criteria',\n 'coaching_sections.*.criteria.*.note' => 'required|string|max:10000',\n 'sharedWithUsers' => [\n 'required_if:visibility,' . CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS,\n 'array',\n ],\n 'sharedWithUsers.*' => [\n 'uuid:users,team_id,' . $teamId,\n ],\n ]);\n\n /** @var User $coach */\n $coach = User::uuid($this->request->input('coach_id'));\n /** @var User $coachee */\n $coachee = User::uuid($this->request->input('coachee_id'));\n $coachingSectionFeedbacks = $this->request->input('coaching_sections');\n\n $previousRecord = $this->coachingFeedbackRepository->getOneForActivityByCoacheeAndCoach(\n $coachee->getId(),\n $coach->getId(),\n $activity->getId()\n );\n $recordIsNew = false;\n if ($previousRecord === null) {\n $recordIsNew = true;\n }\n\n if (! $coachee->isSameTeamId($coach)) {\n return $this->response->errorForbidden('User not member of your team.');\n }\n\n if (! is_array($coachingSectionFeedbacks) || count($coachingSectionFeedbacks) < 1) {\n return $this->response->withError('At least one Coaching Framework Section shall be scored.', 422);\n }\n\n if (! $activity->participants()->where('participants.user_id', $coachee->id)->exists()) {\n return $this->response->withError('Coached user did not participate activity.', 422);\n }\n\n $visibility = $this->request->input('visibility');\n\n $shouldSendNotification = $recordIsNew;\n if ($recordIsNew === false && $visibility !== $previousRecord->getVisibility()) {\n $shouldSendNotification = true;\n }\n\n /**\n * Create CoachingFeedback\n *\n * @var CoachingFeedback $coachingFeedback\n */\n $coachingFeedback = $activity->coachingFeedbacks()->updateOrCreate(\n [\n 'coach_id' => $coach->id,\n 'coachee_id' => $coachee->id,\n ],\n [\n 'framework_id' => $activity->category->id,\n 'visibility' => $visibility,\n ]\n );\n\n $sharedUserIds = [];\n if ($visibility === CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS) {\n foreach ($this->request->input('sharedWithUsers') as $sharedWithUserUuid) {\n /** @var User $user */\n $user = User::uuid($sharedWithUserUuid);\n $sharedUserIds[] = $user->getId();\n }\n }\n\n $syncResult = $coachingFeedback->customAccessUsers()->sync($sharedUserIds);\n\n $scores = [];\n\n\n /**\n * Create CoachingSectionsFeedbacks.\n *\n * @var CoachingSectionFeedback $coachingSectionFeedback\n */\n foreach ($coachingSectionFeedbacks as $coachingSectionFeedbackInput) {\n $coachingSection = CoachingSection::uuid($coachingSectionFeedbackInput['uuid']);\n $coachingSectionFeedback = $coachingFeedback->sectionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_id' => $coachingSection->id,\n ],\n [\n 'score' => array_get($coachingSectionFeedbackInput, 'score'),\n 'summary' => array_get($coachingSectionFeedbackInput, 'summary') ?? '',\n ]\n );\n\n $scores[] = array_get($coachingSectionFeedbackInput, 'score');\n\n $criteria = array_get($coachingSectionFeedbackInput, 'criteria');\n if (is_array($criteria) && ! empty($criteria)) {\n foreach ($criteria as $criteriaFeedbackInput) {\n $coachingSectionFeedback->criterionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_criterion_id' => CoachingSectionCriterion::uuid(array_get($criteriaFeedbackInput, 'uuid'))\n ->id,\n ],\n ['note' => array_get($criteriaFeedbackInput, 'note')],\n );\n }\n }\n }\n\n $coachingFeedback->average_score = array_sum($scores) / count($scores);\n\n if ($recordIsNew === false && $coachingFeedback->getAverageScore() !== $previousRecord->getAverageScore()) {\n $shouldSendNotification = true;\n }\n if (! empty($syncResult['attached']) || ! empty($syncResult['detached']) || ! empty($syncResult['updated'])) {\n $shouldSendNotification = true;\n }\n\n $coachingFeedback->save();\n // ensure updated at for coaching feedback on section feedback summary added.\n $coachingFeedback->touch();\n\n if ($shouldSendNotification) {\n event(new Coached($coachingFeedback));\n }\n\n Datadog::increment('jiminny.activity.score.update', 1, ['company' => $activity->user->team->slug]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n $coachingFeedbackTransformer = new CoachingFeedbackTransformer();\n $coachingFeedbackTransformer->setConsumer($this->getUserFromRequest($request));\n\n return $this->response->withItem($coachingFeedback, $coachingFeedbackTransformer);\n }\n\n\n /**\n * Retrieve category criteria for coaching.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachingSections(Activity $activity)\n {\n $this->authorize('coach', $activity);\n\n if ($activity->category === null) {\n return $this->response->errorUnprocessable('Category has not yet been assigned.');\n }\n\n $criteria = $activity\n ->category\n ->coachingSections()\n ->where('is_enabled', 1)\n ->orderBy('sequence', 'asc');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($criteria->get(), new CoachingSectionsTransformer());\n }\n\n /**\n * @throws AuthorizationException\n * @throws ValidationException\n *\n * @return mixed\n */\n public function addToPlaylist(Activity $activity, PlaylistTrackFactoryInterface $playlistTrackFactory)\n {\n $this->request->validate([\n 'playlists' => 'required|array',\n 'playlists.*' => 'uuid:playlists',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'name' => 'required|max:100',\n ]);\n\n $this->authorize('addToPlaylist', [$activity, $this->request->input('playlists')]);\n\n $startTime = $this->request->input('start_time');\n $endTime = $this->request->input('end_time');\n $name = $this->request->input('name');\n /** @var User $user */\n $user = $this->request->user();\n\n // Get playlist by uuid.\n foreach ($this->request->input('playlists') as $playlistId) {\n // Pull out the playlist model.\n $playlist = Playlist::uuid($playlistId);\n\n $playlistTrackFactory->createTrack($playlist, $user, [\n 'name' => $name,\n 'activity' => $activity,\n 'start_time' => $startTime,\n 'end_time' => $endTime,\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function share(Request $request, Activity $activity): JsonResponse\n {\n $this->authorize('share', $activity);\n\n $request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'recipients.*.type' => 'in:user,group',\n 'recipients.*.id' => 'string|max:40',\n 'share' => 'string|max:255',\n ]);\n\n $user = $request->user();\n\n $recipients = $request->get('recipients');\n $users = $this->userService->convertRecipientsToUsers($user, $recipients);\n\n $shareData = [\n 'from_user_id' => $user->id,\n 'note' => $request->input('note'),\n 'start_time' => $request->input('start_time'),\n 'end_time' => $request->input('end_time'),\n ];\n\n // Create a share object against a notification provider channel\n if ($request->input('share')) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'notification_provider_channel' => $request->input('share'),\n ]\n )\n );\n\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n\n // Create a share object against each recipient\n foreach ($users as $recipient) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'to_user_id' => $recipient->id,\n ]\n )\n );\n\n // If parent_share_id has been selected yet\n if (! isset($shareData['parent_share_id'])) {\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachRequest(Activity $activity)\n {\n $this->authorize('coachRequest', $activity);\n\n $this->request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'coachers.*.type' => 'required|in:user',\n 'coachers.*.id' => 'required',\n ]);\n\n $coachers = $this->request->get('coachers');\n $user = $this->request->user();\n $users = $this->userService->convertRecipientsToUsers($user, $coachers);\n\n foreach ($users as $coacher) {\n CoachRequest::create([\n 'user_id' => $coacher->id,\n 'activity_id' => $activity->id,\n 'note' => $this->request->get('note'),\n 'start_time' => $this->request->get('start_time'),\n 'end_time' => $this->request->get('end_time'),\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function createActivityTopicTriggers(Activity $activity, LoggerInterface $logger): HttpFoundation\\JsonResponse\n {\n $this->authorize('analyzeTopicTriggers', $activity);\n\n if (! $activity->hasTranscription()) {\n return new HttpFoundation\\JsonResponse(\n [\n 'error' => 'Transcription not found.',\n ],\n JsonResponse::HTTP_NOT_FOUND\n );\n }\n\n $logger->info(__METHOD__ . ': queued for analysis', [\n 'activity' => $activity->id_string,\n ]);\n\n dispatch(new ActivityAnalytics\\Job\\AnalyzeActivityTopicTriggers($activity));\n\n return new HttpFoundation\\JsonResponse(null, JsonResponse::HTTP_CREATED);\n }\n\n public function fetchActivityTopicTriggers(\n Activity $activity,\n LoggerInterface $logger,\n ActivityTopicTriggerTransformer $transformer\n ): HttpFoundation\\JsonResponse {\n $this->authorize('fetchTopicTriggers', $activity);\n\n $logger->debug(__METHOD__, [\n 'activity' => $activity->id_string,\n ]);\n\n if (! $activity->isProcessed()) {\n return new HttpFoundation\\JsonResponse([]);\n }\n\n $payload = [];\n\n if ($activity->hasTopicTriggers()) {\n $payload = $activity->getTopicTriggersSorted()\n ->map(\n static fn (Activity\\TopicTrigger $activityTopicTrigger): array\n => $transformer->transform($activityTopicTrigger)\n )\n ->values()\n ->all();\n }\n\n return new HttpFoundation\\JsonResponse($payload);\n }\n\n /**\n * @param Activity $activity\n * @param StatsTransformer $statsTransformer\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function stats(Activity $activity, StatsTransformer $statsTransformer)\n {\n $this->authorize('stream', $activity);\n\n if (! $activity->hasTranscription()) {\n return $this->response->errorNotFound('Waveform data is not yet generated.');\n }\n\n $this->response\n ->getManager()\n ->parseIncludes(['wavedata'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($activity, $statsTransformer);\n }\n\n public function destroy(Activity $activity)\n {\n $this->authorize('delete', $activity);\n\n $activity->delete();\n\n \\Log::info('Soft delete activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n\n return $this->response->withNoContent();\n }\n\n public function note(Activity $activity)\n {\n $this->authorize('note', $activity);\n\n $this->request->validate([\n 'note' => 'required|min:1|max:2000',\n 'time' => 'required|numeric|min:0|max:86400',\n ]);\n\n $note = $this->request->input('note');\n $time = $this->request->input('time');\n\n $this->activityService->setActivity($activity);\n $this->activityService->takeNote($this->getUser(), $note, $time);\n\n return $this->response->withCreated();\n }\n\n /**\n * Mark an activity as private.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPrivate(Activity $activity)\n {\n $this->authorize('markAsPrivate', $activity);\n\n if ($activity->is_private === false) {\n $activity->is_private = true;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * Mark an activity as public.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPublic(Activity $activity)\n {\n $this->authorize('markAsPublic', $activity);\n\n if ($activity->is_private) {\n $activity->is_private = false;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws LogicException\n */\n public function fetchCloudFrontS3MediaKeys(Activity $activity, PlaybackService $playbackService): JsonResponse\n {\n $masterTrack = $activity->masterTrack()->first();\n\n if (! $masterTrack instanceof Track) {\n throw new LogicException(sprintf('Master track not found for activity \"%s\"', $activity->getUuid()));\n }\n\n return $this->response->withArray(\n $playbackService->generateCookies(\n $masterTrack,\n $this->request->ip(),\n ),\n );\n }\n\n /**\n * @throws ValidationException\n */\n private function updateOrCreateActivitySearch(Request $request, ?Search $search = null): Search\n {\n $request->validate([\n 'name' => 'required|string|min:2|max:100',\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $searchName = $request->input('name');\n\n if ($search !== null) {\n $search->update([\n 'name' => $searchName,\n ]);\n\n return $search;\n }\n\n $request->validate([\n 'filters' => ['required', 'array', new MultidimensionalArrayMaxCharRule(limit: 255)],\n 'nudges' => 'array|max:' . count(Nudge::MAP_CHANNEL),\n 'nudges.*.channel' => 'required|in:' . implode(',', Nudge::MAP_CHANNEL),\n 'nudges.*.frequency' => 'required|in:' . implode(',', Nudge::MAP_FREQUENCY),\n 'nudges.*.expiresAt' => [\n 'required',\n 'date',\n 'after:today',\n 'before_or_equal:' . now()->addYear()->format('Y-m-d'),\n ],\n ]);\n\n $searchCriteria = Criteria::createFromRequest(\n Collection::make($request->input('filters', []))->all(),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($searchCriteria, $user);\n $this->validateSearch($request, $filterSet, 'filters.');\n\n /** @var Search $search */\n $search = Search::create([\n 'name' => $searchName,\n 'uuid' => Uuid::uuid4()->toString(),\n 'user_id' => $user->getId(),\n ]);\n\n Collection::make($request->input('nudges', []))\n ->each(fn (array $attributes): Nudge => $this->nudgeFactory->createNudge($search, $attributes));\n\n $this->storeNamedSearchFilters(Collection::make($request->all()), $search, $filterSet, 'filters.');\n\n return $search;\n }\n\n private function resolveAccount(\n Team $team,\n Contact $contact,\n ServiceInterface $crmService,\n array $prospects,\n ): ?Account {\n $this->logger->info('Resolving account from contact');\n $account = $contact->getAccount();\n\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS)) {\n $this->logger->info('Team does not have feature to link activity to multiple prospects');\n\n return $account;\n }\n\n $this->logger->info('Resolving account from prospect data');\n $accountData = array_filter(\n $prospects,\n static fn (array $prospectData): bool => $prospectData['type'] === 'account'\n );\n\n if (! empty($accountData)) {\n $this->logger->info('Found account data in prospects');\n $accountData = reset($accountData);\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountData['id'])->first();\n\n if (! $account instanceof Account) {\n $this->logger->info('Account not found in database, syncing from CRM');\n $account = $crmService->syncAccount($accountData['id']);\n }\n }\n\n $this->logger->info('Resolved account', ['account' => $account->getId()]);\n\n return $account;\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Http\\Controllers\\API;\n\nuse Carbon\\Carbon;\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Exception;\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Validation\\Rule;\nuse Illuminate\\Validation\\Rules\\In;\nuse Illuminate\\Validation\\ValidationException;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ActivityAnalytics;\nuse Jiminny\\Component\\ActivitySearch;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Contracts\\ES\\Events\\UpdateSingleEntity;\nuse Jiminny\\Contracts\\ES\\UpdateTargetEnum;\nuse Jiminny\\Contracts\\Nudge\\NudgeFactoryInterface;\nuse Jiminny\\Contracts\\Playlist\\PlaylistTrackFactoryInterface;\nuse Jiminny\\Contracts\\Repositories\\PlaylistActivityRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Enums\\TeamSetting;\nuse Jiminny\\Events\\Activities\\AiAutomation\\ActivityProspectAdded;\nuse Jiminny\\Events\\Activities\\Coaching\\Coached;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Controllers\\CommentContextInterface;\nuse Jiminny\\Http\\Responses\\Api\\AbstractResponse;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\ActivityCommentTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTopicTriggerTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTransformer;\nuse Jiminny\\Http\\Transformers\\AvailabilityNotificationTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingFeedbackTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingSectionsTransformer;\nuse Jiminny\\Http\\Transformers\\SearchTransformer;\nuse Jiminny\\Http\\Transformers\\StatsTransformer;\nuse Jiminny\\Jobs\\Crm\\SaveActivity;\nuse Jiminny\\Jobs\\Crm\\UpdateStage;\nuse Jiminny\\Jobs\\Telephony\\StartRecording;\nuse Jiminny\\Jobs\\Telephony\\StopRecording;\nuse Jiminny\\Jobs\\Telephony\\ToggleRecording;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\CoachingFeedback;\nuse Jiminny\\Models\\CoachingSection;\nuse Jiminny\\Models\\CoachingSectionCriterion;\nuse Jiminny\\Models\\CoachingSectionFeedback;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\LanguageDialect;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Nudge;\nuse Jiminny\\Models\\PlaybookCategory;\nuse Jiminny\\Models\\Playlist;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\Track;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\CoachingFeedbackRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Rules\\MultidimensionalArrayMaxCharRule;\nuse Jiminny\\Services\\ActivityService;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Services\\PlaybackService;\nuse Jiminny\\Services\\UserService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\nuse Ramsey\\Uuid\\Uuid;\nuse Sentry;\nuse Symfony\\Component\\HttpFoundation;\n\nfinal class ActivityController extends Controller implements CommentContextInterface\n{\n // Number of minutes to look back on activities. i.e. a timeout on activity duration.\n private const int LOOK_BACK = 180;\n\n public function __construct(\n private ProviderRegistry $providerRegistry,\n private ActivityService $activityService,\n Response $response,\n private UserService $userService,\n private ActivitySearch\\Service\\ActivitySearch $activitySearch,\n private NudgeFactoryInterface $nudgeFactory,\n private ActivityCommentService $activityCommentService,\n private LoggerInterface $logger,\n private readonly CoachingFeedbackRepository $coachingFeedbackRepository,\n private readonly TeamRepository $teamRepository,\n ) {\n parent::__construct($response);\n }\n\n public static function getCommentImplementation(): string\n {\n return Comment::class;\n }\n\n public function delete()\n {\n $this->request->validate([\n '*' => 'uuid:activities',\n ]);\n\n $deletedIds = [];\n foreach ($this->request->all() as $activityId) {\n $activity = Activity::idOrUuId($activityId);\n\n try {\n if ($this->authorize('delete', $activity)) {\n $activity->delete();\n $deletedIds[] = $activityId;\n\n \\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n }\n } catch (AuthorizationException $authorizationException) {\n // They didn't have permission.\n }\n }\n\n return $this->response->withArray($deletedIds);\n }\n\n public function update(Request $request, Activity $activity)\n {\n $this->authorize('updateMetadata', $activity);\n\n $request->validate([\n 'title' => 'string|max:250',\n 'category_id' => 'uuid:playbook_categories',\n 'language' => [\n new In(\n LanguageDialect::query()\n ->with('language')\n ->cursor()\n ->map(static function (LanguageDialect $languageDialect): string {\n return $languageDialect->getLanguageLocale();\n })\n ->all()\n ),\n ],\n ]);\n\n if ($request->has('title')) {\n $activity->title = $request->input('title');\n }\n\n if ($request->has('category_id')) {\n $category = PlaybookCategory::uuid($request->input('category_id'));\n\n if ($category->playbook->team_id !== $request->user()->team_id) {\n return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n if ($request->has('language')) {\n if (! $activity->isInProgress()) {\n return $this->response->withError(\n 'Activity language can only be set while the meeting is in progress.',\n 400\n );\n }\n\n $activity->setLanguageCode($request->input('language'));\n }\n\n $activity->save();\n\n return $this->response->withOk();\n }\n\n // XXX: This should be merged with the update method.\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws SocialAccountTokenInvalidException\n *\n * @return mixed\n */\n public function summarize(Activity $activity): mixed\n {\n $this->logger->info('[Log Activity] Summarizing activity ', [\n 'activityId' => $activity->getUuid(),\n 'payload' => $this->request->all(),\n ]);\n $this->authorize('update', $activity);\n\n $this->logger->info('[Log Activity] Validating summary');\n // Validate the payload.\n $this->validateSummary($activity);\n\n // All objects must belong to this team.\n /** @var User $user */\n $user = $this->request->user();\n $team = $user->getTeam();\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n try {\n $crmUser = $user;\n if ($user->isCrmRequired() === false) {\n $crmUser = $team->owner;\n }\n $crmService->setUser($crmUser);\n } catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());\n }\n\n $rawEntities = $this->request->input('entities');\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid(\n $this->request->input('layout_id')\n );\n\n // Delay execution of CRM jobs to avoid locking issues.\n $jobDelay = 0;\n\n // If we have arrived from a notification, mark it as read.\n $notificationId = $this->request->input('nId');\n if ($notificationId) {\n $notification = $user->unreadNotifications->where('id', $notificationId)->first();\n\n if ($notification) {\n $notification->markAsRead();\n }\n }\n\n $title = $this->request->input('title');\n $prospects = $this->request->input('prospects');\n $opportunityId = $this->request->input('opportunity_id');\n $stageId = $this->request->input('stage_id');\n $categoryId = $this->request->input('category_id');\n $summary = $this->request->input('summary');\n $crmProviderId = $this->request->input('crm_id');\n $isInternal = $this->request->input('is_internal') ?? false;\n\n $lead = null;\n $category = null;\n $account = null;\n $contact = null;\n $opportunity = null;\n $stage = null;\n $callStage = null;\n\n foreach ($prospects as $prospectData) {\n $objectId = $prospectData['id'];\n\n if ($objectId === null) {\n continue;\n }\n\n $objectType = $prospectData['type'];\n $this->logger->info('debug', ['prospect_data' => $prospectData]);\n\n try {\n if ($objectType === null) {\n $this->logger->info('no object type');\n if ($crmService instanceof SupportsObjectTypeParseInterface) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n }\n\n switch ($objectType) {\n case 'lead':\n $this->logger->info('Processing lead');\n /** @var Lead|null $lead */\n $lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();\n\n // Lead does not exist locally, import it.\n if ($lead === null) {\n $this->logger->info('Lead does not exist locally');\n /** @var Lead $lead */\n $lead = $crmService->syncLead($objectId);\n }\n\n $this->logger->info('Lead found', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n if ($stageId === null) {\n $this->logger->info('Stage ID is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $lead->stage;\n\n break;\n }\n\n $this->logger->info('Looking for stage');\n // Determine if they have changed the stage.\n /** @var Stage $stage */\n $stage = $team->crm->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_LEAD)\n ->firstOrFail();\n\n $this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);\n if ($lead->stage_id && $lead->stage_id !== $stage->id) {\n $this->logger->info('Stage has changed');\n // Storage current stage on activity.\n $callStage = $lead->stage;\n\n // The stage has changed, update in remote CRM.\n dispatch(new UpdateStage($activity, $lead, $callStage, $stage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing lead stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->getName(),\n $stage->getName()\n ),\n [\n 'user' => $user->getUuid(),\n 'lead' => $lead->getUuid(),\n ]\n );\n } else {\n $this->logger->info('Stage has not changed');\n // Stage remains as current.\n $callStage = $stage;\n }\n\n break;\n\n case 'account':\n $this->logger->info('Processing account');\n // If the object is not a lead, it should be an account.\n $account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();\n\n // Account does not exist locally, import it.\n if ($account === null) {\n $this->logger->info('Account does not exist locally');\n $account = $crmService->syncAccount($objectId);\n }\n\n $this->logger->info('Account found', ['accountId' => $account->id]);\n\n break;\n case 'contact':\n $this->logger->info('processing contact');\n $contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $this->logger->info('contact does not exist locally');\n $contact = $crmService->syncContact($objectId);\n }\n\n $this->logger->info('resolving account');\n $account = $this->resolveAccount($team, $contact, $crmService, $prospects);\n\n break;\n }\n\n // If they have specified an opportunity, retrieve this with stage.\n if ($opportunityId) {\n $this->logger->info('opportunity id is set');\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if ($opportunity === null) {\n $this->logger->info('opportunity does not exist locally');\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n if ($stageId === null) {\n $this->logger->info('stage id is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $opportunity->stage ?? null;\n } else {\n $this->logger->info('looking for stage');\n /** @var ?Stage $opportunityStage */\n $opportunityStage = $team->crm\n ->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n // There is a chance we still cannot import this opportunity.\n if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {\n $this->logger->info('opportunity stage has changed');\n // Storage current stage on activity.\n $callStage = $opportunity->stage;\n\n dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing opportunity stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->name,\n $opportunityStage->name\n ),\n [\n 'userId' => $user->id_string,\n 'opportunityId' => $opportunity->id_string,\n ]\n );\n } else {\n $this->logger->info('opportunity stage has not changed');\n // Stage remains as current.\n $callStage = $opportunityStage;\n }\n }\n }\n\n if ($crmProviderId) {\n // Cast $crmProviderId to string otherwise it won't use database index for some records\n $linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();\n\n // Check if this activity has already been assigned to a different activity.\n if ($linkedActivity && $linkedActivity->id !== $activity->id) {\n throw new InvalidArgumentException(\n 'Sorry, the linked task has already been logged under a different call. '\n . 'Please choose another linked task.'\n );\n }\n }\n } catch (InvalidArgumentException $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($exception->getMessage());\n } catch (Exception $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorInternalError(\n 'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'\n );\n }\n }\n\n if ($categoryId) {\n $category = PlaybookCategory::uuid($categoryId);\n\n if ($category->playbook->team_id !== $team->id) {\n throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n $this->logger->info('Prospect data', [\n 'lead_id' => $lead?->getId(),\n 'account_id' => $account?->getId(),\n 'contact_id' => $contact?->getId(),\n 'opportunity_id' => $opportunity?->getId(),\n 'stage_id' => $stage?->getId(),\n ]);\n\n if ($title) {\n $activity->title = $title;\n }\n\n if ($summary) {\n $activity->summary = $summary;\n }\n\n if ($crmProviderId) {\n $activity->crm_provider_id = $crmProviderId;\n }\n\n if ($callStage) {\n $this->logger->info('Setting stage id', ['stageId' => $callStage->id]);\n $activity->stage_id = $callStage->id;\n }\n\n if ($lead) {\n $this->logger->info('Setting lead id', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n // If we are changed from an account > lead, unset the account data.\n $this->logger->info('Unsetting account id, opportunity id, contact id, value');\n $activity->account_id = null;\n $activity->opportunity_id = null;\n $activity->contact_id = null;\n $activity->value = null;\n }\n\n if ($account) {\n $this->logger->info('Setting account id', ['accountId' => $account->id]);\n $activity->account_id = $account->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('unsetting lead id');\n $activity->lead_id = null;\n\n // Unset the contact if switching different accounts. Will be set up below if still applicable.\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {\n $this->logger->info('Unsetting contact id');\n $activity->contact_id = null;\n }\n }\n\n if ($opportunity) {\n $this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);\n $this->logger->info('unsetting lead id');\n $activity->opportunity_id = $opportunity->id;\n $activity->value = $opportunity->value;\n\n // If we are changed from an lead > account, unset the lead data.\n $activity->lead_id = null;\n }\n\n if ($contact) {\n $this->logger->info('setting contact id', ['contactId' => $contact->id]);\n $activity->contact_id = $contact->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('Unsetting lead id');\n $activity->lead_id = null;\n }\n\n $activity->is_internal = $isInternal;\n $activity->save();\n $activity->refresh();\n\n $this->logger->notice('Activity saved', [\n 'activity_id' => $activity->getId(),\n 'lead_id' => $activity->lead_id,\n 'account_id' => $activity->account_id,\n 'contact_id' => $activity->contact_id,\n 'opportunity_id' => $activity->opportunity_id,\n 'stage_id' => $activity->stage_id,\n 'crm_provider_id' => $activity->getCrmProviderId(),\n ]);\n\n // Store entities as field data on the activity.\n $updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);\n\n if ($activity->isLoggable()) {\n // Follow-up Task or Event data.\n $followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);\n\n $this->logger->info('CRM LOG manual log triggered', [\n 'activityId' => $activity->getUuid(),\n 'followupData' => $followupData,\n 'userId' => $user->getUuid(),\n ]);\n\n // Store data in the CRM.\n // ++add check for crm_required\n $job = new SaveActivity($activity, $followupData);\n\n if ($updatedData) {\n $job->delay(Carbon::now()->addMinutes($jobDelay));\n }\n\n dispatch($job);\n\n // Manually dispatch log for Opportunity or Prospect added\n if ($activity->hasOpportunity() || $activity->hasProspect()) {\n event(new ActivityProspectAdded(\n activity: $activity,\n eventSource: 'manually-log-crm-data'\n ));\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.\n *\n * @param ServiceInterface $service\n * @param Activity $activity\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array\n {\n $updatedData = [];\n $existingData = $activity->data()->get();\n\n // We need to delete any existing data to overwrite with latest values.\n $activity->data()->delete();\n\n $layoutEntities = $layout->entities()\n ->with('field', 'parent')\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->get();\n\n /** @var LayoutEntity $entity */\n foreach ($layoutEntities as $entity) {\n // If the user has provided a value for this entity\n if (array_key_exists($entity->id_string, $entities)) {\n $value = $entities[$entity->id_string];\n\n // Convert raw data into values that the CRM can consume.\n if ($value) {\n $value = $service->normalizeValue($entity->field->type, $value);\n }\n\n // Check the field is part of the activity-summary section.\n if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {\n // This is the internal database ID, not the external CRM ID.\n $objectId = null;\n\n switch ($entity->field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $objectId = $activity->account_id;\n\n break;\n\n case Field::OBJECT_CONTACT:\n $objectId = $activity->contact_id;\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n $objectId = $activity->opportunity_id;\n\n break;\n\n case Field::OBJECT_LEAD:\n $objectId = $activity->lead_id;\n\n break;\n\n case Field::OBJECT_TASK:\n case Field::OBJECT_EVENT:\n $objectId = $activity->id;\n\n break;\n }\n\n if ($objectId) {\n /** @var FieldData $data */\n $data = $activity->data()->create([\n 'crm_layout_entity_id' => $entity->id,\n 'crm_field_id' => $entity->crm_field_id,\n 'object_type' => $entity->field->object_type,\n 'object_id' => $objectId,\n 'value' => $value,\n ]);\n\n // Never send read-only field data to the CRM.\n if ($entity->read_only === false && $entity->is_visible) {\n $existingValue = $existingData\n ->where('crm_layout_entity_id', $entity->id)\n ->where('crm_field_id', $entity->crm_field_id)\n ->where('object_type', $entity->field->object_type)\n ->where('object_id', $objectId)\n ->first();\n\n // If the field was actually changed, we need to reflect this in the CRM too.\n if ($existingValue === null || $existingValue->value !== $value) {\n $updatedData[] = $data->id;\n }\n }\n }\n }\n }\n }\n\n return $updatedData;\n }\n\n /**\n * Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.\n *\n * @param ServiceInterface $crmService\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array\n {\n $fieldData = [];\n foreach ($entities as $entityId => $value) {\n // Only bother with fields that have a value.\n if ($value) {\n // Extract the entity from the UUID. Check the field is valid and part of the follow-up section.\n $entity = $layout->entities()\n ->uuid($entityId, false)\n ->whereHas('parent', function ($query) {\n $query->where('label', 'follow-up');\n })\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->first();\n\n if ($entity) {\n // Convert raw data into values that the CRM can consume.\n $value = $crmService->normalizeValue($entity->field->type, $value);\n\n // Add the field and value to the payload.\n $fieldData += [\n $entity->field->crm_provider_id => $value,\n ];\n }\n }\n }\n\n return $fieldData;\n }\n\n /**\n * @param Activity $activity\n */\n private function validateSummary(Activity $activity): void\n {\n $team = $activity->user->team;\n $crmProvider = $team->crm->provider;\n $attributes = [];\n\n $rules = [\n 'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,\n 'title' => 'string|max:250',\n 'prospects' => 'required|array',\n 'opportunity_id' => new CrmReference($crmProvider),\n 'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',\n 'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator\n 'summary' => 'max:50000',\n 'nId' => 'exists:notifications,id',\n 'crm_id' => new CrmReference($crmProvider),\n 'entities' => 'array',\n 'is_internal' => 'boolean',\n ];\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));\n\n // Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.\n $entities = $layout->entities()\n ->where('read_only', 0)\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->whereHas('parent', function ($query) use ($activity) {\n if ($activity->isLoggable() === false) {\n $query->where('label', '<>', 'follow-up');\n }\n });\n\n $isInternal = $this->request->input('is_internal', false);\n\n foreach ($entities->get() as $entity) {\n $rules += $this->buildFieldValidator($entity, $isInternal);\n $attributes += $this->buildFieldMessage($entity);\n }\n\n $this->request->validate($rules, [], $attributes);\n }\n\n private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array\n {\n return [\n 'entities.' . $entity->id_string => $entity->getValidator($isInternal),\n ];\n }\n\n /**\n * @param LayoutEntity $entity\n *\n * @return array\n */\n private function buildFieldMessage(LayoutEntity $entity): array\n {\n $label = $entity->label;\n if ($label === null) {\n $label = $entity->field->label;\n }\n\n return [\n 'entities.' . $entity->id_string => $label,\n ];\n }\n\n public function search(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->debugLog(\n $user,\n 'User extracted from request',\n ['user' => $user->getId(), 'tz' => $user->getTimezone()]\n );\n\n $searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());\n\n $this->debugLog(\n $user,\n 'ActivitySearch criteria built',\n ['searchCriteria' => $searchCriteria]\n );\n\n $filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);\n\n $this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);\n\n $this->validateSearch($request, $filterSet);\n\n $this->debugLog($user, 'Request validated');\n\n $searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);\n\n /** @var Collection<Activity> $activities */\n $activities = $searchResponse['results'];\n\n $this->debugLog($user, 'Activities ES response extracted');\n\n $hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(\n $user->getTeamId(),\n TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),\n );\n\n if ($hideInternalMeetingsSetting?->getValue() === '1') {\n $activities = $activities->filter(function (Activity $activity) {\n if ($activity->is_internal && empty($activity->actual_start_time)) {\n return false;\n }\n\n return true;\n });\n }\n\n $this->debugLog($user, 'Internal meetings (?!) filtered');\n\n $this->response->getManager()\n ->parseIncludes([\n 'category',\n 'organizer.group',\n 'prospect',\n 'stage',\n 'opportunity',\n 'stats',\n 'scorecards',\n 'masterTrack',\n 'activeParticipants',\n 'notification',\n ])\n ->setSerializer(new JsonSerializer());\n\n $transformerExcludes = $this->request->input('exclude');\n if ($transformerExcludes) {\n $this->response->getManager()->parseExcludes($transformerExcludes);\n }\n\n $this->debugLog($user, 'Response Manager (?!) applied');\n\n $transformer = new ActivityTransformer();\n $transformer->setConsumer($user);\n\n $this->debugLog($user, 'Activity Transformer added');\n\n $resource = new \\League\\Fractal\\Resource\\Collection($activities, $transformer);\n $page = $searchCriteria->getPageNumber();\n\n $this->debugLog($user, 'Search criteria page number called', ['page' => $page]);\n\n $histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');\n\n $this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);\n\n return $this->response->withArray([\n 'pagination' => [\n 'total' => $searchResponse['totalHits'],\n 'current' => $page,\n 'prev' => max($page - 1, 1),\n 'next' => $page + 1,\n ],\n 'results' => $this->response->getManager()->createData($resource)->toArray(),\n 'histogram' => $histogram,\n ]);\n }\n\n private function debugLog(User $user, string $logMessage, ?array $context = []): void\n {\n // Debug for Learning People Only\n if ($user->getTeamId() !== 260) {\n return;\n }\n\n Log::notice(\n sprintf('[activity-search-controller] %s', $logMessage),\n $context\n );\n }\n\n /** @throws ValidationException */\n private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void\n {\n $rules = [\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ];\n\n if ($prefix !== null && mb_strpos($prefix, '.') !== false) {\n $rules[rtrim($prefix, '.')] = sprintf(\n 'required|array|max:%d',\n $filterSet->count()\n );\n }\n\n $validationRules = $filterSet->getValidationRules($prefix)\n ->merge($rules)\n ->all();\n\n $request->validate($validationRules);\n }\n\n public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $search = $this->updateOrCreateActivitySearch($request);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function updateActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('update', $search);\n\n $this->updateOrCreateActivitySearch($request, $search);\n\n return $this->response->withOk();\n }\n\n private function storeNamedSearchFilters(\n Collection $request,\n Search $search,\n FilterDefinitionCollection $filterSet,\n ?string $prefix = null,\n ): self {\n $arrayTypeProperties = $filterSet\n ->getPropertyTypes([\n FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,\n ])\n ->all();\n\n $supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);\n\n foreach ($supportedRequestProperties as $requestPropertyName) {\n if (! array_has($request, $requestPropertyName)) {\n continue;\n }\n\n /** @var string|string[] $propertyValue */\n $propertyValue = array_get($request, $requestPropertyName);\n $propertyName = $prefix === null\n ? $requestPropertyName\n : mb_substr($requestPropertyName, mb_strlen($prefix));\n\n $isArrayType = array_has($arrayTypeProperties, $propertyName);\n\n if (! $isArrayType) {\n /** @var string $requestPropertyValue */\n\n $search->filters()->updateOrCreate(\n [\n 'filter' => $propertyName,\n ],\n [\n 'value' => $propertyValue,\n ]\n );\n\n continue;\n }\n\n /** @var string[] $requestPropertyValue */\n\n /** @var SearchFilter[]|Collection $existingFilterValues */\n $existingFilterValuesKeyed = $search->filters()\n ->where('filter', $propertyName)\n ->get()\n ->keyBy('id');\n\n // Iterate over values provided as request parameters\n foreach ($propertyValue as $value) {\n /** @var SearchFilter|null $valueFilter */\n $valueFilter = $search->filters()\n ->where(\n [\n 'filter' => $propertyName,\n 'value' => $value,\n ]\n )\n ->first();\n\n if ($valueFilter !== null) {\n // Remove filter value pair from list to be deleted\n $existingFilterValuesKeyed->forget($valueFilter->id);\n } else {\n // Add new filter/value pair\n $search->filters()->updateOrCreate([\n 'filter' => $propertyName,\n 'value' => $value,\n ]);\n }\n }\n\n // Delete filter value pairs for this filter that no longer exist in request parameters\n foreach ($existingFilterValuesKeyed as $existingFilter) {\n $existingFilter->delete();\n }\n }\n\n /** @var Collection<int, SearchFilter> $filtersKeyed */\n $filtersKeyed = $search->filters()->get()->keyBy('filter');\n\n // wipe removed filters from this search\n foreach ($filtersKeyed as $filterName => $filter) {\n if (array_has($request, $prefix . $filterName)) {\n continue;\n }\n\n // Remove all filter values for this filter\n $search->filters()->where('filter', $filterName)->delete();\n }\n\n return $this;\n }\n\n /**\n * @throws AuthorizationException\n */\n public function fetchActivitySearch(\n Search $search,\n Request $request,\n SearchTransformer $searchTransformer,\n ): JsonResponse {\n $this->authorize('view', $search);\n\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection(\n $user->searches()->get(),\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n /**\n * Deletes a saved search\n *\n * @param Request $request\n * @param Search $search\n *\n * @throws Exception\n *\n * @return JsonResponse\n */\n public function deleteActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('delete', $search);\n\n // Orphan any AutomatedReports that use this search\n $search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);\n\n // Delete filters and the search itself\n $search->filters()->delete();\n $search->delete();\n\n return $this->response->withOk();\n }\n\n public function live(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n $user = $this->getUserFromRequest($request);\n\n $this->request->validate([\n 'sort_direction' => 'in:asc,desc',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ]);\n\n $activities = $repository->getLiveCoachingEligibleActivities(\n user: $user,\n lookBackMinutes: self::LOOK_BACK,\n limit: (int) $this->request->input('limit', 25),\n page: (int) $this->request->input('page', 1),\n sortBy: ['actual_start_time', 'scheduled_start_time'],\n sortDirection: (string) $this->request->input('sort_direction', 'asc'),\n );\n\n $this->response\n ->getManager()\n ->parseIncludes(['organizer.group', 'prospect'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($activities, new ActivityTransformer());\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function show(Activity $activity, ActivityService $activityService): JsonResponse\n {\n $this->authorize('show', $activity);\n\n $user = $activity->getUser();\n $team = $user->getTeam();\n\n // Sync the opportunity with the latest data if possible.\n if ($activity->opportunity_id) {\n try {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n if (! $user->isCrmRequired()) {\n $crmService->setUser($team->getOwner());\n } else {\n $crmService->setUser($user);\n }\n\n $crmService->syncOpportunity($activity->opportunity->crm_provider_id);\n } catch (Exception $exception) {\n // Move on.\n }\n }\n\n $activityData = $activityService->getActivityData($this->request->user(), $activity);\n\n return response()->json($activityData);\n }\n\n public function createRecording(Activity $activity)\n {\n $this->authorize('record', $activity);\n\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Tell Twilio to start recording this activity.\n if ($activity->recording_state === Activity::RECORDING_OFF) {\n $job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withCreated();\n }\n\n return $this->response->errorGone('Activity is already recording.');\n }\n\n public function updateRecording(Request $request, Activity $activity)\n {\n $this->authorize('record', $activity);\n\n $request->validate([\n 'preference' => 'boolean',\n 'state' => [\n 'string',\n Rule::in([\n Activity::RECORDING_IN_PROGRESS,\n Activity::RECORDING_PAUSED,\n ]),\n ],\n ]);\n\n if ($request->has('state')) {\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Toggle the recording state between paused and resumed.\n if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {\n $job = (new ToggleRecording($activity, $request->input('state')))\n ->onQueue(Constants::QUEUE_CONFERENCES);\n\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Recording is not toggleable.');\n }\n\n if ($request->has('preference')) {\n $activity->update([\n 'recording_preference' => $request->input('preference') ? 1 : 0,\n ]);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorWrongArgs('Something went wrong');\n }\n\n public function stopRecording(Activity $activity)\n {\n $this->authorize('stopRecord', $activity);\n\n // Tell Twilio to stop recording this activity.\n if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {\n $job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Activity is not recording.');\n }\n\n /**\n * Add activity to this user's favorites playlist\n *\n * @throws AuthorizationException\n */\n public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse\n {\n $this->authorize('favorite', $activity);\n\n $user = $this->getUserFromRequest($this->request);\n $favorite = $activity->wasFavoritedBy($user);\n $name = $activity->activity_title ?? '';\n\n // It needs to check at least one record.\n if (! $favorite) {\n $favoritePlaylist = $user->favoritePlaylist();\n\n $playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(\n $activity,\n $user,\n $favoritePlaylist\n );\n\n if ($playlistActivity !== null) {\n $playlistActivity->update(\n // Just update, don't sort.\n ['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],\n );\n } else {\n $playlistActivity = $activity->playlistActivities()->create([\n 'playlist_id' => $favoritePlaylist->getId(),\n 'user_id' => $user->getId(),\n 'start_time' => 0,\n 'name' => mb_strimwidth($name, 0, 100),\n ]);\n // Sort it on top.\n $playlistActivity->update(\n [\n 'sort' => $playlistActivityRepository->calculateNewSortOrder(\n null,\n $playlistActivity,\n ),\n ],\n );\n }\n\n $playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);\n\n return new JsonResponse([], JsonResponse::HTTP_CREATED);\n }\n\n return new JsonResponse(\n [\n 'error' => [\n 'code' => AbstractResponse::CODE_CONFLICT,\n 'http_code' => JsonResponse::HTTP_CONFLICT,\n 'message' => 'Resource Already Exists',\n ],\n ],\n JsonResponse::HTTP_CONFLICT,\n );\n }\n\n /**\n * Remove activity from this user's favorites playlist\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unfavorite(Activity $activity)\n {\n $user = $this->request->user();\n\n $favorites = $activity->favoritedBy($user);\n\n if ($favorites && $favorites->isEmpty()) {\n return $this->response->errorNotFound('Favorite not found.');\n }\n\n $this->authorize('unfavorite', [$activity, $favorites]);\n\n // When you unfavorite an activity,\n // it should remove all the activities in it, including snippets.\n $isDeleted = $favorites->each(function ($favorite) {\n $favorite->forceDelete();\n });\n\n if ($isDeleted) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not remove favorite.');\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function notify(Activity $activity)\n {\n $this->authorize('notify', $activity);\n\n $user = $this->request->user();\n\n $existingNotification = $activity->availabilityNotifications()\n ->where('user_id', $user->id)\n ->exists();\n\n if ($existingNotification) {\n return $this->response->errorWrongArgs('Notification is already configured.');\n }\n\n $notification = Activity\\AvailabilityNotification::create([\n 'user_id' => $user->id,\n 'activity_id' => $activity->id,\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($notification, new AvailabilityNotificationTransformer());\n }\n\n /**\n * @param Activity $activity\n * @param Activity\\AvailabilityNotification $notification\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unnotify(Activity $activity, Activity\\AvailabilityNotification $notification)\n {\n $this->authorize('unnotify', [$activity, $notification]);\n\n if ($notification->sent_at || $notification->delete()) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not delete notification.');\n }\n\n public function play(Request $request, Activity $activity)\n {\n $this->authorize('stream', $activity);\n\n $request->validate([\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $activity->plays()->create([\n 'user_id' => $user->getId(),\n 'start_time' => $request->input('start_time'),\n ]);\n\n return $this->response->withCreated();\n }\n\n /**\n * @param Activity $activity\n *\n * @return mixed\n */\n public function comment(Activity $activity)\n {\n return $this->newComment($activity);\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @return mixed\n */\n public function replyComment(Activity $activity, Comment $comment)\n {\n return $this->newComment($activity, $comment);\n }\n\n /**\n * @param Activity $activity\n * @param Comment|null $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n protected function newComment(Activity $activity, ?Comment $comment = null)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n 'type' => 'integer|between:0,3',\n 'visibility' => sprintf('nullable|integer|between:1,%d', count(Comment::getVisibilityLevels())),\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n $threadStartId = null;\n if ($comment) {\n $threadStartId = $comment->thread_start_id ?: $comment->id;\n }\n\n try {\n $newComment = Comment::create([\n 'parent_comment_id' => $comment->id ?? null,\n 'thread_start_id' => $threadStartId,\n 'activity_id' => $activity->id,\n 'user_id' => $this->request->user()->id,\n 'comment' => trim($this->request->input('comment')),\n 'start_time' => $this->request->input('start_time', 0),\n 'end_time' => $this->request->input('end_time', 0),\n 'type' => $this->request->input('type', Comment::TYPE_NEUTRAL),\n 'visibility' => $this->request->input('visibility', Comment::VISIBILITY_PUBLIC),\n ]);\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($newComment, new ActivityCommentTransformer());\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not create comment.' . $exception->getMessage());\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function updateComment(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n try {\n $comment->update([\n 'comment' => trim($this->request->input('comment')),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment.');\n }\n }\n\n public function updateCommentVisibility(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'visibility' => sprintf('integer|between:1,%d', count(Comment::getVisibilityLevels())),\n ]);\n\n $visibility = $this->request->input('visibility');\n\n if ($comment->parent !== null) {\n return $this->response->errorWrongArgs('Comment visibility can only be updated on top level comments.');\n }\n\n try {\n $this->activityCommentService->updateCommentVisibility($comment, $visibility);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment\\'s visibility.');\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function deleteComment(Activity $activity, Comment $comment)\n {\n $this->authorize('deleteComment', [$activity, $comment]);\n\n // Delete comment and any children.\n $comment->delete();\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function fetchComments()\n {\n $user = $this->request->user();\n $this->request->validate([\n 'forUserId' => 'uuid:users,team_id,' . $user->team_id,\n 'types' => 'array',\n 'types.*' => 'integer|between:0,3',\n ]);\n $forUser = null;\n\n $types = [Comment::TYPE_NEUTRAL, Comment::TYPE_GAME_CHANGER, Comment::TYPE_POSITIVE];\n $user = $this->request->user();\n if ($this->request->has('forUserId')) {\n $forUser = $user->team->users()->uuid($this->request->input('forUserId'));\n }\n\n $comments = Comment::query()\n ->whereHas('activity', static function (Builder $builder) use ($user, $forUser): void {\n $builder\n // I left feedback on my own activity; or\n ->where('activities.user_id', $user->getId());\n if ($forUser) {\n // I left feedback on any activity for this user.\n $builder->orWhere([\n 'user_id' => $user->getId(),\n 'activities.user_id' => $forUser->getId(),\n ]);\n }\n })\n ->whereIn('type', $this->request->input('types', $types))\n ->orderBy('created_at', 'desc')\n ->get();\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity', 'user'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($comments, new ActivityCommentTransformer());\n }\n\n public function deleteCoachingFeedback(Activity $activity, CoachingFeedback $coachingFeedback)\n {\n $this->authorize('deleteCoachingFeedback', [$activity, $coachingFeedback]);\n $activity = $coachingFeedback->getActivity();\n\n if ($coachingFeedback->delete()) {\n event(new UpdateSingleEntity(\n entityId: $activity->getId(),\n updateTarget: UpdateTargetEnum::ACTIVITY,\n purpose: 'delete-coaching-feedback',\n ));\n\n return $this->response->withOk();\n }\n\n return $this->response->withError('Delete operation failed. Contact support.', 500);\n }\n\n /**\n * Add new or update Coaching feedback\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws \\Illuminate\\Validation\\ValidationException\n *\n * @return mixed\n */\n public function putCoachingFeedback(Request $request, Activity $activity)\n {\n $user = $request->user();\n\n if (! $user instanceof User) {\n abort(403);\n }\n $teamId = $user->getTeamId();\n\n $this->authorize('coach', $activity);\n\n $this->request->validate([\n 'coach_id' => 'required|uuid:users,team_id,' . $teamId,\n 'coachee_id' => 'required|uuid:users,team_id,' . $teamId,\n 'visibility' => ['required', Rule::in(CoachingFeedback::VISIBILITIES)],\n 'coaching_sections.*.uuid' => 'required|uuid:coaching_sections',\n 'coaching_sections.*.score' => ['required', Rule::in(CoachingSectionFeedback::SCORES)],\n 'coaching_sections.*.summary' => 'string|max:10000',\n 'coaching_sections.*.criteria.*.uuid' => 'required|uuid:coaching_section_criteria',\n 'coaching_sections.*.criteria.*.note' => 'required|string|max:10000',\n 'sharedWithUsers' => [\n 'required_if:visibility,' . CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS,\n 'array',\n ],\n 'sharedWithUsers.*' => [\n 'uuid:users,team_id,' . $teamId,\n ],\n ]);\n\n /** @var User $coach */\n $coach = User::uuid($this->request->input('coach_id'));\n /** @var User $coachee */\n $coachee = User::uuid($this->request->input('coachee_id'));\n $coachingSectionFeedbacks = $this->request->input('coaching_sections');\n\n $previousRecord = $this->coachingFeedbackRepository->getOneForActivityByCoacheeAndCoach(\n $coachee->getId(),\n $coach->getId(),\n $activity->getId()\n );\n $recordIsNew = false;\n if ($previousRecord === null) {\n $recordIsNew = true;\n }\n\n if (! $coachee->isSameTeamId($coach)) {\n return $this->response->errorForbidden('User not member of your team.');\n }\n\n if (! is_array($coachingSectionFeedbacks) || count($coachingSectionFeedbacks) < 1) {\n return $this->response->withError('At least one Coaching Framework Section shall be scored.', 422);\n }\n\n if (! $activity->participants()->where('participants.user_id', $coachee->id)->exists()) {\n return $this->response->withError('Coached user did not participate activity.', 422);\n }\n\n $visibility = $this->request->input('visibility');\n\n $shouldSendNotification = $recordIsNew;\n if ($recordIsNew === false && $visibility !== $previousRecord->getVisibility()) {\n $shouldSendNotification = true;\n }\n\n /**\n * Create CoachingFeedback\n *\n * @var CoachingFeedback $coachingFeedback\n */\n $coachingFeedback = $activity->coachingFeedbacks()->updateOrCreate(\n [\n 'coach_id' => $coach->id,\n 'coachee_id' => $coachee->id,\n ],\n [\n 'framework_id' => $activity->category->id,\n 'visibility' => $visibility,\n ]\n );\n\n $sharedUserIds = [];\n if ($visibility === CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS) {\n foreach ($this->request->input('sharedWithUsers') as $sharedWithUserUuid) {\n /** @var User $user */\n $user = User::uuid($sharedWithUserUuid);\n $sharedUserIds[] = $user->getId();\n }\n }\n\n $syncResult = $coachingFeedback->customAccessUsers()->sync($sharedUserIds);\n\n $scores = [];\n\n\n /**\n * Create CoachingSectionsFeedbacks.\n *\n * @var CoachingSectionFeedback $coachingSectionFeedback\n */\n foreach ($coachingSectionFeedbacks as $coachingSectionFeedbackInput) {\n $coachingSection = CoachingSection::uuid($coachingSectionFeedbackInput['uuid']);\n $coachingSectionFeedback = $coachingFeedback->sectionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_id' => $coachingSection->id,\n ],\n [\n 'score' => array_get($coachingSectionFeedbackInput, 'score'),\n 'summary' => array_get($coachingSectionFeedbackInput, 'summary') ?? '',\n ]\n );\n\n $scores[] = array_get($coachingSectionFeedbackInput, 'score');\n\n $criteria = array_get($coachingSectionFeedbackInput, 'criteria');\n if (is_array($criteria) && ! empty($criteria)) {\n foreach ($criteria as $criteriaFeedbackInput) {\n $coachingSectionFeedback->criterionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_criterion_id' => CoachingSectionCriterion::uuid(array_get($criteriaFeedbackInput, 'uuid'))\n ->id,\n ],\n ['note' => array_get($criteriaFeedbackInput, 'note')],\n );\n }\n }\n }\n\n $coachingFeedback->average_score = array_sum($scores) / count($scores);\n\n if ($recordIsNew === false && $coachingFeedback->getAverageScore() !== $previousRecord->getAverageScore()) {\n $shouldSendNotification = true;\n }\n if (! empty($syncResult['attached']) || ! empty($syncResult['detached']) || ! empty($syncResult['updated'])) {\n $shouldSendNotification = true;\n }\n\n $coachingFeedback->save();\n // ensure updated at for coaching feedback on section feedback summary added.\n $coachingFeedback->touch();\n\n if ($shouldSendNotification) {\n event(new Coached($coachingFeedback));\n }\n\n Datadog::increment('jiminny.activity.score.update', 1, ['company' => $activity->user->team->slug]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n $coachingFeedbackTransformer = new CoachingFeedbackTransformer();\n $coachingFeedbackTransformer->setConsumer($this->getUserFromRequest($request));\n\n return $this->response->withItem($coachingFeedback, $coachingFeedbackTransformer);\n }\n\n\n /**\n * Retrieve category criteria for coaching.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachingSections(Activity $activity)\n {\n $this->authorize('coach', $activity);\n\n if ($activity->category === null) {\n return $this->response->errorUnprocessable('Category has not yet been assigned.');\n }\n\n $criteria = $activity\n ->category\n ->coachingSections()\n ->where('is_enabled', 1)\n ->orderBy('sequence', 'asc');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($criteria->get(), new CoachingSectionsTransformer());\n }\n\n /**\n * @throws AuthorizationException\n * @throws ValidationException\n *\n * @return mixed\n */\n public function addToPlaylist(Activity $activity, PlaylistTrackFactoryInterface $playlistTrackFactory)\n {\n $this->request->validate([\n 'playlists' => 'required|array',\n 'playlists.*' => 'uuid:playlists',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'name' => 'required|max:100',\n ]);\n\n $this->authorize('addToPlaylist', [$activity, $this->request->input('playlists')]);\n\n $startTime = $this->request->input('start_time');\n $endTime = $this->request->input('end_time');\n $name = $this->request->input('name');\n /** @var User $user */\n $user = $this->request->user();\n\n // Get playlist by uuid.\n foreach ($this->request->input('playlists') as $playlistId) {\n // Pull out the playlist model.\n $playlist = Playlist::uuid($playlistId);\n\n $playlistTrackFactory->createTrack($playlist, $user, [\n 'name' => $name,\n 'activity' => $activity,\n 'start_time' => $startTime,\n 'end_time' => $endTime,\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function share(Request $request, Activity $activity): JsonResponse\n {\n $this->authorize('share', $activity);\n\n $request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'recipients.*.type' => 'in:user,group',\n 'recipients.*.id' => 'string|max:40',\n 'share' => 'string|max:255',\n ]);\n\n $user = $request->user();\n\n $recipients = $request->get('recipients');\n $users = $this->userService->convertRecipientsToUsers($user, $recipients);\n\n $shareData = [\n 'from_user_id' => $user->id,\n 'note' => $request->input('note'),\n 'start_time' => $request->input('start_time'),\n 'end_time' => $request->input('end_time'),\n ];\n\n // Create a share object against a notification provider channel\n if ($request->input('share')) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'notification_provider_channel' => $request->input('share'),\n ]\n )\n );\n\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n\n // Create a share object against each recipient\n foreach ($users as $recipient) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'to_user_id' => $recipient->id,\n ]\n )\n );\n\n // If parent_share_id has been selected yet\n if (! isset($shareData['parent_share_id'])) {\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachRequest(Activity $activity)\n {\n $this->authorize('coachRequest', $activity);\n\n $this->request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'coachers.*.type' => 'required|in:user',\n 'coachers.*.id' => 'required',\n ]);\n\n $coachers = $this->request->get('coachers');\n $user = $this->request->user();\n $users = $this->userService->convertRecipientsToUsers($user, $coachers);\n\n foreach ($users as $coacher) {\n CoachRequest::create([\n 'user_id' => $coacher->id,\n 'activity_id' => $activity->id,\n 'note' => $this->request->get('note'),\n 'start_time' => $this->request->get('start_time'),\n 'end_time' => $this->request->get('end_time'),\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function createActivityTopicTriggers(Activity $activity, LoggerInterface $logger): HttpFoundation\\JsonResponse\n {\n $this->authorize('analyzeTopicTriggers', $activity);\n\n if (! $activity->hasTranscription()) {\n return new HttpFoundation\\JsonResponse(\n [\n 'error' => 'Transcription not found.',\n ],\n JsonResponse::HTTP_NOT_FOUND\n );\n }\n\n $logger->info(__METHOD__ . ': queued for analysis', [\n 'activity' => $activity->id_string,\n ]);\n\n dispatch(new ActivityAnalytics\\Job\\AnalyzeActivityTopicTriggers($activity));\n\n return new HttpFoundation\\JsonResponse(null, JsonResponse::HTTP_CREATED);\n }\n\n public function fetchActivityTopicTriggers(\n Activity $activity,\n LoggerInterface $logger,\n ActivityTopicTriggerTransformer $transformer\n ): HttpFoundation\\JsonResponse {\n $this->authorize('fetchTopicTriggers', $activity);\n\n $logger->debug(__METHOD__, [\n 'activity' => $activity->id_string,\n ]);\n\n if (! $activity->isProcessed()) {\n return new HttpFoundation\\JsonResponse([]);\n }\n\n $payload = [];\n\n if ($activity->hasTopicTriggers()) {\n $payload = $activity->getTopicTriggersSorted()\n ->map(\n static fn (Activity\\TopicTrigger $activityTopicTrigger): array\n => $transformer->transform($activityTopicTrigger)\n )\n ->values()\n ->all();\n }\n\n return new HttpFoundation\\JsonResponse($payload);\n }\n\n /**\n * @param Activity $activity\n * @param StatsTransformer $statsTransformer\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function stats(Activity $activity, StatsTransformer $statsTransformer)\n {\n $this->authorize('stream', $activity);\n\n if (! $activity->hasTranscription()) {\n return $this->response->errorNotFound('Waveform data is not yet generated.');\n }\n\n $this->response\n ->getManager()\n ->parseIncludes(['wavedata'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($activity, $statsTransformer);\n }\n\n public function destroy(Activity $activity)\n {\n $this->authorize('delete', $activity);\n\n $activity->delete();\n\n \\Log::info('Soft delete activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n\n return $this->response->withNoContent();\n }\n\n public function note(Activity $activity)\n {\n $this->authorize('note', $activity);\n\n $this->request->validate([\n 'note' => 'required|min:1|max:2000',\n 'time' => 'required|numeric|min:0|max:86400',\n ]);\n\n $note = $this->request->input('note');\n $time = $this->request->input('time');\n\n $this->activityService->setActivity($activity);\n $this->activityService->takeNote($this->getUser(), $note, $time);\n\n return $this->response->withCreated();\n }\n\n /**\n * Mark an activity as private.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPrivate(Activity $activity)\n {\n $this->authorize('markAsPrivate', $activity);\n\n if ($activity->is_private === false) {\n $activity->is_private = true;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * Mark an activity as public.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPublic(Activity $activity)\n {\n $this->authorize('markAsPublic', $activity);\n\n if ($activity->is_private) {\n $activity->is_private = false;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws LogicException\n */\n public function fetchCloudFrontS3MediaKeys(Activity $activity, PlaybackService $playbackService): JsonResponse\n {\n $masterTrack = $activity->masterTrack()->first();\n\n if (! $masterTrack instanceof Track) {\n throw new LogicException(sprintf('Master track not found for activity \"%s\"', $activity->getUuid()));\n }\n\n return $this->response->withArray(\n $playbackService->generateCookies(\n $masterTrack,\n $this->request->ip(),\n ),\n );\n }\n\n /**\n * @throws ValidationException\n */\n private function updateOrCreateActivitySearch(Request $request, ?Search $search = null): Search\n {\n $request->validate([\n 'name' => 'required|string|min:2|max:100',\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $searchName = $request->input('name');\n\n if ($search !== null) {\n $search->update([\n 'name' => $searchName,\n ]);\n\n return $search;\n }\n\n $request->validate([\n 'filters' => ['required', 'array', new MultidimensionalArrayMaxCharRule(limit: 255)],\n 'nudges' => 'array|max:' . count(Nudge::MAP_CHANNEL),\n 'nudges.*.channel' => 'required|in:' . implode(',', Nudge::MAP_CHANNEL),\n 'nudges.*.frequency' => 'required|in:' . implode(',', Nudge::MAP_FREQUENCY),\n 'nudges.*.expiresAt' => [\n 'required',\n 'date',\n 'after:today',\n 'before_or_equal:' . now()->addYear()->format('Y-m-d'),\n ],\n ]);\n\n $searchCriteria = Criteria::createFromRequest(\n Collection::make($request->input('filters', []))->all(),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($searchCriteria, $user);\n $this->validateSearch($request, $filterSet, 'filters.');\n\n /** @var Search $search */\n $search = Search::create([\n 'name' => $searchName,\n 'uuid' => Uuid::uuid4()->toString(),\n 'user_id' => $user->getId(),\n ]);\n\n Collection::make($request->input('nudges', []))\n ->each(fn (array $attributes): Nudge => $this->nudgeFactory->createNudge($search, $attributes));\n\n $this->storeNamedSearchFilters(Collection::make($request->all()), $search, $filterSet, 'filters.');\n\n return $search;\n }\n\n private function resolveAccount(\n Team $team,\n Contact $contact,\n ServiceInterface $crmService,\n array $prospects,\n ): ?Account {\n $this->logger->info('Resolving account from contact');\n $account = $contact->getAccount();\n\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS)) {\n $this->logger->info('Team does not have feature to link activity to multiple prospects');\n\n return $account;\n }\n\n $this->logger->info('Resolving account from prospect data');\n $accountData = array_filter(\n $prospects,\n static fn (array $prospectData): bool => $prospectData['type'] === 'account'\n );\n\n if (! empty($accountData)) {\n $this->logger->info('Found account data in prospects');\n $accountData = reset($accountData);\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountData['id'])->first();\n\n if (! $account instanceof Account) {\n $this->logger->info('Account not found in database, syncing from CRM');\n $account = $crmService->syncAccount($accountData['id']);\n }\n }\n\n $this->logger->info('Resolved account', ['account' => $account->getId()]);\n\n return $account;\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.40957448,"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.41821808,"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.42918882,"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.43783244,"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.44647607,"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.4574468,"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.46841756,"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.4950133,"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.50598407,"top":0.09896249,"width":0.029587766,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"bounds":{"left":0.7084442,"top":0.09896249,"width":0.02825798,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"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":"40","depth":4,"bounds":{"left":0.67785907,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.69015956,"top":0.123703115,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"40","depth":4,"bounds":{"left":0.6994681,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"64","depth":4,"bounds":{"left":0.7117686,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.7237367,"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.73105055,"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 * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","depth":4,"on_screen":true,"value":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","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}]...
|
-7287184300264252456
|
-8385861013499833196
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use Carbon\Carbon;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\In;
use Illuminate\Validation\ValidationException;
use InvalidArgumentException;
use Jiminny\Component\ActivityAnalytics;
use Jiminny\Component\ActivitySearch;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Queue\Constants;
use Jiminny\Contracts\ES\Events\UpdateSingleEntity;
use Jiminny\Contracts\ES\UpdateTargetEnum;
use Jiminny\Contracts\Nudge\NudgeFactoryInterface;
use Jiminny\Contracts\Playlist\PlaylistTrackFactoryInterface;
use Jiminny\Contracts\Repositories\PlaylistActivityRepository;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Enums\TeamSetting;
use Jiminny\Events\Activities\AiAutomation\ActivityProspectAdded;
use Jiminny\Events\Activities\Coaching\Coached;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Controllers\CommentContextInterface;
use Jiminny\Http\Responses\Api\AbstractResponse;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\ActivityCommentTransformer;
use Jiminny\Http\Transformers\ActivityTopicTriggerTransformer;
use Jiminny\Http\Transformers\ActivityTransformer;
use Jiminny\Http\Transformers\AvailabilityNotificationTransformer;
use Jiminny\Http\Transformers\CoachingFeedbackTransformer;
use Jiminny\Http\Transformers\CoachingSectionsTransformer;
use Jiminny\Http\Transformers\SearchTransformer;
use Jiminny\Http\Transformers\StatsTransformer;
use Jiminny\Jobs\Crm\SaveActivity;
use Jiminny\Jobs\Crm\UpdateStage;
use Jiminny\Jobs\Telephony\StartRecording;
use Jiminny\Jobs\Telephony\StopRecording;
use Jiminny\Jobs\Telephony\ToggleRecording;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\CoachingFeedback;
use Jiminny\Models\CoachingSection;
use Jiminny\Models\CoachingSectionCriterion;
use Jiminny\Models\CoachingSectionFeedback;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\LanguageDialect;
use Jiminny\Models\Lead;
use Jiminny\Models\Nudge;
use Jiminny\Models\PlaybookCategory;
use Jiminny\Models\Playlist;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\Track;
use Jiminny\Models\User;
use Jiminny\Repositories\CoachingFeedbackRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Rules\CrmReference;
use Jiminny\Rules\MultidimensionalArrayMaxCharRule;
use Jiminny\Services\ActivityService;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Services\PlaybackService;
use Jiminny\Services\UserService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
use Ramsey\Uuid\Uuid;
use Sentry;
use Symfony\Component\HttpFoundation;
final class ActivityController extends Controller implements CommentContextInterface
{
// Number of minutes to look back on activities. i.e. a timeout on activity duration.
private const int LOOK_BACK = 180;
public function __construct(
private ProviderRegistry $providerRegistry,
private ActivityService $activityService,
Response $response,
private UserService $userService,
private ActivitySearch\Service\ActivitySearch $activitySearch,
private NudgeFactoryInterface $nudgeFactory,
private ActivityCommentService $activityCommentService,
private LoggerInterface $logger,
private readonly CoachingFeedbackRepository $coachingFeedbackRepository,
private readonly TeamRepository $teamRepository,
) {
parent::__construct($response);
}
public static function getCommentImplementation(): string
{
return Comment::class;
}
public function delete()
{
$this->request->validate([
'*' => 'uuid:activities',
]);
$deletedIds = [];
foreach ($this->request->all() as $activityId) {
$activity = Activity::idOrUuId($activityId);
try {
if ($this->authorize('delete', $activity)) {
$activity->delete();
$deletedIds[] = $activityId;
\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);
}
} catch (AuthorizationException $authorizationException) {
// They didn't have permission.
}
}
return $this->response->withArray($deletedIds);
}
public function update(Request $request, Activity $activity)
{
$this->authorize('updateMetadata', $activity);
$request->validate([
'title' => 'string|max:250',
'category_id' => 'uuid:playbook_categories',
'language' => [
new In(
LanguageDialect::query()
->with('language')
->cursor()
->map(static function (LanguageDialect $languageDialect): string {
return $languageDialect->getLanguageLocale();
})
->all()
),
],
]);
if ($request->has('title')) {
$activity->title = $request->input('title');
}
if ($request->has('category_id')) {
$category = PlaybookCategory::uuid($request->input('category_id'));
if ($category->playbook->team_id !== $request->user()->team_id) {
return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
if ($request->has('language')) {
if (! $activity->isInProgress()) {
return $this->response->withError(
'Activity language can only be set while the meeting is in progress.',
400
);
}
$activity->setLanguageCode($request->input('language'));
}
$activity->save();
return $this->response->withOk();
}
// XXX: This should be merged with the update method.
/**
* @param Activity $activity
*
* @throws AuthorizationException
* @throws SocialAccountTokenInvalidException
*
* @return mixed
*/
public function summarize(Activity $activity): mixed
{
$this->logger->info('[Log Activity] Summarizing activity ', [
'activityId' => $activity->getUuid(),
'payload' => $this->request->all(),
]);
$this->authorize('update', $activity);
$this->logger->info('[Log Activity] Validating summary');
// Validate the payload.
$this->validateSummary($activity);
// All objects must belong to this team.
/** @var User $user */
$user = $this->request->user();
$team = $user->getTeam();
$crmService = $this->providerRegistry->get($team->crm->provider);
try {
$crmUser = $user;
if ($user->isCrmRequired() === false) {
$crmUser = $team->owner;
}
$crmService->setUser($crmUser);
} catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());
}
$rawEntities = $this->request->input('entities');
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid(
$this->request->input('layout_id')
);
// Delay execution of CRM jobs to avoid locking issues.
$jobDelay = 0;
// If we have arrived from a notification, mark it as read.
$notificationId = $this->request->input('nId');
if ($notificationId) {
$notification = $user->unreadNotifications->where('id', $notificationId)->first();
if ($notification) {
$notification->markAsRead();
}
}
$title = $this->request->input('title');
$prospects = $this->request->input('prospects');
$opportunityId = $this->request->input('opportunity_id');
$stageId = $this->request->input('stage_id');
$categoryId = $this->request->input('category_id');
$summary = $this->request->input('summary');
$crmProviderId = $this->request->input('crm_id');
$isInternal = $this->request->input('is_internal') ?? false;
$lead = null;
$category = null;
$account = null;
$contact = null;
$opportunity = null;
$stage = null;
$callStage = null;
foreach ($prospects as $prospectData) {
$objectId = $prospectData['id'];
if ($objectId === null) {
continue;
}
$objectType = $prospectData['type'];
$this->logger->info('debug', ['prospect_data' => $prospectData]);
try {
if ($objectType === null) {
$this->logger->info('no object type');
if ($crmService instanceof SupportsObjectTypeParseInterface) {
$objectType = $crmService->parseObjectType($objectId);
}
}
switch ($objectType) {
case 'lead':
$this->logger->info('Processing lead');
/** @var Lead|null $lead */
$lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();
// Lead does not exist locally, import it.
if ($lead === null) {
$this->logger->info('Lead does not exist locally');
/** @var Lead $lead */
$lead = $crmService->syncLead($objectId);
}
$this->logger->info('Lead found', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
if ($stageId === null) {
$this->logger->info('Stage ID is null');
// If it was not provided, just assume it is the current stage.
$callStage = $lead->stage;
break;
}
$this->logger->info('Looking for stage');
// Determine if they have changed the stage.
/** @var Stage $stage */
$stage = $team->crm->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_LEAD)
->firstOrFail();
$this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);
if ($lead->stage_id && $lead->stage_id !== $stage->id) {
$this->logger->info('Stage has changed');
// Storage current stage on activity.
$callStage = $lead->stage;
// The stage has changed, update in remote CRM.
dispatch(new UpdateStage($activity, $lead, $callStage, $stage));
$this->logger->info(
sprintf(
'[%s] User changing lead stage from %s to %s',
$crmService->getDisplayName(),
$callStage->getName(),
$stage->getName()
),
[
'user' => $user->getUuid(),
'lead' => $lead->getUuid(),
]
);
} else {
$this->logger->info('Stage has not changed');
// Stage remains as current.
$callStage = $stage;
}
break;
case 'account':
$this->logger->info('Processing account');
// If the object is not a lead, it should be an account.
$account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();
// Account does not exist locally, import it.
if ($account === null) {
$this->logger->info('Account does not exist locally');
$account = $crmService->syncAccount($objectId);
}
$this->logger->info('Account found', ['accountId' => $account->id]);
break;
case 'contact':
$this->logger->info('processing contact');
$contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$this->logger->info('contact does not exist locally');
$contact = $crmService->syncContact($objectId);
}
$this->logger->info('resolving account');
$account = $this->resolveAccount($team, $contact, $crmService, $prospects);
break;
}
// If they have specified an opportunity, retrieve this with stage.
if ($opportunityId) {
$this->logger->info('opportunity id is set');
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if ($opportunity === null) {
$this->logger->info('opportunity does not exist locally');
$opportunity = $crmService->syncOpportunity($opportunityId);
}
if ($stageId === null) {
$this->logger->info('stage id is null');
// If it was not provided, just assume it is the current stage.
$callStage = $opportunity->stage ?? null;
} else {
$this->logger->info('looking for stage');
/** @var ?Stage $opportunityStage */
$opportunityStage = $team->crm
->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
// There is a chance we still cannot import this opportunity.
if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {
$this->logger->info('opportunity stage has changed');
// Storage current stage on activity.
$callStage = $opportunity->stage;
dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));
$this->logger->info(
sprintf(
'[%s] User changing opportunity stage from %s to %s',
$crmService->getDisplayName(),
$callStage->name,
$opportunityStage->name
),
[
'userId' => $user->id_string,
'opportunityId' => $opportunity->id_string,
]
);
} else {
$this->logger->info('opportunity stage has not changed');
// Stage remains as current.
$callStage = $opportunityStage;
}
}
}
if ($crmProviderId) {
// Cast $crmProviderId to string otherwise it won't use database index for some records
$linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();
// Check if this activity has already been assigned to a different activity.
if ($linkedActivity && $linkedActivity->id !== $activity->id) {
throw new InvalidArgumentException(
'Sorry, the linked task has already been logged under a different call. '
. 'Please choose another linked task.'
);
}
}
} catch (InvalidArgumentException $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($exception->getMessage());
} catch (Exception $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorInternalError(
'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'
);
}
}
if ($categoryId) {
$category = PlaybookCategory::uuid($categoryId);
if ($category->playbook->team_id !== $team->id) {
throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
$this->logger->info('Prospect data', [
'lead_id' => $lead?->getId(),
'account_id' => $account?->getId(),
'contact_id' => $contact?->getId(),
'opportunity_id' => $opportunity?->getId(),
'stage_id' => $stage?->getId(),
]);
if ($title) {
$activity->title = $title;
}
if ($summary) {
$activity->summary = $summary;
}
if ($crmProviderId) {
$activity->crm_provider_id = $crmProviderId;
}
if ($callStage) {
$this->logger->info('Setting stage id', ['stageId' => $callStage->id]);
$activity->stage_id = $callStage->id;
}
if ($lead) {
$this->logger->info('Setting lead id', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
// If we are changed from an account > lead, unset the account data.
$this->logger->info('Unsetting account id, opportunity id, contact id, value');
$activity->account_id = null;
$activity->opportunity_id = null;
$activity->contact_id = null;
$activity->value = null;
}
if ($account) {
$this->logger->info('Setting account id', ['accountId' => $account->id]);
$activity->account_id = $account->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('unsetting lead id');
$activity->lead_id = null;
// Unset the contact if switching different accounts. Will be set up below if still applicable.
if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {
$this->logger->info('Unsetting contact id');
$activity->contact_id = null;
}
}
if ($opportunity) {
$this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);
$this->logger->info('unsetting lead id');
$activity->opportunity_id = $opportunity->id;
$activity->value = $opportunity->value;
// If we are changed from an lead > account, unset the lead data.
$activity->lead_id = null;
}
if ($contact) {
$this->logger->info('setting contact id', ['contactId' => $contact->id]);
$activity->contact_id = $contact->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('Unsetting lead id');
$activity->lead_id = null;
}
$activity->is_internal = $isInternal;
$activity->save();
$activity->refresh();
$this->logger->notice('Activity saved', [
'activity_id' => $activity->getId(),
'lead_id' => $activity->lead_id,
'account_id' => $activity->account_id,
'contact_id' => $activity->contact_id,
'opportunity_id' => $activity->opportunity_id,
'stage_id' => $activity->stage_id,
'crm_provider_id' => $activity->getCrmProviderId(),
]);
// Store entities as field data on the activity.
$updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);
if ($activity->isLoggable()) {
// Follow-up Task or Event data.
$followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);
$this->logger->info('CRM LOG manual log triggered', [
'activityId' => $activity->getUuid(),
'followupData' => $followupData,
'userId' => $user->getUuid(),
]);
// Store data in the CRM.
// ++add check for crm_required
$job = new SaveActivity($activity, $followupData);
if ($updatedData) {
$job->delay(Carbon::now()->addMinutes($jobDelay));
}
dispatch($job);
// Manually dispatch log for Opportunity or Prospect added
if ($activity->hasOpportunity() || $activity->hasProspect()) {
event(new ActivityProspectAdded(
activity: $activity,
eventSource: 'manually-log-crm-data'
));
}
}
return $this->response->withOk();
}
/**
* Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.
*
* @param ServiceInterface $service
* @param Activity $activity
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array
{
$updatedData = [];
$existingData = $activity->data()->get();
// We need to delete any existing data to overwrite with latest values.
$activity->data()->delete();
$layoutEntities = $layout->entities()
->with('field', 'parent')
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->get();
/** @var LayoutEntity $entity */
foreach ($layoutEntities as $entity) {
// If the user has provided a value for this entity
if (array_key_exists($entity->id_string, $entities)) {
$value = $entities[$entity->id_string];
// Convert raw data into values that the CRM can consume.
if ($value) {
$value = $service->normalizeValue($entity->field->type, $value);
}
// Check the field is part of the activity-summary section.
if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {
// This is the internal database ID, not the external CRM ID.
$objectId = null;
switch ($entity->field->object_type) {
case Field::OBJECT_ACCOUNT:
$objectId = $activity->account_id;
break;
case Field::OBJECT_CONTACT:
$objectId = $activity->contact_id;
break;
case Field::OBJECT_OPPORTUNITY:
$objectId = $activity->opportunity_id;
break;
case Field::OBJECT_LEAD:
$objectId = $activity->lead_id;
break;
case Field::OBJECT_TASK:
case Field::OBJECT_EVENT:
$objectId = $activity->id;
break;
}
if ($objectId) {
/** @var FieldData $data */
$data = $activity->data()->create([
'crm_layout_entity_id' => $entity->id,
'crm_field_id' => $entity->crm_field_id,
'object_type' => $entity->field->object_type,
'object_id' => $objectId,
'value' => $value,
]);
// Never send read-only field data to the CRM.
if ($entity->read_only === false && $entity->is_visible) {
$existingValue = $existingData
->where('crm_layout_entity_id', $entity->id)
->where('crm_field_id', $entity->crm_field_id)
->where('object_type', $entity->field->object_type)
->where('object_id', $objectId)
->first();
// If the field was actually changed, we need to reflect this in the CRM too.
if ($existingValue === null || $existingValue->value !== $value) {
$updatedData[] = $data->id;
}
}
}
}
}
}
return $updatedData;
}
/**
* Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.
*
* @param ServiceInterface $crmService
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array
{
$fieldData = [];
foreach ($entities as $entityId => $value) {
// Only bother with fields that have a value.
if ($value) {
// Extract the entity from the UUID. Check the field is valid and part of the follow-up section.
$entity = $layout->entities()
->uuid($entityId, false)
->whereHas('parent', function ($query) {
$query->where('label', 'follow-up');
})
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->first();
if ($entity) {
// Convert raw data into values that the CRM can consume.
$value = $crmService->normalizeValue($entity->field->type, $value);
// Add the field and value to the payload.
$fieldData += [
$entity->field->crm_provider_id => $value,
];
}
}
}
return $fieldData;
}
/**
* @param Activity $activity
*/
private function validateSummary(Activity $activity): void
{
$team = $activity->user->team;
$crmProvider = $team->crm->provider;
$attributes = [];
$rules = [
'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,
'title' => 'string|max:250',
'prospects' => 'required|array',
'opportunity_id' => new CrmReference($crmProvider),
'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',
'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator
'summary' => 'max:50000',
'nId' => 'exists:notifications,id',
'crm_id' => new CrmReference($crmProvider),
'entities' => 'array',
'is_internal' => 'boolean',
];
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));
// Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.
$entities = $layout->entities()
->where('read_only', 0)
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->whereHas('parent', function ($query) use ($activity) {
if ($activity->isLoggable() === false) {
$query->where('label', '<>', 'follow-up');
}
});
$isInternal = $this->request->input('is_internal', false);
foreach ($entities->get() as $entity) {
$rules += $this->buildFieldValidator($entity, $isInternal);
$attributes += $this->buildFieldMessage($entity);
}
$this->request->validate($rules, [], $attributes);
}
private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array
{
return [
'entities.' . $entity->id_string => $entity->getValidator($isInternal),
];
}
/**
* @param LayoutEntity $entity
*
* @return array
*/
private function buildFieldMessage(LayoutEntity $entity): array
{
$label = $entity->label;
if ($label === null) {
$label = $entity->field->label;
}
return [
'entities.' . $entity->id_string => $label,
];
}
public function search(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->debugLog(
$user,
'User extracted from request',
['user' => $user->getId(), 'tz' => $user->getTimezone()]
);
$searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());
$this->debugLog(
$user,
'ActivitySearch criteria built',
['searchCriteria' => $searchCriteria]
);
$filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);
$this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);
$this->validateSearch($request, $filterSet);
$this->debugLog($user, 'Request validated');
$searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);
/** @var Collection<Activity> $activities */
$activities = $searchResponse['results'];
$this->debugLog($user, 'Activities ES response extracted');
$hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(
$user->getTeamId(),
TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),
);
if ($hideInternalMeetingsSetting?->getValue() === '1') {
$activities = $activities->filter(function (Activity $activity) {
if ($activity->is_internal && empty($activity->actual_start_time)) {
return false;
}
return true;
});
}
$this->debugLog($user, 'Internal meetings (?!) filtered');
$this->response->getManager()
->parseIncludes([
'category',
'organizer.group',
'prospect',
'stage',
'opportunity',
'stats',
'scorecards',
'masterTrack',
'activeParticipants',
'notification',
])
->setSerializer(new JsonSerializer());
$transformerExcludes = $this->request->input('exclude');
if ($transformerExcludes) {
$this->response->getManager()->parseExcludes($transformerExcludes);
}
$this->debugLog($user, 'Response Manager (?!) applied');
$transformer = new ActivityTransformer();
$transformer->setConsumer($user);
$this->debugLog($user, 'Activity Transformer added');
$resource = new \League\Fractal\Resource\Collection($activities, $transformer);
$page = $searchCriteria->getPageNumber();
$this->debugLog($user, 'Search criteria page number called', ['page' => $page]);
$histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');
$this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);
return $this->response->withArray([
'pagination' => [
'total' => $searchResponse['totalHits'],
'current' => $page,
'prev' => max($page - 1, 1),
'next' => $page + 1,
],
'results' => $this->response->getManager()->createData($resource)->toArray(),
'histogram' => $histogram,
]);
}
private function debugLog(User $user, string $logMessage, ?array $context = []): void
{
// Debug for Learning People Only
if ($user->getTeamId() !== 260) {
return;
}
Log::notice(
sprintf('[activity-search-controller] %s', $logMessage),
$context
);
}
/** @throws ValidationException */
private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void
{
$rules = [
'exclude' => 'array',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
];
if ($prefix !== null && mb_strpos($prefix, '.') !== false) {
$rules[rtrim($prefix, '.')] = sprintf(
'required|array|max:%d',
$filterSet->count()
);
}
$validationRules = $filterSet->getValidationRules($prefix)
->merge($rules)
->all();
$request->validate($validationRules);
}
public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$search = $this->updateOrCreateActivitySearch($request);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function updateActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('update', $search);
$this->updateOrCreateActivitySearch($request, $search);
return $this->response->withOk();
}
private function storeNamedSearchFilters(
Collection $request,
Search $search,
FilterDefinitionCollection $filterSet,
?string $prefix = null,
): self {
$arrayTypeProperties = $filterSet
->getPropertyTypes([
FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,
])
->all();
$supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);
foreach ($supportedRequestProperties as $requestPropertyName) {
if (! array_has($request, $requestPropertyName)) {
continue;
}
/** @var string|string[] $propertyValue */
$propertyValue = array_get($request, $requestPropertyName);
$propertyName = $prefix === null
? $requestPropertyName
: mb_substr($requestPropertyName, mb_strlen($prefix));
$isArrayType = array_has($arrayTypeProperties, $propertyName);
if (! $isArrayType) {
/** @var string $requestPropertyValue */
$search->filters()->updateOrCreate(
[
'filter' => $propertyName,
],
[
'value' => $propertyValue,
]
);
continue;
}
/** @var string[] $requestPropertyValue */
/** @var SearchFilter[]|Collection $existingFilterValues */
$existingFilterValuesKeyed = $search->filters()
->where('filter', $propertyName)
->get()
->keyBy('id');
// Iterate over values provided as request parameters
foreach ($propertyValue as $value) {
/** @var SearchFilter|null $valueFilter */
$valueFilter = $search->filters()
->where(
[
'filter' => $propertyName,
'value' => $value,
]
)
->first();
if ($valueFilter !== null) {
// Remove filter value pair from list to be deleted
$existingFilterValuesKeyed->forget($valueFilter->id);
} else {
// Add new filter/value pair
$search->filters()->updateOrCreate([
'filter' => $propertyName,
'value' => $value,
]);
}
}
// Delete filter value pairs for this filter that no longer exist in request parameters
foreach ($existingFilterValuesKeyed as $existingFilter) {
$existingFilter->delete();
}
}
/** @var Collection<int, SearchFilter> $filtersKeyed */
$filtersKeyed = $search->filters()->get()->keyBy('filter');
// wipe removed filters from this search
foreach ($filtersKeyed as $filterName => $filter) {
if (array_has($request, $prefix . $filterName)) {
continue;
}
// Remove all filter values for this filter
$search->filters()->where('filter', $filterName)->delete();
}
return $this;
}
/**
* @throws AuthorizationException
*/
public function fetchActivitySearch(
Search $search,
Request $request,
SearchTransformer $searchTransformer,
): JsonResponse {
$this->authorize('view', $search);
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withCollection(
$user->searches()->get(),
$searchTransformer
->withConsumer($user)
);
}
/**
* Deletes a saved search
*
* @param Request $request
* @param Search $search
*
* @throws Exception
*
* @return JsonResponse
*/
public function deleteActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('delete', $search);
// Orphan any AutomatedReports that use this search
$search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);
// Delete filters and the search itself
$search->filters()->delete();
$search->delete();
return $this->response->withOk();
}
public function live(Request $request, ElasticActivityRepository $repository): JsonResponse
{
$user = $this->getUserFromRequest($request);
$this->request->validate([
'sort_direction' => 'in:asc,desc',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
]);
$activities = $repository->getLiveCoachingEligibleActivities(
user: $user,
lookBackMinutes: self::LOOK_BACK,
limit: (int) $this->request->input('limit', 25),
page: (int) $this->request->input('page', 1),
sortBy: ['actual_start_time', 'scheduled_start_time'],
sortDirection: (string) $this->request->input('sort_direction', 'asc'),
);
$this->response
->getManager()
->parseIncludes(['organizer.group', 'prospect'])
->setSerializer(new JsonSerializer());
return $this->response->withCollection($activities, new ActivityTransformer());
}
/**
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function show(Activity $activity, ActivityService $activityService): JsonResponse
{
$this->authorize('show', $activity);
$user = $activity->getUser();
$team = $user->getTeam();
// Sync the opportunity with the latest data if possible.
if ($activity->opportunity_id) {
try {
$crmService = $this->providerRegistry->get($team->crm->provider);
if (! $user->isCrmRequired()) {
$crmService->setUser($team->getOwner());
} else {
$crmService->setUser($user);
}
$crmService->syncOpportunity($activity->opportunity->crm_provider_id);
} catch (Exception $exception) {
// Move on.
}
}
$activityData = $activityService->getActivityData($this->request->user(), $activity);
return response()->json($activityData);
}
public function createRecording(Activity $activity)
{
$this->authorize('record', $activity);
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Tell Twilio to start recording this activity.
if ($activity->recording_state === Activity::RECORDING_OFF) {
$job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withCreated();
}
return $this->response->errorGone('Activity is already recording.');
}
public function updateRecording(Request $request, Activity $activity)
{
$this->authorize('record', $activity);
$request->validate([
'preference' => 'boolean',
'state' => [
'string',
Rule::in([
Activity::RECORDING_IN_PROGRESS,
Activity::RECORDING_PAUSED,
]),
],
]);
if ($request->has('state')) {
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Toggle the recording state between paused and resumed.
if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {
$job = (new ToggleRecording($activity, $request->input('state')))
->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Recording is not toggleable.');
}
if ($request->has('preference')) {
$activity->update([
'recording_preference' => $request->input('preference') ? 1 : 0,
]);
return $this->response->withOk();
}
return $this->response->errorWrongArgs('Something went wrong');
}
public function stopRecording(Activity $activity)
{
$this->authorize('stopRecord', $activity);
// Tell Twilio to stop recording this activity.
if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {
$job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Activity is not recording.');
}
/**
* Add activity to this user's favorites playlist
*
* @throws AuthorizationException
*/
public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse
{
$this->authorize('favorite', $activity);
$user = $this->getUserFromRequest($this->request);
$favorite = $activity->wasFavoritedBy($user);
$name = $activity->activity_title ?? '';
// It needs to check at least one record.
if (! $favorite) {
$favoritePlaylist = $user->favoritePlaylist();
$playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(
$activity,
$user,
$favoritePlaylist
);
if ($playlistActivity !== null) {
$playlistActivity->update(
// Just update, don't sort.
['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],
);
} else {
$playlistActivity = $activity->playlistActivities()->create([
'playlist_id' => $favoritePlaylist->getId(),
'user_id' => $user->getId(),
'start_time' => 0,
'name' => mb_strimwidth($name, 0, 100),
]);
// Sort it on top.
$playlistActivity->update(
[
'sort' => $playlistActivityRepository->calculateNewSortOrder(
null,
$playlistActivity,
),
],
);
}
$playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);
return new JsonResponse([], JsonResponse::HTTP_CREATED);
}
return new JsonResponse(
[
'error' => [
'code' => AbstractResponse::CODE_CONFLICT,
'http_code' => JsonResponse::HTTP_CONFLICT,
'message' => 'Resource Already Exists',
],
],
JsonResponse::HTTP_CONFLICT,
);
}
/**
* Remove activity from this user's favorites playlist
*
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function unfavorite(Activity $activity)
{
$user = $t...
|
32845
|
NULL
|
NULL
|
NULL
|
|
32849
|
1254
|
24
|
2026-05-13T09:39:48.613857+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665188613_m1.jpg...
|
PhpStorm
|
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Undo
Redo
Cut
Copy
Paste
Paste and Match Style
Sel Undo
Redo
Cut
Copy
Paste
Paste and Match Style
Select All
Open DevTools...
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"Undo","depth":5,"bounds":{"left":0.0,"top":0.0,"width":0.065972224,"height":0.024444444},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Redo","depth":5,"bounds":{"left":0.0,"top":0.0,"width":0.065972224,"height":0.024444444},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Cut","depth":5,"bounds":{"left":0.0,"top":0.0,"width":0.065972224,"height":0.024444444},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Copy","depth":5,"bounds":{"left":0.0,"top":0.0,"width":0.065972224,"height":0.024444444},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Paste","depth":5,"bounds":{"left":0.0,"top":0.0,"width":0.065972224,"height":0.024444444},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Paste and Match Style","depth":5,"bounds":{"left":0.0,"top":0.0,"width":0.065972224,"height":0.024444444},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Select All","depth":5,"bounds":{"left":0.0,"top":0.0,"width":0.065972224,"height":0.024444444},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Open DevTools","depth":5,"bounds":{"left":0.0,"top":0.0,"width":0.065972224,"height":0.024444444},"on_screen":false,"role_description":"text"}]...
|
4445374797877545977
|
7802338930891525294
|
click
|
hybrid
|
NULL
|
Undo
Redo
Cut
Copy
Paste
Paste and Match Style
Sel Undo
Redo
Cut
Copy
Paste
Paste and Match Style
Select All
Open DevTools
SlackFileEdit ViewGoHistoryWindowHelpAPPDOCKER• ₴1DEV (docker)₴82APP (-zshtests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleterTest.phptests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesProviderTest.phptests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesUploaderTest.phptests/Unit/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeeches?tests/Unit/Component/Transcription/Diarization/Source/MeetingBotSourceTest.phptests/Unit/Contracts/Services/Calendar/CalendarTraitTest.phptests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.phptests/Unit/Jobs/Activity/Import/ImportTwilioVideoSpeechesJobTest.phptests/Unit/Jobs/Activity/Import/IsActivityReadyForProcessingJobTest.phptests/Unit/Jobs/Calendar/SetupCalendarSyncTest.phptests/Unit/Services/Activity/ParticipantsServiceTest.phptests/Unit/Services/Calendar/Command/ImportParticipantsTest.phptests/Unit/Services/Calendar/GoogleCalendarServiceTest.phptests/Unit/Services/Crm/Close/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTest.phptests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTraitMatchActivitiesTest.phytests/Unit/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTraitOpportunitiesTe:tests/Unit/Services/Crm/Pipedrive/ImportOpportunityMatchActivitiesTest.phptests/Unit/Services/Crm/Salesforce/ServiceTest.phptests/Unit/Services/Mail/0ffice/EmailApiClientTest.phptests/Unit/Services/RecallAI/RecallAIServiceTest.php113 files changed, 4143 insertions(+), 1740 deletions(-)create mode 120000 CLAUDE.mdcreate mode 100644 app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.phpdelete mode 100644 app/Component/ES/ElasticSearchWorkerManager.phpdelete mode 100644 app/Component/ES/Worker/ActivityWorker.phpdelete mode 100644 app/Component/ES/Worker/EntityWorker.phpdelete mode100644 app/Component/ES/Worker/WorkerAmount.phpdelete mode100644 app/Component/ES/Worker/WorkerInterface.phpcreate mode100644 app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.phtcreate mode100644 app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/Assembl:create mode100644 app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNot(create mode 100644 app/Console/Commands/Crm/Backfill0pportunityUserFromAccountCommand.phpdelete mode 100644 app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.phpcreate mode100644 front-end/src/components/shared/modals/EntityPickerModal/__tests__/us‹create mode 100644 tests/Feature/Component/Nudge/Process0rganisationImmediateNudgesJobTe:create mode 100644 tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheck‹delete mode 100644 tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/ActivityWorkerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/EntityWorkerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/WorkerAmountTest.phpcreate mode 100644 tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCr‹create mode 100644 tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.phpLukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ I|•HomeDMsActivityFilesLaterMore(ab)# Support Daily • in 2h 21 m100% <78•Wed 13 May12:39:48ED-→Describe what you are looking forJiminny ...Nikolay Ivanov6 0curoaroylau# engineering# general# jiminny-bg# platform-tickets# product_launches#random# releases# sofia-office# support# thank-yous# the_people_of jimi...MessagesAdd canvas@ Files+Lukas Kovalik 11.Today ~мен все ме праща наhttps://app.vanta.com/c/jiminny.com/employee/onboardingNikolay Ivanov 11:01 AMХм, Джейс дали не може да ти помогне?Lukas Kovalik 11:01 AMще питам James, предполагам че нямам правада мерсиNikolay Ivanov 11:01 AMмда° Direct messages& Nikolay Ivanovdo James Graham. Stoyan Tanev. Galya DimitrovaP. Steliyan Georgievo Petko Kashinski®. Aneliya Angelovaã. Stefka Stoyanova•. Vasil Vasilev •!Lukas Kovalik y...МОЛЯLukas Kovalik 12:13 PMНики сори, още един въпрос имамкогато ги правеше ти FE ли оправяима vulnerabilities no npmNikolay Ivanov 12:28 PMнетях ги оставямLukas Kovalik 12:29 PMаз погледнах твоя тикет и там друго нямашесамо FEкак стигна до Workerl:: AppsJira CloudMessage Nikolay IvanovToast...
|
32847
|
NULL
|
NULL
|
NULL
|
|
32850
|
1255
|
32
|
2026-05-13T09:39:48.658500+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665188658_m2.jpg...
|
PhpStorm
|
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Undo
Redo
Cut
Copy
Paste
Paste and Match Style
Sel Undo
Redo
Cut
Copy
Paste
Paste and Match Style
Select All
Open DevTools...
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"Undo","depth":5,"bounds":{"left":0.27027926,"top":1.0,"width":0.03158245,"height":0.0},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Redo","depth":5,"bounds":{"left":0.27027926,"top":1.0,"width":0.03158245,"height":0.0},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Cut","depth":5,"bounds":{"left":0.27027926,"top":1.0,"width":0.03158245,"height":0.0},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Copy","depth":5,"bounds":{"left":0.27027926,"top":1.0,"width":0.03158245,"height":0.0},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Paste","depth":5,"bounds":{"left":0.27027926,"top":1.0,"width":0.03158245,"height":0.0},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Paste and Match Style","depth":5,"bounds":{"left":0.27027926,"top":1.0,"width":0.03158245,"height":0.0},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Select All","depth":5,"bounds":{"left":0.27027926,"top":1.0,"width":0.03158245,"height":0.0},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Open DevTools","depth":5,"bounds":{"left":0.27027926,"top":1.0,"width":0.03158245,"height":0.0},"on_screen":false,"role_description":"text"}]...
|
4445374797877545977
|
7802338930891525294
|
click
|
hybrid
|
NULL
|
Undo
Redo
Cut
Copy
Paste
Paste and Match Style
Sel Undo
Redo
Cut
Copy
Paste
Paste and Match Style
Select All
Open DevTools
PhostormProiectVIeWINavigareCodeLaravelKeractorJOOISWindowFV faVsco.js°9 master ~(C ActivityController.pnp|aravel.l0gA SF (jiminny@localhost]4 HS_local [jiminny@localhost]& console (PROD] X A console [EU]D Teaminsights, m Themesv D UserAutomatedRep -007final class ActivityController extends Controller implements CommentContextInterfaceA console [STAGING]v Dv2c) ACuviLyvzconuroAskAnythingCorLL0/() AskJiminnyRepc© DealsV2Controll 410%(C) OnDemandV2Cc€ PlavlistControlleC) PlavlistSharecorC PlavlistTrackCor111131114(C) UoloadControlleC) [EMAIL]) AiCrmNotesControl(c) Racecontroller nhn@ ClientTokenControl 1157(e) CrmController.pnp11158© DealLevelPromptsC 1159c) DealRiskcontroller.@ InctantMeetinaCont 11611164C) Languagecontrolle© LayoutManagemen 1163Ca) livoCoodControllor1164 9© MeetingsController 1192© MessageController. 1193 l >C) MotadntoControllor L2141212 |159c) Mobilesettinasconi© MomentController.r 125gc) Nudgecontroller.phNumberAllocatorCc 12/e11271OraanizationMembi 1212C) OraanizationRetentC) OraanizationSvnce@ PartnerController.o1276 1g) PlavbackController1133480 PlavlictController pl 1335g ScimController.nhn9) SidekickController , 13379a) SoftnhoneControlle© SsoController.php() CnbccrintionGontrae ToamAiAutomationt6) ToamAiContovtCar0 ToamContrallor nhr 1343 (Q9 >public function ListActivitySearch(Request Srequest, SearchTransformer SsearchTransformer): JsonResponses: 569— 571* Deletes a saved search— 573* @param Request $request* apanam Search $search575* achrows except1or* drecurn Jsonkesponse578579— 580pubLic tunccion deleteActivicysearch kequest srequest, search ssearch: Jsonkesponse.582oubunc tunction uivelrequest srequest, clastcactIvirvkedosirory srepostrory: usonkesponse....* dparam Activitu Sactivitu*Gthrows_AuthorizationExcent.zon589* Greturn mixedpublic function show(Activity Sactivity, ActivityService $activityService): JsonResponse{...}public function createRecording(Activity Sactivity)1...597593594public function updateRecording(Request Srequest, Activity $activity){...h~ 596public function stopRecording(Activity Sactivity)(...}60€* Add activity to this user's favorites playlist_ 601=602* athrows AuthorizationException604public function favorite(Activity Sactivitv. PlavlistActivitvRepository SolavlistActivitvRepositorv): J501605606=607* Remove activitu from this user's favorites plaulisti60S•Goarom Actvatu sactvitu*athrowsAuthorizationExcent.ion* Greturn mixednublic function unfavorite Activitv Sactivitv)-Tx: AutovCONCAT(u.id, CASE WHEN U.id = t.owner_id THEN ' (owner)' ELSE"' END) AS user_id,sa.*t.owner_id FROM social_accounts saNolN usens u on u.id e sa.sociable idJOIN teams t .n<->l: on t.id = u.team_icWHERE u.team_id = 581 and sa.provider = 'salesforce';SELECT * FROM automated_report_results order by id desc;select * from features;select * from team_features where feature_id = 40;select * from teams where id = 556:select * from automated_reports:where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044"pat", "podcast"]SELECT * FROM automated report_ results WHERE uuid to bin( '822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid:select * from automated_report_results order by za desc;SELECT * FROM automated report resultsWHEKE 10 =144select * from automated report results WHERE report id = 54:select * from opportunities where 1d = 75943494SELE * FROM teams WHERE name LIKE "%Les%': # 711, 692. 16067 - Timinnvintearationdlesmils.comselect * from playbooks where team id = 711: # event 226147SELEd * FROM Davbook catedonies WHERE Dlavbook 10 e 55151SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_typeSELECT * EROM eom fields WHERE 1d = 226147÷SELECT * EROM eom field values WHERE com field 1d = 226147.SELECT * FROM crm_configurations WHERE id = 692;SEISCTCONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '• END) AS user_id,nemailSa.xt.owner id FROM social accounts saJOIN users u on u.id = sa.sociable idJOIN teams t 1.n<->1: on t.id = u.team_idWHERE U.team id = 711 and sa.provider = 'salesforce':SELECT * FROM crm profiles cp JOIN users u 1..n<->1: on u.id = co.user id WHERE u.team_id = 711;select * from leads:select * from calendars:SELECTcascadeNew Cascade50 lihi7 # Support Daily - in 2h 21 m100% L2• Wed 13 May 12:39:48AskJiminnyReportActivityServiceTest v+0 ..So jiminny040 A1 A40 V 64 ^Cascade Code x .Kick off a new project. Make changesUndo@, Event Serialization Requirement The user wants to determine it the SerializesModels trait is necessary inC, Fixing Automated Report Job Failure Due to Missing PDF URI© Planhat Event Playback InvestigationDacteneed to review the task "Allow owner's role to be selected when setting up a trial" Here is the descritPaste and Match Stvle÷ @Code SWF-1.6Solect AlOnen DevToolsWN Windsurf Teams...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
32855
|
1254
|
26
|
2026-05-13T09:40:00.532666+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665200532_m1.jpg...
|
PhpStorm
|
faVsco.js – ActivityController.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use Carbon\Carbon;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\In;
use Illuminate\Validation\ValidationException;
use InvalidArgumentException;
use Jiminny\Component\ActivityAnalytics;
use Jiminny\Component\ActivitySearch;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Queue\Constants;
use Jiminny\Contracts\ES\Events\UpdateSingleEntity;
use Jiminny\Contracts\ES\UpdateTargetEnum;
use Jiminny\Contracts\Nudge\NudgeFactoryInterface;
use Jiminny\Contracts\Playlist\PlaylistTrackFactoryInterface;
use Jiminny\Contracts\Repositories\PlaylistActivityRepository;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Enums\TeamSetting;
use Jiminny\Events\Activities\AiAutomation\ActivityProspectAdded;
use Jiminny\Events\Activities\Coaching\Coached;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Controllers\CommentContextInterface;
use Jiminny\Http\Responses\Api\AbstractResponse;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\ActivityCommentTransformer;
use Jiminny\Http\Transformers\ActivityTopicTriggerTransformer;
use Jiminny\Http\Transformers\ActivityTransformer;
use Jiminny\Http\Transformers\AvailabilityNotificationTransformer;
use Jiminny\Http\Transformers\CoachingFeedbackTransformer;
use Jiminny\Http\Transformers\CoachingSectionsTransformer;
use Jiminny\Http\Transformers\SearchTransformer;
use Jiminny\Http\Transformers\StatsTransformer;
use Jiminny\Jobs\Crm\SaveActivity;
use Jiminny\Jobs\Crm\UpdateStage;
use Jiminny\Jobs\Telephony\StartRecording;
use Jiminny\Jobs\Telephony\StopRecording;
use Jiminny\Jobs\Telephony\ToggleRecording;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\CoachingFeedback;
use Jiminny\Models\CoachingSection;
use Jiminny\Models\CoachingSectionCriterion;
use Jiminny\Models\CoachingSectionFeedback;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\LanguageDialect;
use Jiminny\Models\Lead;
use Jiminny\Models\Nudge;
use Jiminny\Models\PlaybookCategory;
use Jiminny\Models\Playlist;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\Track;
use Jiminny\Models\User;
use Jiminny\Repositories\CoachingFeedbackRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Rules\CrmReference;
use Jiminny\Rules\MultidimensionalArrayMaxCharRule;
use Jiminny\Services\ActivityService;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Services\PlaybackService;
use Jiminny\Services\UserService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
use Ramsey\Uuid\Uuid;
use Sentry;
use Symfony\Component\HttpFoundation;
final class ActivityController extends Controller implements CommentContextInterface
{
// Number of minutes to look back on activities. i.e. a timeout on activity duration.
private const int LOOK_BACK = 180;
public function __construct(
private ProviderRegistry $providerRegistry,
private ActivityService $activityService,
Response $response,
private UserService $userService,
private ActivitySearch\Service\ActivitySearch $activitySearch,
private NudgeFactoryInterface $nudgeFactory,
private ActivityCommentService $activityCommentService,
private LoggerInterface $logger,
private readonly CoachingFeedbackRepository $coachingFeedbackRepository,
private readonly TeamRepository $teamRepository,
) {
parent::__construct($response);
}
public static function getCommentImplementation(): string
{
return Comment::class;
}
public function delete()
{
$this->request->validate([
'*' => 'uuid:activities',
]);
$deletedIds = [];
foreach ($this->request->all() as $activityId) {
$activity = Activity::idOrUuId($activityId);
try {
if ($this->authorize('delete', $activity)) {
$activity->delete();
$deletedIds[] = $activityId;
\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);
}
} catch (AuthorizationException $authorizationException) {
// They didn't have permission.
}
}
return $this->response->withArray($deletedIds);
}
public function update(Request $request, Activity $activity)
{
$this->authorize('updateMetadata', $activity);
$request->validate([
'title' => 'string|max:250',
'category_id' => 'uuid:playbook_categories',
'language' => [
new In(
LanguageDialect::query()
->with('language')
->cursor()
->map(static function (LanguageDialect $languageDialect): string {
return $languageDialect->getLanguageLocale();
})
->all()
),
],
]);
if ($request->has('title')) {
$activity->title = $request->input('title');
}
if ($request->has('category_id')) {
$category = PlaybookCategory::uuid($request->input('category_id'));
if ($category->playbook->team_id !== $request->user()->team_id) {
return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
if ($request->has('language')) {
if (! $activity->isInProgress()) {
return $this->response->withError(
'Activity language can only be set while the meeting is in progress.',
400
);
}
$activity->setLanguageCode($request->input('language'));
}
$activity->save();
return $this->response->withOk();
}
// XXX: This should be merged with the update method.
/**
* @param Activity $activity
*
* @throws AuthorizationException
* @throws SocialAccountTokenInvalidException
*
* @return mixed
*/
public function summarize(Activity $activity): mixed
{
$this->logger->info('[Log Activity] Summarizing activity ', [
'activityId' => $activity->getUuid(),
'payload' => $this->request->all(),
]);
$this->authorize('update', $activity);
$this->logger->info('[Log Activity] Validating summary');
// Validate the payload.
$this->validateSummary($activity);
// All objects must belong to this team.
/** @var User $user */
$user = $this->request->user();
$team = $user->getTeam();
$crmService = $this->providerRegistry->get($team->crm->provider);
try {
$crmUser = $user;
if ($user->isCrmRequired() === false) {
$crmUser = $team->owner;
}
$crmService->setUser($crmUser);
} catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());
}
$rawEntities = $this->request->input('entities');
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid(
$this->request->input('layout_id')
);
// Delay execution of CRM jobs to avoid locking issues.
$jobDelay = 0;
// If we have arrived from a notification, mark it as read.
$notificationId = $this->request->input('nId');
if ($notificationId) {
$notification = $user->unreadNotifications->where('id', $notificationId)->first();
if ($notification) {
$notification->markAsRead();
}
}
$title = $this->request->input('title');
$prospects = $this->request->input('prospects');
$opportunityId = $this->request->input('opportunity_id');
$stageId = $this->request->input('stage_id');
$categoryId = $this->request->input('category_id');
$summary = $this->request->input('summary');
$crmProviderId = $this->request->input('crm_id');
$isInternal = $this->request->input('is_internal') ?? false;
$lead = null;
$category = null;
$account = null;
$contact = null;
$opportunity = null;
$stage = null;
$callStage = null;
foreach ($prospects as $prospectData) {
$objectId = $prospectData['id'];
if ($objectId === null) {
continue;
}
$objectType = $prospectData['type'];
$this->logger->info('debug', ['prospect_data' => $prospectData]);
try {
if ($objectType === null) {
$this->logger->info('no object type');
if ($crmService instanceof SupportsObjectTypeParseInterface) {
$objectType = $crmService->parseObjectType($objectId);
}
}
switch ($objectType) {
case 'lead':
$this->logger->info('Processing lead');
/** @var Lead|null $lead */
$lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();
// Lead does not exist locally, import it.
if ($lead === null) {
$this->logger->info('Lead does not exist locally');
/** @var Lead $lead */
$lead = $crmService->syncLead($objectId);
}
$this->logger->info('Lead found', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
if ($stageId === null) {
$this->logger->info('Stage ID is null');
// If it was not provided, just assume it is the current stage.
$callStage = $lead->stage;
break;
}
$this->logger->info('Looking for stage');
// Determine if they have changed the stage.
/** @var Stage $stage */
$stage = $team->crm->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_LEAD)
->firstOrFail();
$this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);
if ($lead->stage_id && $lead->stage_id !== $stage->id) {
$this->logger->info('Stage has changed');
// Storage current stage on activity.
$callStage = $lead->stage;
// The stage has changed, update in remote CRM.
dispatch(new UpdateStage($activity, $lead, $callStage, $stage));
$this->logger->info(
sprintf(
'[%s] User changing lead stage from %s to %s',
$crmService->getDisplayName(),
$callStage->getName(),
$stage->getName()
),
[
'user' => $user->getUuid(),
'lead' => $lead->getUuid(),
]
);
} else {
$this->logger->info('Stage has not changed');
// Stage remains as current.
$callStage = $stage;
}
break;
case 'account':
$this->logger->info('Processing account');
// If the object is not a lead, it should be an account.
$account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();
// Account does not exist locally, import it.
if ($account === null) {
$this->logger->info('Account does not exist locally');
$account = $crmService->syncAccount($objectId);
}
$this->logger->info('Account found', ['accountId' => $account->id]);
break;
case 'contact':
$this->logger->info('processing contact');
$contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$this->logger->info('contact does not exist locally');
$contact = $crmService->syncContact($objectId);
}
$this->logger->info('resolving account');
$account = $this->resolveAccount($team, $contact, $crmService, $prospects);
break;
}
// If they have specified an opportunity, retrieve this with stage.
if ($opportunityId) {
$this->logger->info('opportunity id is set');
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if ($opportunity === null) {
$this->logger->info('opportunity does not exist locally');
$opportunity = $crmService->syncOpportunity($opportunityId);
}
if ($stageId === null) {
$this->logger->info('stage id is null');
// If it was not provided, just assume it is the current stage.
$callStage = $opportunity->stage ?? null;
} else {
$this->logger->info('looking for stage');
/** @var ?Stage $opportunityStage */
$opportunityStage = $team->crm
->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
// There is a chance we still cannot import this opportunity.
if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {
$this->logger->info('opportunity stage has changed');
// Storage current stage on activity.
$callStage = $opportunity->stage;
dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));
$this->logger->info(
sprintf(
'[%s] User changing opportunity stage from %s to %s',
$crmService->getDisplayName(),
$callStage->name,
$opportunityStage->name
),
[
'userId' => $user->id_string,
'opportunityId' => $opportunity->id_string,
]
);
} else {
$this->logger->info('opportunity stage has not changed');
// Stage remains as current.
$callStage = $opportunityStage;
}
}
}
if ($crmProviderId) {
// Cast $crmProviderId to string otherwise it won't use database index for some records
$linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();
// Check if this activity has already been assigned to a different activity.
if ($linkedActivity && $linkedActivity->id !== $activity->id) {
throw new InvalidArgumentException(
'Sorry, the linked task has already been logged under a different call. '
. 'Please choose another linked task.'
);
}
}
} catch (InvalidArgumentException $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($exception->getMessage());
} catch (Exception $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorInternalError(
'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'
);
}
}
if ($categoryId) {
$category = PlaybookCategory::uuid($categoryId);
if ($category->playbook->team_id !== $team->id) {
throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
$this->logger->info('Prospect data', [
'lead_id' => $lead?->getId(),
'account_id' => $account?->getId(),
'contact_id' => $contact?->getId(),
'opportunity_id' => $opportunity?->getId(),
'stage_id' => $stage?->getId(),
]);
if ($title) {
$activity->title = $title;
}
if ($summary) {
$activity->summary = $summary;
}
if ($crmProviderId) {
$activity->crm_provider_id = $crmProviderId;
}
if ($callStage) {
$this->logger->info('Setting stage id', ['stageId' => $callStage->id]);
$activity->stage_id = $callStage->id;
}
if ($lead) {
$this->logger->info('Setting lead id', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
// If we are changed from an account > lead, unset the account data.
$this->logger->info('Unsetting account id, opportunity id, contact id, value');
$activity->account_id = null;
$activity->opportunity_id = null;
$activity->contact_id = null;
$activity->value = null;
}
if ($account) {
$this->logger->info('Setting account id', ['accountId' => $account->id]);
$activity->account_id = $account->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('unsetting lead id');
$activity->lead_id = null;
// Unset the contact if switching different accounts. Will be set up below if still applicable.
if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {
$this->logger->info('Unsetting contact id');
$activity->contact_id = null;
}
}
if ($opportunity) {
$this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);
$this->logger->info('unsetting lead id');
$activity->opportunity_id = $opportunity->id;
$activity->value = $opportunity->value;
// If we are changed from an lead > account, unset the lead data.
$activity->lead_id = null;
}
if ($contact) {
$this->logger->info('setting contact id', ['contactId' => $contact->id]);
$activity->contact_id = $contact->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('Unsetting lead id');
$activity->lead_id = null;
}
$activity->is_internal = $isInternal;
$activity->save();
$activity->refresh();
$this->logger->notice('Activity saved', [
'activity_id' => $activity->getId(),
'lead_id' => $activity->lead_id,
'account_id' => $activity->account_id,
'contact_id' => $activity->contact_id,
'opportunity_id' => $activity->opportunity_id,
'stage_id' => $activity->stage_id,
'crm_provider_id' => $activity->getCrmProviderId(),
]);
// Store entities as field data on the activity.
$updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);
if ($activity->isLoggable()) {
// Follow-up Task or Event data.
$followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);
$this->logger->info('CRM LOG manual log triggered', [
'activityId' => $activity->getUuid(),
'followupData' => $followupData,
'userId' => $user->getUuid(),
]);
// Store data in the CRM.
// ++add check for crm_required
$job = new SaveActivity($activity, $followupData);
if ($updatedData) {
$job->delay(Carbon::now()->addMinutes($jobDelay));
}
dispatch($job);
// Manually dispatch log for Opportunity or Prospect added
if ($activity->hasOpportunity() || $activity->hasProspect()) {
event(new ActivityProspectAdded(
activity: $activity,
eventSource: 'manually-log-crm-data'
));
}
}
return $this->response->withOk();
}
/**
* Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.
*
* @param ServiceInterface $service
* @param Activity $activity
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array
{
$updatedData = [];
$existingData = $activity->data()->get();
// We need to delete any existing data to overwrite with latest values.
$activity->data()->delete();
$layoutEntities = $layout->entities()
->with('field', 'parent')
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->get();
/** @var LayoutEntity $entity */
foreach ($layoutEntities as $entity) {
// If the user has provided a value for this entity
if (array_key_exists($entity->id_string, $entities)) {
$value = $entities[$entity->id_string];
// Convert raw data into values that the CRM can consume.
if ($value) {
$value = $service->normalizeValue($entity->field->type, $value);
}
// Check the field is part of the activity-summary section.
if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {
// This is the internal database ID, not the external CRM ID.
$objectId = null;
switch ($entity->field->object_type) {
case Field::OBJECT_ACCOUNT:
$objectId = $activity->account_id;
break;
case Field::OBJECT_CONTACT:
$objectId = $activity->contact_id;
break;
case Field::OBJECT_OPPORTUNITY:
$objectId = $activity->opportunity_id;
break;
case Field::OBJECT_LEAD:
$objectId = $activity->lead_id;
break;
case Field::OBJECT_TASK:
case Field::OBJECT_EVENT:
$objectId = $activity->id;
break;
}
if ($objectId) {
/** @var FieldData $data */
$data = $activity->data()->create([
'crm_layout_entity_id' => $entity->id,
'crm_field_id' => $entity->crm_field_id,
'object_type' => $entity->field->object_type,
'object_id' => $objectId,
'value' => $value,
]);
// Never send read-only field data to the CRM.
if ($entity->read_only === false && $entity->is_visible) {
$existingValue = $existingData
->where('crm_layout_entity_id', $entity->id)
->where('crm_field_id', $entity->crm_field_id)
->where('object_type', $entity->field->object_type)
->where('object_id', $objectId)
->first();
// If the field was actually changed, we need to reflect this in the CRM too.
if ($existingValue === null || $existingValue->value !== $value) {
$updatedData[] = $data->id;
}
}
}
}
}
}
return $updatedData;
}
/**
* Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.
*
* @param ServiceInterface $crmService
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array
{
$fieldData = [];
foreach ($entities as $entityId => $value) {
// Only bother with fields that have a value.
if ($value) {
// Extract the entity from the UUID. Check the field is valid and part of the follow-up section.
$entity = $layout->entities()
->uuid($entityId, false)
->whereHas('parent', function ($query) {
$query->where('label', 'follow-up');
})
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->first();
if ($entity) {
// Convert raw data into values that the CRM can consume.
$value = $crmService->normalizeValue($entity->field->type, $value);
// Add the field and value to the payload.
$fieldData += [
$entity->field->crm_provider_id => $value,
];
}
}
}
return $fieldData;
}
/**
* @param Activity $activity
*/
private function validateSummary(Activity $activity): void
{
$team = $activity->user->team;
$crmProvider = $team->crm->provider;
$attributes = [];
$rules = [
'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,
'title' => 'string|max:250',
'prospects' => 'required|array',
'opportunity_id' => new CrmReference($crmProvider),
'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',
'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator
'summary' => 'max:50000',
'nId' => 'exists:notifications,id',
'crm_id' => new CrmReference($crmProvider),
'entities' => 'array',
'is_internal' => 'boolean',
];
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));
// Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.
$entities = $layout->entities()
->where('read_only', 0)
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->whereHas('parent', function ($query) use ($activity) {
if ($activity->isLoggable() === false) {
$query->where('label', '<>', 'follow-up');
}
});
$isInternal = $this->request->input('is_internal', false);
foreach ($entities->get() as $entity) {
$rules += $this->buildFieldValidator($entity, $isInternal);
$attributes += $this->buildFieldMessage($entity);
}
$this->request->validate($rules, [], $attributes);
}
private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array
{
return [
'entities.' . $entity->id_string => $entity->getValidator($isInternal),
];
}
/**
* @param LayoutEntity $entity
*
* @return array
*/
private function buildFieldMessage(LayoutEntity $entity): array
{
$label = $entity->label;
if ($label === null) {
$label = $entity->field->label;
}
return [
'entities.' . $entity->id_string => $label,
];
}
public function search(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->debugLog(
$user,
'User extracted from request',
['user' => $user->getId(), 'tz' => $user->getTimezone()]
);
$searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());
$this->debugLog(
$user,
'ActivitySearch criteria built',
['searchCriteria' => $searchCriteria]
);
$filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);
$this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);
$this->validateSearch($request, $filterSet);
$this->debugLog($user, 'Request validated');
$searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);
/** @var Collection<Activity> $activities */
$activities = $searchResponse['results'];
$this->debugLog($user, 'Activities ES response extracted');
$hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(
$user->getTeamId(),
TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),
);
if ($hideInternalMeetingsSetting?->getValue() === '1') {
$activities = $activities->filter(function (Activity $activity) {
if ($activity->is_internal && empty($activity->actual_start_time)) {
return false;
}
return true;
});
}
$this->debugLog($user, 'Internal meetings (?!) filtered');
$this->response->getManager()
->parseIncludes([
'category',
'organizer.group',
'prospect',
'stage',
'opportunity',
'stats',
'scorecards',
'masterTrack',
'activeParticipants',
'notification',
])
->setSerializer(new JsonSerializer());
$transformerExcludes = $this->request->input('exclude');
if ($transformerExcludes) {
$this->response->getManager()->parseExcludes($transformerExcludes);
}
$this->debugLog($user, 'Response Manager (?!) applied');
$transformer = new ActivityTransformer();
$transformer->setConsumer($user);
$this->debugLog($user, 'Activity Transformer added');
$resource = new \League\Fractal\Resource\Collection($activities, $transformer);
$page = $searchCriteria->getPageNumber();
$this->debugLog($user, 'Search criteria page number called', ['page' => $page]);
$histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');
$this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);
return $this->response->withArray([
'pagination' => [
'total' => $searchResponse['totalHits'],
'current' => $page,
'prev' => max($page - 1, 1),
'next' => $page + 1,
],
'results' => $this->response->getManager()->createData($resource)->toArray(),
'histogram' => $histogram,
]);
}
private function debugLog(User $user, string $logMessage, ?array $context = []): void
{
// Debug for Learning People Only
if ($user->getTeamId() !== 260) {
return;
}
Log::notice(
sprintf('[activity-search-controller] %s', $logMessage),
$context
);
}
/** @throws ValidationException */
private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void
{
$rules = [
'exclude' => 'array',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
];
if ($prefix !== null && mb_strpos($prefix, '.') !== false) {
$rules[rtrim($prefix, '.')] = sprintf(
'required|array|max:%d',
$filterSet->count()
);
}
$validationRules = $filterSet->getValidationRules($prefix)
->merge($rules)
->all();
$request->validate($validationRules);
}
public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$search = $this->updateOrCreateActivitySearch($request);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function updateActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('update', $search);
$this->updateOrCreateActivitySearch($request, $search);
return $this->response->withOk();
}
private function storeNamedSearchFilters(
Collection $request,
Search $search,
FilterDefinitionCollection $filterSet,
?string $prefix = null,
): self {
$arrayTypeProperties = $filterSet
->getPropertyTypes([
FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,
])
->all();
$supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);
foreach ($supportedRequestProperties as $requestPropertyName) {
if (! array_has($request, $requestPropertyName)) {
continue;
}
/** @var string|string[] $propertyValue */
$propertyValue = array_get($request, $requestPropertyName);
$propertyName = $prefix === null
? $requestPropertyName
: mb_substr($requestPropertyName, mb_strlen($prefix));
$isArrayType = array_has($arrayTypeProperties, $propertyName);
if (! $isArrayType) {
/** @var string $requestPropertyValue */
$search->filters()->updateOrCreate(
[
'filter' => $propertyName,
],
[
'value' => $propertyValue,
]
);
continue;
}
/** @var string[] $requestPropertyValue */
/** @var SearchFilter[]|Collection $existingFilterValues */
$existingFilterValuesKeyed = $search->filters()
->where('filter', $propertyName)
->get()
->keyBy('id');
// Iterate over values provided as request parameters
foreach ($propertyValue as $value) {
/** @var SearchFilter|null $valueFilter */
$valueFilter = $search->filters()
->where(
[
'filter' => $propertyName,
'value' => $value,
]
)
->first();
if ($valueFilter !== null) {
// Remove filter value pair from list to be deleted
$existingFilterValuesKeyed->forget($valueFilter->id);
} else {
// Add new filter/value pair
$search->filters()->updateOrCreate([
'filter' => $propertyName,
'value' => $value,
]);
}
}
// Delete filter value pairs for this filter that no longer exist in request parameters
foreach ($existingFilterValuesKeyed as $existingFilter) {
$existingFilter->delete();
}
}
/** @var Collection<int, SearchFilter> $filtersKeyed */
$filtersKeyed = $search->filters()->get()->keyBy('filter');
// wipe removed filters from this search
foreach ($filtersKeyed as $filterName => $filter) {
if (array_has($request, $prefix . $filterName)) {
continue;
}
// Remove all filter values for this filter
$search->filters()->where('filter', $filterName)->delete();
}
return $this;
}
/**
* @throws AuthorizationException
*/
public function fetchActivitySearch(
Search $search,
Request $request,
SearchTransformer $searchTransformer,
): JsonResponse {
$this->authorize('view', $search);
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withCollection(
$user->searches()->get(),
$searchTransformer
->withConsumer($user)
);
}
/**
* Deletes a saved search
*
* @param Request $request
* @param Search $search
*
* @throws Exception
*
* @return JsonResponse
*/
public function deleteActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('delete', $search);
// Orphan any AutomatedReports that use this search
$search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);
// Delete filters and the search itself
$search->filters()->delete();
$search->delete();
return $this->response->withOk();
}
public function live(Request $request, ElasticActivityRepository $repository): JsonResponse
{
$user = $this->getUserFromRequest($request);
$this->request->validate([
'sort_direction' => 'in:asc,desc',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
]);
$activities = $repository->getLiveCoachingEligibleActivities(
user: $user,
lookBackMinutes: self::LOOK_BACK,
limit: (int) $this->request->input('limit', 25),
page: (int) $this->request->input('page', 1),
sortBy: ['actual_start_time', 'scheduled_start_time'],
sortDirection: (string) $this->request->input('sort_direction', 'asc'),
);
$this->response
->getManager()
->parseIncludes(['organizer.group', 'prospect'])
->setSerializer(new JsonSerializer());
return $this->response->withCollection($activities, new ActivityTransformer());
}
/**
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function show(Activity $activity, ActivityService $activityService): JsonResponse
{
$this->authorize('show', $activity);
$user = $activity->getUser();
$team = $user->getTeam();
// Sync the opportunity with the latest data if possible.
if ($activity->opportunity_id) {
try {
$crmService = $this->providerRegistry->get($team->crm->provider);
if (! $user->isCrmRequired()) {
$crmService->setUser($team->getOwner());
} else {
$crmService->setUser($user);
}
$crmService->syncOpportunity($activity->opportunity->crm_provider_id);
} catch (Exception $exception) {
// Move on.
}
}
$activityData = $activityService->getActivityData($this->request->user(), $activity);
return response()->json($activityData);
}
public function createRecording(Activity $activity)
{
$this->authorize('record', $activity);
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Tell Twilio to start recording this activity.
if ($activity->recording_state === Activity::RECORDING_OFF) {
$job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withCreated();
}
return $this->response->errorGone('Activity is already recording.');
}
public function updateRecording(Request $request, Activity $activity)
{
$this->authorize('record', $activity);
$request->validate([
'preference' => 'boolean',
'state' => [
'string',
Rule::in([
Activity::RECORDING_IN_PROGRESS,
Activity::RECORDING_PAUSED,
]),
],
]);
if ($request->has('state')) {
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Toggle the recording state between paused and resumed.
if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {
$job = (new ToggleRecording($activity, $request->input('state')))
->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Recording is not toggleable.');
}
if ($request->has('preference')) {
$activity->update([
'recording_preference' => $request->input('preference') ? 1 : 0,
]);
return $this->response->withOk();
}
return $this->response->errorWrongArgs('Something went wrong');
}
public function stopRecording(Activity $activity)
{
$this->authorize('stopRecord', $activity);
// Tell Twilio to stop recording this activity.
if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {
$job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Activity is not recording.');
}
/**
* Add activity to this user's favorites playlist
*
* @throws AuthorizationException
*/
public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse
{
$this->authorize('favorite', $activity);
$user = $this->getUserFromRequest($this->request);
$favorite = $activity->wasFavoritedBy($user);
$name = $activity->activity_title ?? '';
// It needs to check at least one record.
if (! $favorite) {
$favoritePlaylist = $user->favoritePlaylist();
$playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(
$activity,
$user,
$favoritePlaylist
);
if ($playlistActivity !== null) {
$playlistActivity->update(
// Just update, don't sort.
['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],
);
} else {
$playlistActivity = $activity->playlistActivities()->create([
'playlist_id' => $favoritePlaylist->getId(),
'user_id' => $user->getId(),
'start_time' => 0,
'name' => mb_strimwidth($name, 0, 100),
]);
// Sort it on top.
$playlistActivity->update(
[
'sort' => $playlistActivityRepository->calculateNewSortOrder(
null,
$playlistActivity,
),
],
);
}
$playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);
return new JsonResponse([], JsonResponse::HTTP_CREATED);
}
return new JsonResponse(
[
'error' => [
'code' => AbstractResponse::CODE_CONFLICT,
'http_code' => JsonResponse::HTTP_CONFLICT,
'message' => 'Resource Already Exists',
],
],
JsonResponse::HTTP_CONFLICT,
);
}
/**
* Remove activity from this user's favorites playlist
*
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function unfavorite(Activity $activity)
{
$user = $t...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"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":"Analyzing…","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 Carbon\\Carbon;\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Exception;\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Validation\\Rule;\nuse Illuminate\\Validation\\Rules\\In;\nuse Illuminate\\Validation\\ValidationException;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ActivityAnalytics;\nuse Jiminny\\Component\\ActivitySearch;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Contracts\\ES\\Events\\UpdateSingleEntity;\nuse Jiminny\\Contracts\\ES\\UpdateTargetEnum;\nuse Jiminny\\Contracts\\Nudge\\NudgeFactoryInterface;\nuse Jiminny\\Contracts\\Playlist\\PlaylistTrackFactoryInterface;\nuse Jiminny\\Contracts\\Repositories\\PlaylistActivityRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Enums\\TeamSetting;\nuse Jiminny\\Events\\Activities\\AiAutomation\\ActivityProspectAdded;\nuse Jiminny\\Events\\Activities\\Coaching\\Coached;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Controllers\\CommentContextInterface;\nuse Jiminny\\Http\\Responses\\Api\\AbstractResponse;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\ActivityCommentTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTopicTriggerTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTransformer;\nuse Jiminny\\Http\\Transformers\\AvailabilityNotificationTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingFeedbackTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingSectionsTransformer;\nuse Jiminny\\Http\\Transformers\\SearchTransformer;\nuse Jiminny\\Http\\Transformers\\StatsTransformer;\nuse Jiminny\\Jobs\\Crm\\SaveActivity;\nuse Jiminny\\Jobs\\Crm\\UpdateStage;\nuse Jiminny\\Jobs\\Telephony\\StartRecording;\nuse Jiminny\\Jobs\\Telephony\\StopRecording;\nuse Jiminny\\Jobs\\Telephony\\ToggleRecording;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\CoachingFeedback;\nuse Jiminny\\Models\\CoachingSection;\nuse Jiminny\\Models\\CoachingSectionCriterion;\nuse Jiminny\\Models\\CoachingSectionFeedback;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\LanguageDialect;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Nudge;\nuse Jiminny\\Models\\PlaybookCategory;\nuse Jiminny\\Models\\Playlist;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\Track;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\CoachingFeedbackRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Rules\\MultidimensionalArrayMaxCharRule;\nuse Jiminny\\Services\\ActivityService;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Services\\PlaybackService;\nuse Jiminny\\Services\\UserService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\nuse Ramsey\\Uuid\\Uuid;\nuse Sentry;\nuse Symfony\\Component\\HttpFoundation;\n\nfinal class ActivityController extends Controller implements CommentContextInterface\n{\n // Number of minutes to look back on activities. i.e. a timeout on activity duration.\n private const int LOOK_BACK = 180;\n\n public function __construct(\n private ProviderRegistry $providerRegistry,\n private ActivityService $activityService,\n Response $response,\n private UserService $userService,\n private ActivitySearch\\Service\\ActivitySearch $activitySearch,\n private NudgeFactoryInterface $nudgeFactory,\n private ActivityCommentService $activityCommentService,\n private LoggerInterface $logger,\n private readonly CoachingFeedbackRepository $coachingFeedbackRepository,\n private readonly TeamRepository $teamRepository,\n ) {\n parent::__construct($response);\n }\n\n public static function getCommentImplementation(): string\n {\n return Comment::class;\n }\n\n public function delete()\n {\n $this->request->validate([\n '*' => 'uuid:activities',\n ]);\n\n $deletedIds = [];\n foreach ($this->request->all() as $activityId) {\n $activity = Activity::idOrUuId($activityId);\n\n try {\n if ($this->authorize('delete', $activity)) {\n $activity->delete();\n $deletedIds[] = $activityId;\n\n \\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n }\n } catch (AuthorizationException $authorizationException) {\n // They didn't have permission.\n }\n }\n\n return $this->response->withArray($deletedIds);\n }\n\n public function update(Request $request, Activity $activity)\n {\n $this->authorize('updateMetadata', $activity);\n\n $request->validate([\n 'title' => 'string|max:250',\n 'category_id' => 'uuid:playbook_categories',\n 'language' => [\n new In(\n LanguageDialect::query()\n ->with('language')\n ->cursor()\n ->map(static function (LanguageDialect $languageDialect): string {\n return $languageDialect->getLanguageLocale();\n })\n ->all()\n ),\n ],\n ]);\n\n if ($request->has('title')) {\n $activity->title = $request->input('title');\n }\n\n if ($request->has('category_id')) {\n $category = PlaybookCategory::uuid($request->input('category_id'));\n\n if ($category->playbook->team_id !== $request->user()->team_id) {\n return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n if ($request->has('language')) {\n if (! $activity->isInProgress()) {\n return $this->response->withError(\n 'Activity language can only be set while the meeting is in progress.',\n 400\n );\n }\n\n $activity->setLanguageCode($request->input('language'));\n }\n\n $activity->save();\n\n return $this->response->withOk();\n }\n\n // XXX: This should be merged with the update method.\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws SocialAccountTokenInvalidException\n *\n * @return mixed\n */\n public function summarize(Activity $activity): mixed\n {\n $this->logger->info('[Log Activity] Summarizing activity ', [\n 'activityId' => $activity->getUuid(),\n 'payload' => $this->request->all(),\n ]);\n $this->authorize('update', $activity);\n\n $this->logger->info('[Log Activity] Validating summary');\n // Validate the payload.\n $this->validateSummary($activity);\n\n // All objects must belong to this team.\n /** @var User $user */\n $user = $this->request->user();\n $team = $user->getTeam();\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n try {\n $crmUser = $user;\n if ($user->isCrmRequired() === false) {\n $crmUser = $team->owner;\n }\n $crmService->setUser($crmUser);\n } catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());\n }\n\n $rawEntities = $this->request->input('entities');\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid(\n $this->request->input('layout_id')\n );\n\n // Delay execution of CRM jobs to avoid locking issues.\n $jobDelay = 0;\n\n // If we have arrived from a notification, mark it as read.\n $notificationId = $this->request->input('nId');\n if ($notificationId) {\n $notification = $user->unreadNotifications->where('id', $notificationId)->first();\n\n if ($notification) {\n $notification->markAsRead();\n }\n }\n\n $title = $this->request->input('title');\n $prospects = $this->request->input('prospects');\n $opportunityId = $this->request->input('opportunity_id');\n $stageId = $this->request->input('stage_id');\n $categoryId = $this->request->input('category_id');\n $summary = $this->request->input('summary');\n $crmProviderId = $this->request->input('crm_id');\n $isInternal = $this->request->input('is_internal') ?? false;\n\n $lead = null;\n $category = null;\n $account = null;\n $contact = null;\n $opportunity = null;\n $stage = null;\n $callStage = null;\n\n foreach ($prospects as $prospectData) {\n $objectId = $prospectData['id'];\n\n if ($objectId === null) {\n continue;\n }\n\n $objectType = $prospectData['type'];\n $this->logger->info('debug', ['prospect_data' => $prospectData]);\n\n try {\n if ($objectType === null) {\n $this->logger->info('no object type');\n if ($crmService instanceof SupportsObjectTypeParseInterface) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n }\n\n switch ($objectType) {\n case 'lead':\n $this->logger->info('Processing lead');\n /** @var Lead|null $lead */\n $lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();\n\n // Lead does not exist locally, import it.\n if ($lead === null) {\n $this->logger->info('Lead does not exist locally');\n /** @var Lead $lead */\n $lead = $crmService->syncLead($objectId);\n }\n\n $this->logger->info('Lead found', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n if ($stageId === null) {\n $this->logger->info('Stage ID is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $lead->stage;\n\n break;\n }\n\n $this->logger->info('Looking for stage');\n // Determine if they have changed the stage.\n /** @var Stage $stage */\n $stage = $team->crm->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_LEAD)\n ->firstOrFail();\n\n $this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);\n if ($lead->stage_id && $lead->stage_id !== $stage->id) {\n $this->logger->info('Stage has changed');\n // Storage current stage on activity.\n $callStage = $lead->stage;\n\n // The stage has changed, update in remote CRM.\n dispatch(new UpdateStage($activity, $lead, $callStage, $stage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing lead stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->getName(),\n $stage->getName()\n ),\n [\n 'user' => $user->getUuid(),\n 'lead' => $lead->getUuid(),\n ]\n );\n } else {\n $this->logger->info('Stage has not changed');\n // Stage remains as current.\n $callStage = $stage;\n }\n\n break;\n\n case 'account':\n $this->logger->info('Processing account');\n // If the object is not a lead, it should be an account.\n $account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();\n\n // Account does not exist locally, import it.\n if ($account === null) {\n $this->logger->info('Account does not exist locally');\n $account = $crmService->syncAccount($objectId);\n }\n\n $this->logger->info('Account found', ['accountId' => $account->id]);\n\n break;\n case 'contact':\n $this->logger->info('processing contact');\n $contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $this->logger->info('contact does not exist locally');\n $contact = $crmService->syncContact($objectId);\n }\n\n $this->logger->info('resolving account');\n $account = $this->resolveAccount($team, $contact, $crmService, $prospects);\n\n break;\n }\n\n // If they have specified an opportunity, retrieve this with stage.\n if ($opportunityId) {\n $this->logger->info('opportunity id is set');\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if ($opportunity === null) {\n $this->logger->info('opportunity does not exist locally');\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n if ($stageId === null) {\n $this->logger->info('stage id is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $opportunity->stage ?? null;\n } else {\n $this->logger->info('looking for stage');\n /** @var ?Stage $opportunityStage */\n $opportunityStage = $team->crm\n ->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n // There is a chance we still cannot import this opportunity.\n if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {\n $this->logger->info('opportunity stage has changed');\n // Storage current stage on activity.\n $callStage = $opportunity->stage;\n\n dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing opportunity stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->name,\n $opportunityStage->name\n ),\n [\n 'userId' => $user->id_string,\n 'opportunityId' => $opportunity->id_string,\n ]\n );\n } else {\n $this->logger->info('opportunity stage has not changed');\n // Stage remains as current.\n $callStage = $opportunityStage;\n }\n }\n }\n\n if ($crmProviderId) {\n // Cast $crmProviderId to string otherwise it won't use database index for some records\n $linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();\n\n // Check if this activity has already been assigned to a different activity.\n if ($linkedActivity && $linkedActivity->id !== $activity->id) {\n throw new InvalidArgumentException(\n 'Sorry, the linked task has already been logged under a different call. '\n . 'Please choose another linked task.'\n );\n }\n }\n } catch (InvalidArgumentException $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($exception->getMessage());\n } catch (Exception $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorInternalError(\n 'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'\n );\n }\n }\n\n if ($categoryId) {\n $category = PlaybookCategory::uuid($categoryId);\n\n if ($category->playbook->team_id !== $team->id) {\n throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n $this->logger->info('Prospect data', [\n 'lead_id' => $lead?->getId(),\n 'account_id' => $account?->getId(),\n 'contact_id' => $contact?->getId(),\n 'opportunity_id' => $opportunity?->getId(),\n 'stage_id' => $stage?->getId(),\n ]);\n\n if ($title) {\n $activity->title = $title;\n }\n\n if ($summary) {\n $activity->summary = $summary;\n }\n\n if ($crmProviderId) {\n $activity->crm_provider_id = $crmProviderId;\n }\n\n if ($callStage) {\n $this->logger->info('Setting stage id', ['stageId' => $callStage->id]);\n $activity->stage_id = $callStage->id;\n }\n\n if ($lead) {\n $this->logger->info('Setting lead id', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n // If we are changed from an account > lead, unset the account data.\n $this->logger->info('Unsetting account id, opportunity id, contact id, value');\n $activity->account_id = null;\n $activity->opportunity_id = null;\n $activity->contact_id = null;\n $activity->value = null;\n }\n\n if ($account) {\n $this->logger->info('Setting account id', ['accountId' => $account->id]);\n $activity->account_id = $account->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('unsetting lead id');\n $activity->lead_id = null;\n\n // Unset the contact if switching different accounts. Will be set up below if still applicable.\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {\n $this->logger->info('Unsetting contact id');\n $activity->contact_id = null;\n }\n }\n\n if ($opportunity) {\n $this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);\n $this->logger->info('unsetting lead id');\n $activity->opportunity_id = $opportunity->id;\n $activity->value = $opportunity->value;\n\n // If we are changed from an lead > account, unset the lead data.\n $activity->lead_id = null;\n }\n\n if ($contact) {\n $this->logger->info('setting contact id', ['contactId' => $contact->id]);\n $activity->contact_id = $contact->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('Unsetting lead id');\n $activity->lead_id = null;\n }\n\n $activity->is_internal = $isInternal;\n $activity->save();\n $activity->refresh();\n\n $this->logger->notice('Activity saved', [\n 'activity_id' => $activity->getId(),\n 'lead_id' => $activity->lead_id,\n 'account_id' => $activity->account_id,\n 'contact_id' => $activity->contact_id,\n 'opportunity_id' => $activity->opportunity_id,\n 'stage_id' => $activity->stage_id,\n 'crm_provider_id' => $activity->getCrmProviderId(),\n ]);\n\n // Store entities as field data on the activity.\n $updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);\n\n if ($activity->isLoggable()) {\n // Follow-up Task or Event data.\n $followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);\n\n $this->logger->info('CRM LOG manual log triggered', [\n 'activityId' => $activity->getUuid(),\n 'followupData' => $followupData,\n 'userId' => $user->getUuid(),\n ]);\n\n // Store data in the CRM.\n // ++add check for crm_required\n $job = new SaveActivity($activity, $followupData);\n\n if ($updatedData) {\n $job->delay(Carbon::now()->addMinutes($jobDelay));\n }\n\n dispatch($job);\n\n // Manually dispatch log for Opportunity or Prospect added\n if ($activity->hasOpportunity() || $activity->hasProspect()) {\n event(new ActivityProspectAdded(\n activity: $activity,\n eventSource: 'manually-log-crm-data'\n ));\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.\n *\n * @param ServiceInterface $service\n * @param Activity $activity\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array\n {\n $updatedData = [];\n $existingData = $activity->data()->get();\n\n // We need to delete any existing data to overwrite with latest values.\n $activity->data()->delete();\n\n $layoutEntities = $layout->entities()\n ->with('field', 'parent')\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->get();\n\n /** @var LayoutEntity $entity */\n foreach ($layoutEntities as $entity) {\n // If the user has provided a value for this entity\n if (array_key_exists($entity->id_string, $entities)) {\n $value = $entities[$entity->id_string];\n\n // Convert raw data into values that the CRM can consume.\n if ($value) {\n $value = $service->normalizeValue($entity->field->type, $value);\n }\n\n // Check the field is part of the activity-summary section.\n if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {\n // This is the internal database ID, not the external CRM ID.\n $objectId = null;\n\n switch ($entity->field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $objectId = $activity->account_id;\n\n break;\n\n case Field::OBJECT_CONTACT:\n $objectId = $activity->contact_id;\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n $objectId = $activity->opportunity_id;\n\n break;\n\n case Field::OBJECT_LEAD:\n $objectId = $activity->lead_id;\n\n break;\n\n case Field::OBJECT_TASK:\n case Field::OBJECT_EVENT:\n $objectId = $activity->id;\n\n break;\n }\n\n if ($objectId) {\n /** @var FieldData $data */\n $data = $activity->data()->create([\n 'crm_layout_entity_id' => $entity->id,\n 'crm_field_id' => $entity->crm_field_id,\n 'object_type' => $entity->field->object_type,\n 'object_id' => $objectId,\n 'value' => $value,\n ]);\n\n // Never send read-only field data to the CRM.\n if ($entity->read_only === false && $entity->is_visible) {\n $existingValue = $existingData\n ->where('crm_layout_entity_id', $entity->id)\n ->where('crm_field_id', $entity->crm_field_id)\n ->where('object_type', $entity->field->object_type)\n ->where('object_id', $objectId)\n ->first();\n\n // If the field was actually changed, we need to reflect this in the CRM too.\n if ($existingValue === null || $existingValue->value !== $value) {\n $updatedData[] = $data->id;\n }\n }\n }\n }\n }\n }\n\n return $updatedData;\n }\n\n /**\n * Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.\n *\n * @param ServiceInterface $crmService\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array\n {\n $fieldData = [];\n foreach ($entities as $entityId => $value) {\n // Only bother with fields that have a value.\n if ($value) {\n // Extract the entity from the UUID. Check the field is valid and part of the follow-up section.\n $entity = $layout->entities()\n ->uuid($entityId, false)\n ->whereHas('parent', function ($query) {\n $query->where('label', 'follow-up');\n })\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->first();\n\n if ($entity) {\n // Convert raw data into values that the CRM can consume.\n $value = $crmService->normalizeValue($entity->field->type, $value);\n\n // Add the field and value to the payload.\n $fieldData += [\n $entity->field->crm_provider_id => $value,\n ];\n }\n }\n }\n\n return $fieldData;\n }\n\n /**\n * @param Activity $activity\n */\n private function validateSummary(Activity $activity): void\n {\n $team = $activity->user->team;\n $crmProvider = $team->crm->provider;\n $attributes = [];\n\n $rules = [\n 'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,\n 'title' => 'string|max:250',\n 'prospects' => 'required|array',\n 'opportunity_id' => new CrmReference($crmProvider),\n 'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',\n 'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator\n 'summary' => 'max:50000',\n 'nId' => 'exists:notifications,id',\n 'crm_id' => new CrmReference($crmProvider),\n 'entities' => 'array',\n 'is_internal' => 'boolean',\n ];\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));\n\n // Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.\n $entities = $layout->entities()\n ->where('read_only', 0)\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->whereHas('parent', function ($query) use ($activity) {\n if ($activity->isLoggable() === false) {\n $query->where('label', '<>', 'follow-up');\n }\n });\n\n $isInternal = $this->request->input('is_internal', false);\n\n foreach ($entities->get() as $entity) {\n $rules += $this->buildFieldValidator($entity, $isInternal);\n $attributes += $this->buildFieldMessage($entity);\n }\n\n $this->request->validate($rules, [], $attributes);\n }\n\n private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array\n {\n return [\n 'entities.' . $entity->id_string => $entity->getValidator($isInternal),\n ];\n }\n\n /**\n * @param LayoutEntity $entity\n *\n * @return array\n */\n private function buildFieldMessage(LayoutEntity $entity): array\n {\n $label = $entity->label;\n if ($label === null) {\n $label = $entity->field->label;\n }\n\n return [\n 'entities.' . $entity->id_string => $label,\n ];\n }\n\n public function search(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->debugLog(\n $user,\n 'User extracted from request',\n ['user' => $user->getId(), 'tz' => $user->getTimezone()]\n );\n\n $searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());\n\n $this->debugLog(\n $user,\n 'ActivitySearch criteria built',\n ['searchCriteria' => $searchCriteria]\n );\n\n $filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);\n\n $this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);\n\n $this->validateSearch($request, $filterSet);\n\n $this->debugLog($user, 'Request validated');\n\n $searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);\n\n /** @var Collection<Activity> $activities */\n $activities = $searchResponse['results'];\n\n $this->debugLog($user, 'Activities ES response extracted');\n\n $hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(\n $user->getTeamId(),\n TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),\n );\n\n if ($hideInternalMeetingsSetting?->getValue() === '1') {\n $activities = $activities->filter(function (Activity $activity) {\n if ($activity->is_internal && empty($activity->actual_start_time)) {\n return false;\n }\n\n return true;\n });\n }\n\n $this->debugLog($user, 'Internal meetings (?!) filtered');\n\n $this->response->getManager()\n ->parseIncludes([\n 'category',\n 'organizer.group',\n 'prospect',\n 'stage',\n 'opportunity',\n 'stats',\n 'scorecards',\n 'masterTrack',\n 'activeParticipants',\n 'notification',\n ])\n ->setSerializer(new JsonSerializer());\n\n $transformerExcludes = $this->request->input('exclude');\n if ($transformerExcludes) {\n $this->response->getManager()->parseExcludes($transformerExcludes);\n }\n\n $this->debugLog($user, 'Response Manager (?!) applied');\n\n $transformer = new ActivityTransformer();\n $transformer->setConsumer($user);\n\n $this->debugLog($user, 'Activity Transformer added');\n\n $resource = new \\League\\Fractal\\Resource\\Collection($activities, $transformer);\n $page = $searchCriteria->getPageNumber();\n\n $this->debugLog($user, 'Search criteria page number called', ['page' => $page]);\n\n $histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');\n\n $this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);\n\n return $this->response->withArray([\n 'pagination' => [\n 'total' => $searchResponse['totalHits'],\n 'current' => $page,\n 'prev' => max($page - 1, 1),\n 'next' => $page + 1,\n ],\n 'results' => $this->response->getManager()->createData($resource)->toArray(),\n 'histogram' => $histogram,\n ]);\n }\n\n private function debugLog(User $user, string $logMessage, ?array $context = []): void\n {\n // Debug for Learning People Only\n if ($user->getTeamId() !== 260) {\n return;\n }\n\n Log::notice(\n sprintf('[activity-search-controller] %s', $logMessage),\n $context\n );\n }\n\n /** @throws ValidationException */\n private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void\n {\n $rules = [\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ];\n\n if ($prefix !== null && mb_strpos($prefix, '.') !== false) {\n $rules[rtrim($prefix, '.')] = sprintf(\n 'required|array|max:%d',\n $filterSet->count()\n );\n }\n\n $validationRules = $filterSet->getValidationRules($prefix)\n ->merge($rules)\n ->all();\n\n $request->validate($validationRules);\n }\n\n public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $search = $this->updateOrCreateActivitySearch($request);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function updateActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('update', $search);\n\n $this->updateOrCreateActivitySearch($request, $search);\n\n return $this->response->withOk();\n }\n\n private function storeNamedSearchFilters(\n Collection $request,\n Search $search,\n FilterDefinitionCollection $filterSet,\n ?string $prefix = null,\n ): self {\n $arrayTypeProperties = $filterSet\n ->getPropertyTypes([\n FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,\n ])\n ->all();\n\n $supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);\n\n foreach ($supportedRequestProperties as $requestPropertyName) {\n if (! array_has($request, $requestPropertyName)) {\n continue;\n }\n\n /** @var string|string[] $propertyValue */\n $propertyValue = array_get($request, $requestPropertyName);\n $propertyName = $prefix === null\n ? $requestPropertyName\n : mb_substr($requestPropertyName, mb_strlen($prefix));\n\n $isArrayType = array_has($arrayTypeProperties, $propertyName);\n\n if (! $isArrayType) {\n /** @var string $requestPropertyValue */\n\n $search->filters()->updateOrCreate(\n [\n 'filter' => $propertyName,\n ],\n [\n 'value' => $propertyValue,\n ]\n );\n\n continue;\n }\n\n /** @var string[] $requestPropertyValue */\n\n /** @var SearchFilter[]|Collection $existingFilterValues */\n $existingFilterValuesKeyed = $search->filters()\n ->where('filter', $propertyName)\n ->get()\n ->keyBy('id');\n\n // Iterate over values provided as request parameters\n foreach ($propertyValue as $value) {\n /** @var SearchFilter|null $valueFilter */\n $valueFilter = $search->filters()\n ->where(\n [\n 'filter' => $propertyName,\n 'value' => $value,\n ]\n )\n ->first();\n\n if ($valueFilter !== null) {\n // Remove filter value pair from list to be deleted\n $existingFilterValuesKeyed->forget($valueFilter->id);\n } else {\n // Add new filter/value pair\n $search->filters()->updateOrCreate([\n 'filter' => $propertyName,\n 'value' => $value,\n ]);\n }\n }\n\n // Delete filter value pairs for this filter that no longer exist in request parameters\n foreach ($existingFilterValuesKeyed as $existingFilter) {\n $existingFilter->delete();\n }\n }\n\n /** @var Collection<int, SearchFilter> $filtersKeyed */\n $filtersKeyed = $search->filters()->get()->keyBy('filter');\n\n // wipe removed filters from this search\n foreach ($filtersKeyed as $filterName => $filter) {\n if (array_has($request, $prefix . $filterName)) {\n continue;\n }\n\n // Remove all filter values for this filter\n $search->filters()->where('filter', $filterName)->delete();\n }\n\n return $this;\n }\n\n /**\n * @throws AuthorizationException\n */\n public function fetchActivitySearch(\n Search $search,\n Request $request,\n SearchTransformer $searchTransformer,\n ): JsonResponse {\n $this->authorize('view', $search);\n\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection(\n $user->searches()->get(),\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n /**\n * Deletes a saved search\n *\n * @param Request $request\n * @param Search $search\n *\n * @throws Exception\n *\n * @return JsonResponse\n */\n public function deleteActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('delete', $search);\n\n // Orphan any AutomatedReports that use this search\n $search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);\n\n // Delete filters and the search itself\n $search->filters()->delete();\n $search->delete();\n\n return $this->response->withOk();\n }\n\n public function live(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n $user = $this->getUserFromRequest($request);\n\n $this->request->validate([\n 'sort_direction' => 'in:asc,desc',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ]);\n\n $activities = $repository->getLiveCoachingEligibleActivities(\n user: $user,\n lookBackMinutes: self::LOOK_BACK,\n limit: (int) $this->request->input('limit', 25),\n page: (int) $this->request->input('page', 1),\n sortBy: ['actual_start_time', 'scheduled_start_time'],\n sortDirection: (string) $this->request->input('sort_direction', 'asc'),\n );\n\n $this->response\n ->getManager()\n ->parseIncludes(['organizer.group', 'prospect'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($activities, new ActivityTransformer());\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function show(Activity $activity, ActivityService $activityService): JsonResponse\n {\n $this->authorize('show', $activity);\n\n $user = $activity->getUser();\n $team = $user->getTeam();\n\n // Sync the opportunity with the latest data if possible.\n if ($activity->opportunity_id) {\n try {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n if (! $user->isCrmRequired()) {\n $crmService->setUser($team->getOwner());\n } else {\n $crmService->setUser($user);\n }\n\n $crmService->syncOpportunity($activity->opportunity->crm_provider_id);\n } catch (Exception $exception) {\n // Move on.\n }\n }\n\n $activityData = $activityService->getActivityData($this->request->user(), $activity);\n\n return response()->json($activityData);\n }\n\n public function createRecording(Activity $activity)\n {\n $this->authorize('record', $activity);\n\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Tell Twilio to start recording this activity.\n if ($activity->recording_state === Activity::RECORDING_OFF) {\n $job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withCreated();\n }\n\n return $this->response->errorGone('Activity is already recording.');\n }\n\n public function updateRecording(Request $request, Activity $activity)\n {\n $this->authorize('record', $activity);\n\n $request->validate([\n 'preference' => 'boolean',\n 'state' => [\n 'string',\n Rule::in([\n Activity::RECORDING_IN_PROGRESS,\n Activity::RECORDING_PAUSED,\n ]),\n ],\n ]);\n\n if ($request->has('state')) {\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Toggle the recording state between paused and resumed.\n if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {\n $job = (new ToggleRecording($activity, $request->input('state')))\n ->onQueue(Constants::QUEUE_CONFERENCES);\n\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Recording is not toggleable.');\n }\n\n if ($request->has('preference')) {\n $activity->update([\n 'recording_preference' => $request->input('preference') ? 1 : 0,\n ]);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorWrongArgs('Something went wrong');\n }\n\n public function stopRecording(Activity $activity)\n {\n $this->authorize('stopRecord', $activity);\n\n // Tell Twilio to stop recording this activity.\n if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {\n $job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Activity is not recording.');\n }\n\n /**\n * Add activity to this user's favorites playlist\n *\n * @throws AuthorizationException\n */\n public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse\n {\n $this->authorize('favorite', $activity);\n\n $user = $this->getUserFromRequest($this->request);\n $favorite = $activity->wasFavoritedBy($user);\n $name = $activity->activity_title ?? '';\n\n // It needs to check at least one record.\n if (! $favorite) {\n $favoritePlaylist = $user->favoritePlaylist();\n\n $playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(\n $activity,\n $user,\n $favoritePlaylist\n );\n\n if ($playlistActivity !== null) {\n $playlistActivity->update(\n // Just update, don't sort.\n ['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],\n );\n } else {\n $playlistActivity = $activity->playlistActivities()->create([\n 'playlist_id' => $favoritePlaylist->getId(),\n 'user_id' => $user->getId(),\n 'start_time' => 0,\n 'name' => mb_strimwidth($name, 0, 100),\n ]);\n // Sort it on top.\n $playlistActivity->update(\n [\n 'sort' => $playlistActivityRepository->calculateNewSortOrder(\n null,\n $playlistActivity,\n ),\n ],\n );\n }\n\n $playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);\n\n return new JsonResponse([], JsonResponse::HTTP_CREATED);\n }\n\n return new JsonResponse(\n [\n 'error' => [\n 'code' => AbstractResponse::CODE_CONFLICT,\n 'http_code' => JsonResponse::HTTP_CONFLICT,\n 'message' => 'Resource Already Exists',\n ],\n ],\n JsonResponse::HTTP_CONFLICT,\n );\n }\n\n /**\n * Remove activity from this user's favorites playlist\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unfavorite(Activity $activity)\n {\n $user = $this->request->user();\n\n $favorites = $activity->favoritedBy($user);\n\n if ($favorites && $favorites->isEmpty()) {\n return $this->response->errorNotFound('Favorite not found.');\n }\n\n $this->authorize('unfavorite', [$activity, $favorites]);\n\n // When you unfavorite an activity,\n // it should remove all the activities in it, including snippets.\n $isDeleted = $favorites->each(function ($favorite) {\n $favorite->forceDelete();\n });\n\n if ($isDeleted) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not remove favorite.');\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function notify(Activity $activity)\n {\n $this->authorize('notify', $activity);\n\n $user = $this->request->user();\n\n $existingNotification = $activity->availabilityNotifications()\n ->where('user_id', $user->id)\n ->exists();\n\n if ($existingNotification) {\n return $this->response->errorWrongArgs('Notification is already configured.');\n }\n\n $notification = Activity\\AvailabilityNotification::create([\n 'user_id' => $user->id,\n 'activity_id' => $activity->id,\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($notification, new AvailabilityNotificationTransformer());\n }\n\n /**\n * @param Activity $activity\n * @param Activity\\AvailabilityNotification $notification\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unnotify(Activity $activity, Activity\\AvailabilityNotification $notification)\n {\n $this->authorize('unnotify', [$activity, $notification]);\n\n if ($notification->sent_at || $notification->delete()) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not delete notification.');\n }\n\n public function play(Request $request, Activity $activity)\n {\n $this->authorize('stream', $activity);\n\n $request->validate([\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $activity->plays()->create([\n 'user_id' => $user->getId(),\n 'start_time' => $request->input('start_time'),\n ]);\n\n return $this->response->withCreated();\n }\n\n /**\n * @param Activity $activity\n *\n * @return mixed\n */\n public function comment(Activity $activity)\n {\n return $this->newComment($activity);\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @return mixed\n */\n public function replyComment(Activity $activity, Comment $comment)\n {\n return $this->newComment($activity, $comment);\n }\n\n /**\n * @param Activity $activity\n * @param Comment|null $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n protected function newComment(Activity $activity, ?Comment $comment = null)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n 'type' => 'integer|between:0,3',\n 'visibility' => sprintf('nullable|integer|between:1,%d', count(Comment::getVisibilityLevels())),\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n $threadStartId = null;\n if ($comment) {\n $threadStartId = $comment->thread_start_id ?: $comment->id;\n }\n\n try {\n $newComment = Comment::create([\n 'parent_comment_id' => $comment->id ?? null,\n 'thread_start_id' => $threadStartId,\n 'activity_id' => $activity->id,\n 'user_id' => $this->request->user()->id,\n 'comment' => trim($this->request->input('comment')),\n 'start_time' => $this->request->input('start_time', 0),\n 'end_time' => $this->request->input('end_time', 0),\n 'type' => $this->request->input('type', Comment::TYPE_NEUTRAL),\n 'visibility' => $this->request->input('visibility', Comment::VISIBILITY_PUBLIC),\n ]);\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($newComment, new ActivityCommentTransformer());\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not create comment.' . $exception->getMessage());\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function updateComment(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n try {\n $comment->update([\n 'comment' => trim($this->request->input('comment')),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment.');\n }\n }\n\n public function updateCommentVisibility(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'visibility' => sprintf('integer|between:1,%d', count(Comment::getVisibilityLevels())),\n ]);\n\n $visibility = $this->request->input('visibility');\n\n if ($comment->parent !== null) {\n return $this->response->errorWrongArgs('Comment visibility can only be updated on top level comments.');\n }\n\n try {\n $this->activityCommentService->updateCommentVisibility($comment, $visibility);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment\\'s visibility.');\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function deleteComment(Activity $activity, Comment $comment)\n {\n $this->authorize('deleteComment', [$activity, $comment]);\n\n // Delete comment and any children.\n $comment->delete();\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function fetchComments()\n {\n $user = $this->request->user();\n $this->request->validate([\n 'forUserId' => 'uuid:users,team_id,' . $user->team_id,\n 'types' => 'array',\n 'types.*' => 'integer|between:0,3',\n ]);\n $forUser = null;\n\n $types = [Comment::TYPE_NEUTRAL, Comment::TYPE_GAME_CHANGER, Comment::TYPE_POSITIVE];\n $user = $this->request->user();\n if ($this->request->has('forUserId')) {\n $forUser = $user->team->users()->uuid($this->request->input('forUserId'));\n }\n\n $comments = Comment::query()\n ->whereHas('activity', static function (Builder $builder) use ($user, $forUser): void {\n $builder\n // I left feedback on my own activity; or\n ->where('activities.user_id', $user->getId());\n if ($forUser) {\n // I left feedback on any activity for this user.\n $builder->orWhere([\n 'user_id' => $user->getId(),\n 'activities.user_id' => $forUser->getId(),\n ]);\n }\n })\n ->whereIn('type', $this->request->input('types', $types))\n ->orderBy('created_at', 'desc')\n ->get();\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity', 'user'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($comments, new ActivityCommentTransformer());\n }\n\n public function deleteCoachingFeedback(Activity $activity, CoachingFeedback $coachingFeedback)\n {\n $this->authorize('deleteCoachingFeedback', [$activity, $coachingFeedback]);\n $activity = $coachingFeedback->getActivity();\n\n if ($coachingFeedback->delete()) {\n event(new UpdateSingleEntity(\n entityId: $activity->getId(),\n updateTarget: UpdateTargetEnum::ACTIVITY,\n purpose: 'delete-coaching-feedback',\n ));\n\n return $this->response->withOk();\n }\n\n return $this->response->withError('Delete operation failed. Contact support.', 500);\n }\n\n /**\n * Add new or update Coaching feedback\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws \\Illuminate\\Validation\\ValidationException\n *\n * @return mixed\n */\n public function putCoachingFeedback(Request $request, Activity $activity)\n {\n $user = $request->user();\n\n if (! $user instanceof User) {\n abort(403);\n }\n $teamId = $user->getTeamId();\n\n $this->authorize('coach', $activity);\n\n $this->request->validate([\n 'coach_id' => 'required|uuid:users,team_id,' . $teamId,\n 'coachee_id' => 'required|uuid:users,team_id,' . $teamId,\n 'visibility' => ['required', Rule::in(CoachingFeedback::VISIBILITIES)],\n 'coaching_sections.*.uuid' => 'required|uuid:coaching_sections',\n 'coaching_sections.*.score' => ['required', Rule::in(CoachingSectionFeedback::SCORES)],\n 'coaching_sections.*.summary' => 'string|max:10000',\n 'coaching_sections.*.criteria.*.uuid' => 'required|uuid:coaching_section_criteria',\n 'coaching_sections.*.criteria.*.note' => 'required|string|max:10000',\n 'sharedWithUsers' => [\n 'required_if:visibility,' . CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS,\n 'array',\n ],\n 'sharedWithUsers.*' => [\n 'uuid:users,team_id,' . $teamId,\n ],\n ]);\n\n /** @var User $coach */\n $coach = User::uuid($this->request->input('coach_id'));\n /** @var User $coachee */\n $coachee = User::uuid($this->request->input('coachee_id'));\n $coachingSectionFeedbacks = $this->request->input('coaching_sections');\n\n $previousRecord = $this->coachingFeedbackRepository->getOneForActivityByCoacheeAndCoach(\n $coachee->getId(),\n $coach->getId(),\n $activity->getId()\n );\n $recordIsNew = false;\n if ($previousRecord === null) {\n $recordIsNew = true;\n }\n\n if (! $coachee->isSameTeamId($coach)) {\n return $this->response->errorForbidden('User not member of your team.');\n }\n\n if (! is_array($coachingSectionFeedbacks) || count($coachingSectionFeedbacks) < 1) {\n return $this->response->withError('At least one Coaching Framework Section shall be scored.', 422);\n }\n\n if (! $activity->participants()->where('participants.user_id', $coachee->id)->exists()) {\n return $this->response->withError('Coached user did not participate activity.', 422);\n }\n\n $visibility = $this->request->input('visibility');\n\n $shouldSendNotification = $recordIsNew;\n if ($recordIsNew === false && $visibility !== $previousRecord->getVisibility()) {\n $shouldSendNotification = true;\n }\n\n /**\n * Create CoachingFeedback\n *\n * @var CoachingFeedback $coachingFeedback\n */\n $coachingFeedback = $activity->coachingFeedbacks()->updateOrCreate(\n [\n 'coach_id' => $coach->id,\n 'coachee_id' => $coachee->id,\n ],\n [\n 'framework_id' => $activity->category->id,\n 'visibility' => $visibility,\n ]\n );\n\n $sharedUserIds = [];\n if ($visibility === CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS) {\n foreach ($this->request->input('sharedWithUsers') as $sharedWithUserUuid) {\n /** @var User $user */\n $user = User::uuid($sharedWithUserUuid);\n $sharedUserIds[] = $user->getId();\n }\n }\n\n $syncResult = $coachingFeedback->customAccessUsers()->sync($sharedUserIds);\n\n $scores = [];\n\n\n /**\n * Create CoachingSectionsFeedbacks.\n *\n * @var CoachingSectionFeedback $coachingSectionFeedback\n */\n foreach ($coachingSectionFeedbacks as $coachingSectionFeedbackInput) {\n $coachingSection = CoachingSection::uuid($coachingSectionFeedbackInput['uuid']);\n $coachingSectionFeedback = $coachingFeedback->sectionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_id' => $coachingSection->id,\n ],\n [\n 'score' => array_get($coachingSectionFeedbackInput, 'score'),\n 'summary' => array_get($coachingSectionFeedbackInput, 'summary') ?? '',\n ]\n );\n\n $scores[] = array_get($coachingSectionFeedbackInput, 'score');\n\n $criteria = array_get($coachingSectionFeedbackInput, 'criteria');\n if (is_array($criteria) && ! empty($criteria)) {\n foreach ($criteria as $criteriaFeedbackInput) {\n $coachingSectionFeedback->criterionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_criterion_id' => CoachingSectionCriterion::uuid(array_get($criteriaFeedbackInput, 'uuid'))\n ->id,\n ],\n ['note' => array_get($criteriaFeedbackInput, 'note')],\n );\n }\n }\n }\n\n $coachingFeedback->average_score = array_sum($scores) / count($scores);\n\n if ($recordIsNew === false && $coachingFeedback->getAverageScore() !== $previousRecord->getAverageScore()) {\n $shouldSendNotification = true;\n }\n if (! empty($syncResult['attached']) || ! empty($syncResult['detached']) || ! empty($syncResult['updated'])) {\n $shouldSendNotification = true;\n }\n\n $coachingFeedback->save();\n // ensure updated at for coaching feedback on section feedback summary added.\n $coachingFeedback->touch();\n\n if ($shouldSendNotification) {\n event(new Coached($coachingFeedback));\n }\n\n Datadog::increment('jiminny.activity.score.update', 1, ['company' => $activity->user->team->slug]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n $coachingFeedbackTransformer = new CoachingFeedbackTransformer();\n $coachingFeedbackTransformer->setConsumer($this->getUserFromRequest($request));\n\n return $this->response->withItem($coachingFeedback, $coachingFeedbackTransformer);\n }\n\n\n /**\n * Retrieve category criteria for coaching.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachingSections(Activity $activity)\n {\n $this->authorize('coach', $activity);\n\n if ($activity->category === null) {\n return $this->response->errorUnprocessable('Category has not yet been assigned.');\n }\n\n $criteria = $activity\n ->category\n ->coachingSections()\n ->where('is_enabled', 1)\n ->orderBy('sequence', 'asc');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($criteria->get(), new CoachingSectionsTransformer());\n }\n\n /**\n * @throws AuthorizationException\n * @throws ValidationException\n *\n * @return mixed\n */\n public function addToPlaylist(Activity $activity, PlaylistTrackFactoryInterface $playlistTrackFactory)\n {\n $this->request->validate([\n 'playlists' => 'required|array',\n 'playlists.*' => 'uuid:playlists',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'name' => 'required|max:100',\n ]);\n\n $this->authorize('addToPlaylist', [$activity, $this->request->input('playlists')]);\n\n $startTime = $this->request->input('start_time');\n $endTime = $this->request->input('end_time');\n $name = $this->request->input('name');\n /** @var User $user */\n $user = $this->request->user();\n\n // Get playlist by uuid.\n foreach ($this->request->input('playlists') as $playlistId) {\n // Pull out the playlist model.\n $playlist = Playlist::uuid($playlistId);\n\n $playlistTrackFactory->createTrack($playlist, $user, [\n 'name' => $name,\n 'activity' => $activity,\n 'start_time' => $startTime,\n 'end_time' => $endTime,\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function share(Request $request, Activity $activity): JsonResponse\n {\n $this->authorize('share', $activity);\n\n $request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'recipients.*.type' => 'in:user,group',\n 'recipients.*.id' => 'string|max:40',\n 'share' => 'string|max:255',\n ]);\n\n $user = $request->user();\n\n $recipients = $request->get('recipients');\n $users = $this->userService->convertRecipientsToUsers($user, $recipients);\n\n $shareData = [\n 'from_user_id' => $user->id,\n 'note' => $request->input('note'),\n 'start_time' => $request->input('start_time'),\n 'end_time' => $request->input('end_time'),\n ];\n\n // Create a share object against a notification provider channel\n if ($request->input('share')) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'notification_provider_channel' => $request->input('share'),\n ]\n )\n );\n\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n\n // Create a share object against each recipient\n foreach ($users as $recipient) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'to_user_id' => $recipient->id,\n ]\n )\n );\n\n // If parent_share_id has been selected yet\n if (! isset($shareData['parent_share_id'])) {\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachRequest(Activity $activity)\n {\n $this->authorize('coachRequest', $activity);\n\n $this->request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'coachers.*.type' => 'required|in:user',\n 'coachers.*.id' => 'required',\n ]);\n\n $coachers = $this->request->get('coachers');\n $user = $this->request->user();\n $users = $this->userService->convertRecipientsToUsers($user, $coachers);\n\n foreach ($users as $coacher) {\n CoachRequest::create([\n 'user_id' => $coacher->id,\n 'activity_id' => $activity->id,\n 'note' => $this->request->get('note'),\n 'start_time' => $this->request->get('start_time'),\n 'end_time' => $this->request->get('end_time'),\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function createActivityTopicTriggers(Activity $activity, LoggerInterface $logger): HttpFoundation\\JsonResponse\n {\n $this->authorize('analyzeTopicTriggers', $activity);\n\n if (! $activity->hasTranscription()) {\n return new HttpFoundation\\JsonResponse(\n [\n 'error' => 'Transcription not found.',\n ],\n JsonResponse::HTTP_NOT_FOUND\n );\n }\n\n $logger->info(__METHOD__ . ': queued for analysis', [\n 'activity' => $activity->id_string,\n ]);\n\n dispatch(new ActivityAnalytics\\Job\\AnalyzeActivityTopicTriggers($activity));\n\n return new HttpFoundation\\JsonResponse(null, JsonResponse::HTTP_CREATED);\n }\n\n public function fetchActivityTopicTriggers(\n Activity $activity,\n LoggerInterface $logger,\n ActivityTopicTriggerTransformer $transformer\n ): HttpFoundation\\JsonResponse {\n $this->authorize('fetchTopicTriggers', $activity);\n\n $logger->debug(__METHOD__, [\n 'activity' => $activity->id_string,\n ]);\n\n if (! $activity->isProcessed()) {\n return new HttpFoundation\\JsonResponse([]);\n }\n\n $payload = [];\n\n if ($activity->hasTopicTriggers()) {\n $payload = $activity->getTopicTriggersSorted()\n ->map(\n static fn (Activity\\TopicTrigger $activityTopicTrigger): array\n => $transformer->transform($activityTopicTrigger)\n )\n ->values()\n ->all();\n }\n\n return new HttpFoundation\\JsonResponse($payload);\n }\n\n /**\n * @param Activity $activity\n * @param StatsTransformer $statsTransformer\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function stats(Activity $activity, StatsTransformer $statsTransformer)\n {\n $this->authorize('stream', $activity);\n\n if (! $activity->hasTranscription()) {\n return $this->response->errorNotFound('Waveform data is not yet generated.');\n }\n\n $this->response\n ->getManager()\n ->parseIncludes(['wavedata'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($activity, $statsTransformer);\n }\n\n public function destroy(Activity $activity)\n {\n $this->authorize('delete', $activity);\n\n $activity->delete();\n\n \\Log::info('Soft delete activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n\n return $this->response->withNoContent();\n }\n\n public function note(Activity $activity)\n {\n $this->authorize('note', $activity);\n\n $this->request->validate([\n 'note' => 'required|min:1|max:2000',\n 'time' => 'required|numeric|min:0|max:86400',\n ]);\n\n $note = $this->request->input('note');\n $time = $this->request->input('time');\n\n $this->activityService->setActivity($activity);\n $this->activityService->takeNote($this->getUser(), $note, $time);\n\n return $this->response->withCreated();\n }\n\n /**\n * Mark an activity as private.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPrivate(Activity $activity)\n {\n $this->authorize('markAsPrivate', $activity);\n\n if ($activity->is_private === false) {\n $activity->is_private = true;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * Mark an activity as public.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPublic(Activity $activity)\n {\n $this->authorize('markAsPublic', $activity);\n\n if ($activity->is_private) {\n $activity->is_private = false;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws LogicException\n */\n public function fetchCloudFrontS3MediaKeys(Activity $activity, PlaybackService $playbackService): JsonResponse\n {\n $masterTrack = $activity->masterTrack()->first();\n\n if (! $masterTrack instanceof Track) {\n throw new LogicException(sprintf('Master track not found for activity \"%s\"', $activity->getUuid()));\n }\n\n return $this->response->withArray(\n $playbackService->generateCookies(\n $masterTrack,\n $this->request->ip(),\n ),\n );\n }\n\n /**\n * @throws ValidationException\n */\n private function updateOrCreateActivitySearch(Request $request, ?Search $search = null): Search\n {\n $request->validate([\n 'name' => 'required|string|min:2|max:100',\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $searchName = $request->input('name');\n\n if ($search !== null) {\n $search->update([\n 'name' => $searchName,\n ]);\n\n return $search;\n }\n\n $request->validate([\n 'filters' => ['required', 'array', new MultidimensionalArrayMaxCharRule(limit: 255)],\n 'nudges' => 'array|max:' . count(Nudge::MAP_CHANNEL),\n 'nudges.*.channel' => 'required|in:' . implode(',', Nudge::MAP_CHANNEL),\n 'nudges.*.frequency' => 'required|in:' . implode(',', Nudge::MAP_FREQUENCY),\n 'nudges.*.expiresAt' => [\n 'required',\n 'date',\n 'after:today',\n 'before_or_equal:' . now()->addYear()->format('Y-m-d'),\n ],\n ]);\n\n $searchCriteria = Criteria::createFromRequest(\n Collection::make($request->input('filters', []))->all(),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($searchCriteria, $user);\n $this->validateSearch($request, $filterSet, 'filters.');\n\n /** @var Search $search */\n $search = Search::create([\n 'name' => $searchName,\n 'uuid' => Uuid::uuid4()->toString(),\n 'user_id' => $user->getId(),\n ]);\n\n Collection::make($request->input('nudges', []))\n ->each(fn (array $attributes): Nudge => $this->nudgeFactory->createNudge($search, $attributes));\n\n $this->storeNamedSearchFilters(Collection::make($request->all()), $search, $filterSet, 'filters.');\n\n return $search;\n }\n\n private function resolveAccount(\n Team $team,\n Contact $contact,\n ServiceInterface $crmService,\n array $prospects,\n ): ?Account {\n $this->logger->info('Resolving account from contact');\n $account = $contact->getAccount();\n\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS)) {\n $this->logger->info('Team does not have feature to link activity to multiple prospects');\n\n return $account;\n }\n\n $this->logger->info('Resolving account from prospect data');\n $accountData = array_filter(\n $prospects,\n static fn (array $prospectData): bool => $prospectData['type'] === 'account'\n );\n\n if (! empty($accountData)) {\n $this->logger->info('Found account data in prospects');\n $accountData = reset($accountData);\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountData['id'])->first();\n\n if (! $account instanceof Account) {\n $this->logger->info('Account not found in database, syncing from CRM');\n $account = $crmService->syncAccount($accountData['id']);\n }\n }\n\n $this->logger->info('Resolved account', ['account' => $account->getId()]);\n\n return $account;\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Http\\Controllers\\API;\n\nuse Carbon\\Carbon;\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Exception;\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Validation\\Rule;\nuse Illuminate\\Validation\\Rules\\In;\nuse Illuminate\\Validation\\ValidationException;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ActivityAnalytics;\nuse Jiminny\\Component\\ActivitySearch;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Contracts\\ES\\Events\\UpdateSingleEntity;\nuse Jiminny\\Contracts\\ES\\UpdateTargetEnum;\nuse Jiminny\\Contracts\\Nudge\\NudgeFactoryInterface;\nuse Jiminny\\Contracts\\Playlist\\PlaylistTrackFactoryInterface;\nuse Jiminny\\Contracts\\Repositories\\PlaylistActivityRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Enums\\TeamSetting;\nuse Jiminny\\Events\\Activities\\AiAutomation\\ActivityProspectAdded;\nuse Jiminny\\Events\\Activities\\Coaching\\Coached;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Controllers\\CommentContextInterface;\nuse Jiminny\\Http\\Responses\\Api\\AbstractResponse;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\ActivityCommentTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTopicTriggerTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTransformer;\nuse Jiminny\\Http\\Transformers\\AvailabilityNotificationTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingFeedbackTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingSectionsTransformer;\nuse Jiminny\\Http\\Transformers\\SearchTransformer;\nuse Jiminny\\Http\\Transformers\\StatsTransformer;\nuse Jiminny\\Jobs\\Crm\\SaveActivity;\nuse Jiminny\\Jobs\\Crm\\UpdateStage;\nuse Jiminny\\Jobs\\Telephony\\StartRecording;\nuse Jiminny\\Jobs\\Telephony\\StopRecording;\nuse Jiminny\\Jobs\\Telephony\\ToggleRecording;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\CoachingFeedback;\nuse Jiminny\\Models\\CoachingSection;\nuse Jiminny\\Models\\CoachingSectionCriterion;\nuse Jiminny\\Models\\CoachingSectionFeedback;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\LanguageDialect;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Nudge;\nuse Jiminny\\Models\\PlaybookCategory;\nuse Jiminny\\Models\\Playlist;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\Track;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\CoachingFeedbackRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Rules\\MultidimensionalArrayMaxCharRule;\nuse Jiminny\\Services\\ActivityService;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Services\\PlaybackService;\nuse Jiminny\\Services\\UserService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\nuse Ramsey\\Uuid\\Uuid;\nuse Sentry;\nuse Symfony\\Component\\HttpFoundation;\n\nfinal class ActivityController extends Controller implements CommentContextInterface\n{\n // Number of minutes to look back on activities. i.e. a timeout on activity duration.\n private const int LOOK_BACK = 180;\n\n public function __construct(\n private ProviderRegistry $providerRegistry,\n private ActivityService $activityService,\n Response $response,\n private UserService $userService,\n private ActivitySearch\\Service\\ActivitySearch $activitySearch,\n private NudgeFactoryInterface $nudgeFactory,\n private ActivityCommentService $activityCommentService,\n private LoggerInterface $logger,\n private readonly CoachingFeedbackRepository $coachingFeedbackRepository,\n private readonly TeamRepository $teamRepository,\n ) {\n parent::__construct($response);\n }\n\n public static function getCommentImplementation(): string\n {\n return Comment::class;\n }\n\n public function delete()\n {\n $this->request->validate([\n '*' => 'uuid:activities',\n ]);\n\n $deletedIds = [];\n foreach ($this->request->all() as $activityId) {\n $activity = Activity::idOrUuId($activityId);\n\n try {\n if ($this->authorize('delete', $activity)) {\n $activity->delete();\n $deletedIds[] = $activityId;\n\n \\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n }\n } catch (AuthorizationException $authorizationException) {\n // They didn't have permission.\n }\n }\n\n return $this->response->withArray($deletedIds);\n }\n\n public function update(Request $request, Activity $activity)\n {\n $this->authorize('updateMetadata', $activity);\n\n $request->validate([\n 'title' => 'string|max:250',\n 'category_id' => 'uuid:playbook_categories',\n 'language' => [\n new In(\n LanguageDialect::query()\n ->with('language')\n ->cursor()\n ->map(static function (LanguageDialect $languageDialect): string {\n return $languageDialect->getLanguageLocale();\n })\n ->all()\n ),\n ],\n ]);\n\n if ($request->has('title')) {\n $activity->title = $request->input('title');\n }\n\n if ($request->has('category_id')) {\n $category = PlaybookCategory::uuid($request->input('category_id'));\n\n if ($category->playbook->team_id !== $request->user()->team_id) {\n return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n if ($request->has('language')) {\n if (! $activity->isInProgress()) {\n return $this->response->withError(\n 'Activity language can only be set while the meeting is in progress.',\n 400\n );\n }\n\n $activity->setLanguageCode($request->input('language'));\n }\n\n $activity->save();\n\n return $this->response->withOk();\n }\n\n // XXX: This should be merged with the update method.\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws SocialAccountTokenInvalidException\n *\n * @return mixed\n */\n public function summarize(Activity $activity): mixed\n {\n $this->logger->info('[Log Activity] Summarizing activity ', [\n 'activityId' => $activity->getUuid(),\n 'payload' => $this->request->all(),\n ]);\n $this->authorize('update', $activity);\n\n $this->logger->info('[Log Activity] Validating summary');\n // Validate the payload.\n $this->validateSummary($activity);\n\n // All objects must belong to this team.\n /** @var User $user */\n $user = $this->request->user();\n $team = $user->getTeam();\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n try {\n $crmUser = $user;\n if ($user->isCrmRequired() === false) {\n $crmUser = $team->owner;\n }\n $crmService->setUser($crmUser);\n } catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());\n }\n\n $rawEntities = $this->request->input('entities');\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid(\n $this->request->input('layout_id')\n );\n\n // Delay execution of CRM jobs to avoid locking issues.\n $jobDelay = 0;\n\n // If we have arrived from a notification, mark it as read.\n $notificationId = $this->request->input('nId');\n if ($notificationId) {\n $notification = $user->unreadNotifications->where('id', $notificationId)->first();\n\n if ($notification) {\n $notification->markAsRead();\n }\n }\n\n $title = $this->request->input('title');\n $prospects = $this->request->input('prospects');\n $opportunityId = $this->request->input('opportunity_id');\n $stageId = $this->request->input('stage_id');\n $categoryId = $this->request->input('category_id');\n $summary = $this->request->input('summary');\n $crmProviderId = $this->request->input('crm_id');\n $isInternal = $this->request->input('is_internal') ?? false;\n\n $lead = null;\n $category = null;\n $account = null;\n $contact = null;\n $opportunity = null;\n $stage = null;\n $callStage = null;\n\n foreach ($prospects as $prospectData) {\n $objectId = $prospectData['id'];\n\n if ($objectId === null) {\n continue;\n }\n\n $objectType = $prospectData['type'];\n $this->logger->info('debug', ['prospect_data' => $prospectData]);\n\n try {\n if ($objectType === null) {\n $this->logger->info('no object type');\n if ($crmService instanceof SupportsObjectTypeParseInterface) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n }\n\n switch ($objectType) {\n case 'lead':\n $this->logger->info('Processing lead');\n /** @var Lead|null $lead */\n $lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();\n\n // Lead does not exist locally, import it.\n if ($lead === null) {\n $this->logger->info('Lead does not exist locally');\n /** @var Lead $lead */\n $lead = $crmService->syncLead($objectId);\n }\n\n $this->logger->info('Lead found', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n if ($stageId === null) {\n $this->logger->info('Stage ID is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $lead->stage;\n\n break;\n }\n\n $this->logger->info('Looking for stage');\n // Determine if they have changed the stage.\n /** @var Stage $stage */\n $stage = $team->crm->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_LEAD)\n ->firstOrFail();\n\n $this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);\n if ($lead->stage_id && $lead->stage_id !== $stage->id) {\n $this->logger->info('Stage has changed');\n // Storage current stage on activity.\n $callStage = $lead->stage;\n\n // The stage has changed, update in remote CRM.\n dispatch(new UpdateStage($activity, $lead, $callStage, $stage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing lead stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->getName(),\n $stage->getName()\n ),\n [\n 'user' => $user->getUuid(),\n 'lead' => $lead->getUuid(),\n ]\n );\n } else {\n $this->logger->info('Stage has not changed');\n // Stage remains as current.\n $callStage = $stage;\n }\n\n break;\n\n case 'account':\n $this->logger->info('Processing account');\n // If the object is not a lead, it should be an account.\n $account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();\n\n // Account does not exist locally, import it.\n if ($account === null) {\n $this->logger->info('Account does not exist locally');\n $account = $crmService->syncAccount($objectId);\n }\n\n $this->logger->info('Account found', ['accountId' => $account->id]);\n\n break;\n case 'contact':\n $this->logger->info('processing contact');\n $contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $this->logger->info('contact does not exist locally');\n $contact = $crmService->syncContact($objectId);\n }\n\n $this->logger->info('resolving account');\n $account = $this->resolveAccount($team, $contact, $crmService, $prospects);\n\n break;\n }\n\n // If they have specified an opportunity, retrieve this with stage.\n if ($opportunityId) {\n $this->logger->info('opportunity id is set');\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if ($opportunity === null) {\n $this->logger->info('opportunity does not exist locally');\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n if ($stageId === null) {\n $this->logger->info('stage id is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $opportunity->stage ?? null;\n } else {\n $this->logger->info('looking for stage');\n /** @var ?Stage $opportunityStage */\n $opportunityStage = $team->crm\n ->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n // There is a chance we still cannot import this opportunity.\n if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {\n $this->logger->info('opportunity stage has changed');\n // Storage current stage on activity.\n $callStage = $opportunity->stage;\n\n dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing opportunity stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->name,\n $opportunityStage->name\n ),\n [\n 'userId' => $user->id_string,\n 'opportunityId' => $opportunity->id_string,\n ]\n );\n } else {\n $this->logger->info('opportunity stage has not changed');\n // Stage remains as current.\n $callStage = $opportunityStage;\n }\n }\n }\n\n if ($crmProviderId) {\n // Cast $crmProviderId to string otherwise it won't use database index for some records\n $linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();\n\n // Check if this activity has already been assigned to a different activity.\n if ($linkedActivity && $linkedActivity->id !== $activity->id) {\n throw new InvalidArgumentException(\n 'Sorry, the linked task has already been logged under a different call. '\n . 'Please choose another linked task.'\n );\n }\n }\n } catch (InvalidArgumentException $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($exception->getMessage());\n } catch (Exception $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorInternalError(\n 'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'\n );\n }\n }\n\n if ($categoryId) {\n $category = PlaybookCategory::uuid($categoryId);\n\n if ($category->playbook->team_id !== $team->id) {\n throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n $this->logger->info('Prospect data', [\n 'lead_id' => $lead?->getId(),\n 'account_id' => $account?->getId(),\n 'contact_id' => $contact?->getId(),\n 'opportunity_id' => $opportunity?->getId(),\n 'stage_id' => $stage?->getId(),\n ]);\n\n if ($title) {\n $activity->title = $title;\n }\n\n if ($summary) {\n $activity->summary = $summary;\n }\n\n if ($crmProviderId) {\n $activity->crm_provider_id = $crmProviderId;\n }\n\n if ($callStage) {\n $this->logger->info('Setting stage id', ['stageId' => $callStage->id]);\n $activity->stage_id = $callStage->id;\n }\n\n if ($lead) {\n $this->logger->info('Setting lead id', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n // If we are changed from an account > lead, unset the account data.\n $this->logger->info('Unsetting account id, opportunity id, contact id, value');\n $activity->account_id = null;\n $activity->opportunity_id = null;\n $activity->contact_id = null;\n $activity->value = null;\n }\n\n if ($account) {\n $this->logger->info('Setting account id', ['accountId' => $account->id]);\n $activity->account_id = $account->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('unsetting lead id');\n $activity->lead_id = null;\n\n // Unset the contact if switching different accounts. Will be set up below if still applicable.\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {\n $this->logger->info('Unsetting contact id');\n $activity->contact_id = null;\n }\n }\n\n if ($opportunity) {\n $this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);\n $this->logger->info('unsetting lead id');\n $activity->opportunity_id = $opportunity->id;\n $activity->value = $opportunity->value;\n\n // If we are changed from an lead > account, unset the lead data.\n $activity->lead_id = null;\n }\n\n if ($contact) {\n $this->logger->info('setting contact id', ['contactId' => $contact->id]);\n $activity->contact_id = $contact->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('Unsetting lead id');\n $activity->lead_id = null;\n }\n\n $activity->is_internal = $isInternal;\n $activity->save();\n $activity->refresh();\n\n $this->logger->notice('Activity saved', [\n 'activity_id' => $activity->getId(),\n 'lead_id' => $activity->lead_id,\n 'account_id' => $activity->account_id,\n 'contact_id' => $activity->contact_id,\n 'opportunity_id' => $activity->opportunity_id,\n 'stage_id' => $activity->stage_id,\n 'crm_provider_id' => $activity->getCrmProviderId(),\n ]);\n\n // Store entities as field data on the activity.\n $updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);\n\n if ($activity->isLoggable()) {\n // Follow-up Task or Event data.\n $followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);\n\n $this->logger->info('CRM LOG manual log triggered', [\n 'activityId' => $activity->getUuid(),\n 'followupData' => $followupData,\n 'userId' => $user->getUuid(),\n ]);\n\n // Store data in the CRM.\n // ++add check for crm_required\n $job = new SaveActivity($activity, $followupData);\n\n if ($updatedData) {\n $job->delay(Carbon::now()->addMinutes($jobDelay));\n }\n\n dispatch($job);\n\n // Manually dispatch log for Opportunity or Prospect added\n if ($activity->hasOpportunity() || $activity->hasProspect()) {\n event(new ActivityProspectAdded(\n activity: $activity,\n eventSource: 'manually-log-crm-data'\n ));\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.\n *\n * @param ServiceInterface $service\n * @param Activity $activity\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array\n {\n $updatedData = [];\n $existingData = $activity->data()->get();\n\n // We need to delete any existing data to overwrite with latest values.\n $activity->data()->delete();\n\n $layoutEntities = $layout->entities()\n ->with('field', 'parent')\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->get();\n\n /** @var LayoutEntity $entity */\n foreach ($layoutEntities as $entity) {\n // If the user has provided a value for this entity\n if (array_key_exists($entity->id_string, $entities)) {\n $value = $entities[$entity->id_string];\n\n // Convert raw data into values that the CRM can consume.\n if ($value) {\n $value = $service->normalizeValue($entity->field->type, $value);\n }\n\n // Check the field is part of the activity-summary section.\n if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {\n // This is the internal database ID, not the external CRM ID.\n $objectId = null;\n\n switch ($entity->field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $objectId = $activity->account_id;\n\n break;\n\n case Field::OBJECT_CONTACT:\n $objectId = $activity->contact_id;\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n $objectId = $activity->opportunity_id;\n\n break;\n\n case Field::OBJECT_LEAD:\n $objectId = $activity->lead_id;\n\n break;\n\n case Field::OBJECT_TASK:\n case Field::OBJECT_EVENT:\n $objectId = $activity->id;\n\n break;\n }\n\n if ($objectId) {\n /** @var FieldData $data */\n $data = $activity->data()->create([\n 'crm_layout_entity_id' => $entity->id,\n 'crm_field_id' => $entity->crm_field_id,\n 'object_type' => $entity->field->object_type,\n 'object_id' => $objectId,\n 'value' => $value,\n ]);\n\n // Never send read-only field data to the CRM.\n if ($entity->read_only === false && $entity->is_visible) {\n $existingValue = $existingData\n ->where('crm_layout_entity_id', $entity->id)\n ->where('crm_field_id', $entity->crm_field_id)\n ->where('object_type', $entity->field->object_type)\n ->where('object_id', $objectId)\n ->first();\n\n // If the field was actually changed, we need to reflect this in the CRM too.\n if ($existingValue === null || $existingValue->value !== $value) {\n $updatedData[] = $data->id;\n }\n }\n }\n }\n }\n }\n\n return $updatedData;\n }\n\n /**\n * Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.\n *\n * @param ServiceInterface $crmService\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array\n {\n $fieldData = [];\n foreach ($entities as $entityId => $value) {\n // Only bother with fields that have a value.\n if ($value) {\n // Extract the entity from the UUID. Check the field is valid and part of the follow-up section.\n $entity = $layout->entities()\n ->uuid($entityId, false)\n ->whereHas('parent', function ($query) {\n $query->where('label', 'follow-up');\n })\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->first();\n\n if ($entity) {\n // Convert raw data into values that the CRM can consume.\n $value = $crmService->normalizeValue($entity->field->type, $value);\n\n // Add the field and value to the payload.\n $fieldData += [\n $entity->field->crm_provider_id => $value,\n ];\n }\n }\n }\n\n return $fieldData;\n }\n\n /**\n * @param Activity $activity\n */\n private function validateSummary(Activity $activity): void\n {\n $team = $activity->user->team;\n $crmProvider = $team->crm->provider;\n $attributes = [];\n\n $rules = [\n 'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,\n 'title' => 'string|max:250',\n 'prospects' => 'required|array',\n 'opportunity_id' => new CrmReference($crmProvider),\n 'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',\n 'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator\n 'summary' => 'max:50000',\n 'nId' => 'exists:notifications,id',\n 'crm_id' => new CrmReference($crmProvider),\n 'entities' => 'array',\n 'is_internal' => 'boolean',\n ];\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));\n\n // Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.\n $entities = $layout->entities()\n ->where('read_only', 0)\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->whereHas('parent', function ($query) use ($activity) {\n if ($activity->isLoggable() === false) {\n $query->where('label', '<>', 'follow-up');\n }\n });\n\n $isInternal = $this->request->input('is_internal', false);\n\n foreach ($entities->get() as $entity) {\n $rules += $this->buildFieldValidator($entity, $isInternal);\n $attributes += $this->buildFieldMessage($entity);\n }\n\n $this->request->validate($rules, [], $attributes);\n }\n\n private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array\n {\n return [\n 'entities.' . $entity->id_string => $entity->getValidator($isInternal),\n ];\n }\n\n /**\n * @param LayoutEntity $entity\n *\n * @return array\n */\n private function buildFieldMessage(LayoutEntity $entity): array\n {\n $label = $entity->label;\n if ($label === null) {\n $label = $entity->field->label;\n }\n\n return [\n 'entities.' . $entity->id_string => $label,\n ];\n }\n\n public function search(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->debugLog(\n $user,\n 'User extracted from request',\n ['user' => $user->getId(), 'tz' => $user->getTimezone()]\n );\n\n $searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());\n\n $this->debugLog(\n $user,\n 'ActivitySearch criteria built',\n ['searchCriteria' => $searchCriteria]\n );\n\n $filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);\n\n $this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);\n\n $this->validateSearch($request, $filterSet);\n\n $this->debugLog($user, 'Request validated');\n\n $searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);\n\n /** @var Collection<Activity> $activities */\n $activities = $searchResponse['results'];\n\n $this->debugLog($user, 'Activities ES response extracted');\n\n $hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(\n $user->getTeamId(),\n TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),\n );\n\n if ($hideInternalMeetingsSetting?->getValue() === '1') {\n $activities = $activities->filter(function (Activity $activity) {\n if ($activity->is_internal && empty($activity->actual_start_time)) {\n return false;\n }\n\n return true;\n });\n }\n\n $this->debugLog($user, 'Internal meetings (?!) filtered');\n\n $this->response->getManager()\n ->parseIncludes([\n 'category',\n 'organizer.group',\n 'prospect',\n 'stage',\n 'opportunity',\n 'stats',\n 'scorecards',\n 'masterTrack',\n 'activeParticipants',\n 'notification',\n ])\n ->setSerializer(new JsonSerializer());\n\n $transformerExcludes = $this->request->input('exclude');\n if ($transformerExcludes) {\n $this->response->getManager()->parseExcludes($transformerExcludes);\n }\n\n $this->debugLog($user, 'Response Manager (?!) applied');\n\n $transformer = new ActivityTransformer();\n $transformer->setConsumer($user);\n\n $this->debugLog($user, 'Activity Transformer added');\n\n $resource = new \\League\\Fractal\\Resource\\Collection($activities, $transformer);\n $page = $searchCriteria->getPageNumber();\n\n $this->debugLog($user, 'Search criteria page number called', ['page' => $page]);\n\n $histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');\n\n $this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);\n\n return $this->response->withArray([\n 'pagination' => [\n 'total' => $searchResponse['totalHits'],\n 'current' => $page,\n 'prev' => max($page - 1, 1),\n 'next' => $page + 1,\n ],\n 'results' => $this->response->getManager()->createData($resource)->toArray(),\n 'histogram' => $histogram,\n ]);\n }\n\n private function debugLog(User $user, string $logMessage, ?array $context = []): void\n {\n // Debug for Learning People Only\n if ($user->getTeamId() !== 260) {\n return;\n }\n\n Log::notice(\n sprintf('[activity-search-controller] %s', $logMessage),\n $context\n );\n }\n\n /** @throws ValidationException */\n private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void\n {\n $rules = [\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ];\n\n if ($prefix !== null && mb_strpos($prefix, '.') !== false) {\n $rules[rtrim($prefix, '.')] = sprintf(\n 'required|array|max:%d',\n $filterSet->count()\n );\n }\n\n $validationRules = $filterSet->getValidationRules($prefix)\n ->merge($rules)\n ->all();\n\n $request->validate($validationRules);\n }\n\n public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $search = $this->updateOrCreateActivitySearch($request);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function updateActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('update', $search);\n\n $this->updateOrCreateActivitySearch($request, $search);\n\n return $this->response->withOk();\n }\n\n private function storeNamedSearchFilters(\n Collection $request,\n Search $search,\n FilterDefinitionCollection $filterSet,\n ?string $prefix = null,\n ): self {\n $arrayTypeProperties = $filterSet\n ->getPropertyTypes([\n FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,\n ])\n ->all();\n\n $supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);\n\n foreach ($supportedRequestProperties as $requestPropertyName) {\n if (! array_has($request, $requestPropertyName)) {\n continue;\n }\n\n /** @var string|string[] $propertyValue */\n $propertyValue = array_get($request, $requestPropertyName);\n $propertyName = $prefix === null\n ? $requestPropertyName\n : mb_substr($requestPropertyName, mb_strlen($prefix));\n\n $isArrayType = array_has($arrayTypeProperties, $propertyName);\n\n if (! $isArrayType) {\n /** @var string $requestPropertyValue */\n\n $search->filters()->updateOrCreate(\n [\n 'filter' => $propertyName,\n ],\n [\n 'value' => $propertyValue,\n ]\n );\n\n continue;\n }\n\n /** @var string[] $requestPropertyValue */\n\n /** @var SearchFilter[]|Collection $existingFilterValues */\n $existingFilterValuesKeyed = $search->filters()\n ->where('filter', $propertyName)\n ->get()\n ->keyBy('id');\n\n // Iterate over values provided as request parameters\n foreach ($propertyValue as $value) {\n /** @var SearchFilter|null $valueFilter */\n $valueFilter = $search->filters()\n ->where(\n [\n 'filter' => $propertyName,\n 'value' => $value,\n ]\n )\n ->first();\n\n if ($valueFilter !== null) {\n // Remove filter value pair from list to be deleted\n $existingFilterValuesKeyed->forget($valueFilter->id);\n } else {\n // Add new filter/value pair\n $search->filters()->updateOrCreate([\n 'filter' => $propertyName,\n 'value' => $value,\n ]);\n }\n }\n\n // Delete filter value pairs for this filter that no longer exist in request parameters\n foreach ($existingFilterValuesKeyed as $existingFilter) {\n $existingFilter->delete();\n }\n }\n\n /** @var Collection<int, SearchFilter> $filtersKeyed */\n $filtersKeyed = $search->filters()->get()->keyBy('filter');\n\n // wipe removed filters from this search\n foreach ($filtersKeyed as $filterName => $filter) {\n if (array_has($request, $prefix . $filterName)) {\n continue;\n }\n\n // Remove all filter values for this filter\n $search->filters()->where('filter', $filterName)->delete();\n }\n\n return $this;\n }\n\n /**\n * @throws AuthorizationException\n */\n public function fetchActivitySearch(\n Search $search,\n Request $request,\n SearchTransformer $searchTransformer,\n ): JsonResponse {\n $this->authorize('view', $search);\n\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection(\n $user->searches()->get(),\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n /**\n * Deletes a saved search\n *\n * @param Request $request\n * @param Search $search\n *\n * @throws Exception\n *\n * @return JsonResponse\n */\n public function deleteActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('delete', $search);\n\n // Orphan any AutomatedReports that use this search\n $search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);\n\n // Delete filters and the search itself\n $search->filters()->delete();\n $search->delete();\n\n return $this->response->withOk();\n }\n\n public function live(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n $user = $this->getUserFromRequest($request);\n\n $this->request->validate([\n 'sort_direction' => 'in:asc,desc',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ]);\n\n $activities = $repository->getLiveCoachingEligibleActivities(\n user: $user,\n lookBackMinutes: self::LOOK_BACK,\n limit: (int) $this->request->input('limit', 25),\n page: (int) $this->request->input('page', 1),\n sortBy: ['actual_start_time', 'scheduled_start_time'],\n sortDirection: (string) $this->request->input('sort_direction', 'asc'),\n );\n\n $this->response\n ->getManager()\n ->parseIncludes(['organizer.group', 'prospect'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($activities, new ActivityTransformer());\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function show(Activity $activity, ActivityService $activityService): JsonResponse\n {\n $this->authorize('show', $activity);\n\n $user = $activity->getUser();\n $team = $user->getTeam();\n\n // Sync the opportunity with the latest data if possible.\n if ($activity->opportunity_id) {\n try {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n if (! $user->isCrmRequired()) {\n $crmService->setUser($team->getOwner());\n } else {\n $crmService->setUser($user);\n }\n\n $crmService->syncOpportunity($activity->opportunity->crm_provider_id);\n } catch (Exception $exception) {\n // Move on.\n }\n }\n\n $activityData = $activityService->getActivityData($this->request->user(), $activity);\n\n return response()->json($activityData);\n }\n\n public function createRecording(Activity $activity)\n {\n $this->authorize('record', $activity);\n\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Tell Twilio to start recording this activity.\n if ($activity->recording_state === Activity::RECORDING_OFF) {\n $job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withCreated();\n }\n\n return $this->response->errorGone('Activity is already recording.');\n }\n\n public function updateRecording(Request $request, Activity $activity)\n {\n $this->authorize('record', $activity);\n\n $request->validate([\n 'preference' => 'boolean',\n 'state' => [\n 'string',\n Rule::in([\n Activity::RECORDING_IN_PROGRESS,\n Activity::RECORDING_PAUSED,\n ]),\n ],\n ]);\n\n if ($request->has('state')) {\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Toggle the recording state between paused and resumed.\n if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {\n $job = (new ToggleRecording($activity, $request->input('state')))\n ->onQueue(Constants::QUEUE_CONFERENCES);\n\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Recording is not toggleable.');\n }\n\n if ($request->has('preference')) {\n $activity->update([\n 'recording_preference' => $request->input('preference') ? 1 : 0,\n ]);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorWrongArgs('Something went wrong');\n }\n\n public function stopRecording(Activity $activity)\n {\n $this->authorize('stopRecord', $activity);\n\n // Tell Twilio to stop recording this activity.\n if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {\n $job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Activity is not recording.');\n }\n\n /**\n * Add activity to this user's favorites playlist\n *\n * @throws AuthorizationException\n */\n public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse\n {\n $this->authorize('favorite', $activity);\n\n $user = $this->getUserFromRequest($this->request);\n $favorite = $activity->wasFavoritedBy($user);\n $name = $activity->activity_title ?? '';\n\n // It needs to check at least one record.\n if (! $favorite) {\n $favoritePlaylist = $user->favoritePlaylist();\n\n $playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(\n $activity,\n $user,\n $favoritePlaylist\n );\n\n if ($playlistActivity !== null) {\n $playlistActivity->update(\n // Just update, don't sort.\n ['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],\n );\n } else {\n $playlistActivity = $activity->playlistActivities()->create([\n 'playlist_id' => $favoritePlaylist->getId(),\n 'user_id' => $user->getId(),\n 'start_time' => 0,\n 'name' => mb_strimwidth($name, 0, 100),\n ]);\n // Sort it on top.\n $playlistActivity->update(\n [\n 'sort' => $playlistActivityRepository->calculateNewSortOrder(\n null,\n $playlistActivity,\n ),\n ],\n );\n }\n\n $playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);\n\n return new JsonResponse([], JsonResponse::HTTP_CREATED);\n }\n\n return new JsonResponse(\n [\n 'error' => [\n 'code' => AbstractResponse::CODE_CONFLICT,\n 'http_code' => JsonResponse::HTTP_CONFLICT,\n 'message' => 'Resource Already Exists',\n ],\n ],\n JsonResponse::HTTP_CONFLICT,\n );\n }\n\n /**\n * Remove activity from this user's favorites playlist\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unfavorite(Activity $activity)\n {\n $user = $this->request->user();\n\n $favorites = $activity->favoritedBy($user);\n\n if ($favorites && $favorites->isEmpty()) {\n return $this->response->errorNotFound('Favorite not found.');\n }\n\n $this->authorize('unfavorite', [$activity, $favorites]);\n\n // When you unfavorite an activity,\n // it should remove all the activities in it, including snippets.\n $isDeleted = $favorites->each(function ($favorite) {\n $favorite->forceDelete();\n });\n\n if ($isDeleted) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not remove favorite.');\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function notify(Activity $activity)\n {\n $this->authorize('notify', $activity);\n\n $user = $this->request->user();\n\n $existingNotification = $activity->availabilityNotifications()\n ->where('user_id', $user->id)\n ->exists();\n\n if ($existingNotification) {\n return $this->response->errorWrongArgs('Notification is already configured.');\n }\n\n $notification = Activity\\AvailabilityNotification::create([\n 'user_id' => $user->id,\n 'activity_id' => $activity->id,\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($notification, new AvailabilityNotificationTransformer());\n }\n\n /**\n * @param Activity $activity\n * @param Activity\\AvailabilityNotification $notification\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unnotify(Activity $activity, Activity\\AvailabilityNotification $notification)\n {\n $this->authorize('unnotify', [$activity, $notification]);\n\n if ($notification->sent_at || $notification->delete()) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not delete notification.');\n }\n\n public function play(Request $request, Activity $activity)\n {\n $this->authorize('stream', $activity);\n\n $request->validate([\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $activity->plays()->create([\n 'user_id' => $user->getId(),\n 'start_time' => $request->input('start_time'),\n ]);\n\n return $this->response->withCreated();\n }\n\n /**\n * @param Activity $activity\n *\n * @return mixed\n */\n public function comment(Activity $activity)\n {\n return $this->newComment($activity);\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @return mixed\n */\n public function replyComment(Activity $activity, Comment $comment)\n {\n return $this->newComment($activity, $comment);\n }\n\n /**\n * @param Activity $activity\n * @param Comment|null $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n protected function newComment(Activity $activity, ?Comment $comment = null)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n 'type' => 'integer|between:0,3',\n 'visibility' => sprintf('nullable|integer|between:1,%d', count(Comment::getVisibilityLevels())),\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n $threadStartId = null;\n if ($comment) {\n $threadStartId = $comment->thread_start_id ?: $comment->id;\n }\n\n try {\n $newComment = Comment::create([\n 'parent_comment_id' => $comment->id ?? null,\n 'thread_start_id' => $threadStartId,\n 'activity_id' => $activity->id,\n 'user_id' => $this->request->user()->id,\n 'comment' => trim($this->request->input('comment')),\n 'start_time' => $this->request->input('start_time', 0),\n 'end_time' => $this->request->input('end_time', 0),\n 'type' => $this->request->input('type', Comment::TYPE_NEUTRAL),\n 'visibility' => $this->request->input('visibility', Comment::VISIBILITY_PUBLIC),\n ]);\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($newComment, new ActivityCommentTransformer());\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not create comment.' . $exception->getMessage());\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function updateComment(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n try {\n $comment->update([\n 'comment' => trim($this->request->input('comment')),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment.');\n }\n }\n\n public function updateCommentVisibility(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'visibility' => sprintf('integer|between:1,%d', count(Comment::getVisibilityLevels())),\n ]);\n\n $visibility = $this->request->input('visibility');\n\n if ($comment->parent !== null) {\n return $this->response->errorWrongArgs('Comment visibility can only be updated on top level comments.');\n }\n\n try {\n $this->activityCommentService->updateCommentVisibility($comment, $visibility);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment\\'s visibility.');\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function deleteComment(Activity $activity, Comment $comment)\n {\n $this->authorize('deleteComment', [$activity, $comment]);\n\n // Delete comment and any children.\n $comment->delete();\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function fetchComments()\n {\n $user = $this->request->user();\n $this->request->validate([\n 'forUserId' => 'uuid:users,team_id,' . $user->team_id,\n 'types' => 'array',\n 'types.*' => 'integer|between:0,3',\n ]);\n $forUser = null;\n\n $types = [Comment::TYPE_NEUTRAL, Comment::TYPE_GAME_CHANGER, Comment::TYPE_POSITIVE];\n $user = $this->request->user();\n if ($this->request->has('forUserId')) {\n $forUser = $user->team->users()->uuid($this->request->input('forUserId'));\n }\n\n $comments = Comment::query()\n ->whereHas('activity', static function (Builder $builder) use ($user, $forUser): void {\n $builder\n // I left feedback on my own activity; or\n ->where('activities.user_id', $user->getId());\n if ($forUser) {\n // I left feedback on any activity for this user.\n $builder->orWhere([\n 'user_id' => $user->getId(),\n 'activities.user_id' => $forUser->getId(),\n ]);\n }\n })\n ->whereIn('type', $this->request->input('types', $types))\n ->orderBy('created_at', 'desc')\n ->get();\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity', 'user'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($comments, new ActivityCommentTransformer());\n }\n\n public function deleteCoachingFeedback(Activity $activity, CoachingFeedback $coachingFeedback)\n {\n $this->authorize('deleteCoachingFeedback', [$activity, $coachingFeedback]);\n $activity = $coachingFeedback->getActivity();\n\n if ($coachingFeedback->delete()) {\n event(new UpdateSingleEntity(\n entityId: $activity->getId(),\n updateTarget: UpdateTargetEnum::ACTIVITY,\n purpose: 'delete-coaching-feedback',\n ));\n\n return $this->response->withOk();\n }\n\n return $this->response->withError('Delete operation failed. Contact support.', 500);\n }\n\n /**\n * Add new or update Coaching feedback\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws \\Illuminate\\Validation\\ValidationException\n *\n * @return mixed\n */\n public function putCoachingFeedback(Request $request, Activity $activity)\n {\n $user = $request->user();\n\n if (! $user instanceof User) {\n abort(403);\n }\n $teamId = $user->getTeamId();\n\n $this->authorize('coach', $activity);\n\n $this->request->validate([\n 'coach_id' => 'required|uuid:users,team_id,' . $teamId,\n 'coachee_id' => 'required|uuid:users,team_id,' . $teamId,\n 'visibility' => ['required', Rule::in(CoachingFeedback::VISIBILITIES)],\n 'coaching_sections.*.uuid' => 'required|uuid:coaching_sections',\n 'coaching_sections.*.score' => ['required', Rule::in(CoachingSectionFeedback::SCORES)],\n 'coaching_sections.*.summary' => 'string|max:10000',\n 'coaching_sections.*.criteria.*.uuid' => 'required|uuid:coaching_section_criteria',\n 'coaching_sections.*.criteria.*.note' => 'required|string|max:10000',\n 'sharedWithUsers' => [\n 'required_if:visibility,' . CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS,\n 'array',\n ],\n 'sharedWithUsers.*' => [\n 'uuid:users,team_id,' . $teamId,\n ],\n ]);\n\n /** @var User $coach */\n $coach = User::uuid($this->request->input('coach_id'));\n /** @var User $coachee */\n $coachee = User::uuid($this->request->input('coachee_id'));\n $coachingSectionFeedbacks = $this->request->input('coaching_sections');\n\n $previousRecord = $this->coachingFeedbackRepository->getOneForActivityByCoacheeAndCoach(\n $coachee->getId(),\n $coach->getId(),\n $activity->getId()\n );\n $recordIsNew = false;\n if ($previousRecord === null) {\n $recordIsNew = true;\n }\n\n if (! $coachee->isSameTeamId($coach)) {\n return $this->response->errorForbidden('User not member of your team.');\n }\n\n if (! is_array($coachingSectionFeedbacks) || count($coachingSectionFeedbacks) < 1) {\n return $this->response->withError('At least one Coaching Framework Section shall be scored.', 422);\n }\n\n if (! $activity->participants()->where('participants.user_id', $coachee->id)->exists()) {\n return $this->response->withError('Coached user did not participate activity.', 422);\n }\n\n $visibility = $this->request->input('visibility');\n\n $shouldSendNotification = $recordIsNew;\n if ($recordIsNew === false && $visibility !== $previousRecord->getVisibility()) {\n $shouldSendNotification = true;\n }\n\n /**\n * Create CoachingFeedback\n *\n * @var CoachingFeedback $coachingFeedback\n */\n $coachingFeedback = $activity->coachingFeedbacks()->updateOrCreate(\n [\n 'coach_id' => $coach->id,\n 'coachee_id' => $coachee->id,\n ],\n [\n 'framework_id' => $activity->category->id,\n 'visibility' => $visibility,\n ]\n );\n\n $sharedUserIds = [];\n if ($visibility === CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS) {\n foreach ($this->request->input('sharedWithUsers') as $sharedWithUserUuid) {\n /** @var User $user */\n $user = User::uuid($sharedWithUserUuid);\n $sharedUserIds[] = $user->getId();\n }\n }\n\n $syncResult = $coachingFeedback->customAccessUsers()->sync($sharedUserIds);\n\n $scores = [];\n\n\n /**\n * Create CoachingSectionsFeedbacks.\n *\n * @var CoachingSectionFeedback $coachingSectionFeedback\n */\n foreach ($coachingSectionFeedbacks as $coachingSectionFeedbackInput) {\n $coachingSection = CoachingSection::uuid($coachingSectionFeedbackInput['uuid']);\n $coachingSectionFeedback = $coachingFeedback->sectionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_id' => $coachingSection->id,\n ],\n [\n 'score' => array_get($coachingSectionFeedbackInput, 'score'),\n 'summary' => array_get($coachingSectionFeedbackInput, 'summary') ?? '',\n ]\n );\n\n $scores[] = array_get($coachingSectionFeedbackInput, 'score');\n\n $criteria = array_get($coachingSectionFeedbackInput, 'criteria');\n if (is_array($criteria) && ! empty($criteria)) {\n foreach ($criteria as $criteriaFeedbackInput) {\n $coachingSectionFeedback->criterionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_criterion_id' => CoachingSectionCriterion::uuid(array_get($criteriaFeedbackInput, 'uuid'))\n ->id,\n ],\n ['note' => array_get($criteriaFeedbackInput, 'note')],\n );\n }\n }\n }\n\n $coachingFeedback->average_score = array_sum($scores) / count($scores);\n\n if ($recordIsNew === false && $coachingFeedback->getAverageScore() !== $previousRecord->getAverageScore()) {\n $shouldSendNotification = true;\n }\n if (! empty($syncResult['attached']) || ! empty($syncResult['detached']) || ! empty($syncResult['updated'])) {\n $shouldSendNotification = true;\n }\n\n $coachingFeedback->save();\n // ensure updated at for coaching feedback on section feedback summary added.\n $coachingFeedback->touch();\n\n if ($shouldSendNotification) {\n event(new Coached($coachingFeedback));\n }\n\n Datadog::increment('jiminny.activity.score.update', 1, ['company' => $activity->user->team->slug]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n $coachingFeedbackTransformer = new CoachingFeedbackTransformer();\n $coachingFeedbackTransformer->setConsumer($this->getUserFromRequest($request));\n\n return $this->response->withItem($coachingFeedback, $coachingFeedbackTransformer);\n }\n\n\n /**\n * Retrieve category criteria for coaching.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachingSections(Activity $activity)\n {\n $this->authorize('coach', $activity);\n\n if ($activity->category === null) {\n return $this->response->errorUnprocessable('Category has not yet been assigned.');\n }\n\n $criteria = $activity\n ->category\n ->coachingSections()\n ->where('is_enabled', 1)\n ->orderBy('sequence', 'asc');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($criteria->get(), new CoachingSectionsTransformer());\n }\n\n /**\n * @throws AuthorizationException\n * @throws ValidationException\n *\n * @return mixed\n */\n public function addToPlaylist(Activity $activity, PlaylistTrackFactoryInterface $playlistTrackFactory)\n {\n $this->request->validate([\n 'playlists' => 'required|array',\n 'playlists.*' => 'uuid:playlists',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'name' => 'required|max:100',\n ]);\n\n $this->authorize('addToPlaylist', [$activity, $this->request->input('playlists')]);\n\n $startTime = $this->request->input('start_time');\n $endTime = $this->request->input('end_time');\n $name = $this->request->input('name');\n /** @var User $user */\n $user = $this->request->user();\n\n // Get playlist by uuid.\n foreach ($this->request->input('playlists') as $playlistId) {\n // Pull out the playlist model.\n $playlist = Playlist::uuid($playlistId);\n\n $playlistTrackFactory->createTrack($playlist, $user, [\n 'name' => $name,\n 'activity' => $activity,\n 'start_time' => $startTime,\n 'end_time' => $endTime,\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function share(Request $request, Activity $activity): JsonResponse\n {\n $this->authorize('share', $activity);\n\n $request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'recipients.*.type' => 'in:user,group',\n 'recipients.*.id' => 'string|max:40',\n 'share' => 'string|max:255',\n ]);\n\n $user = $request->user();\n\n $recipients = $request->get('recipients');\n $users = $this->userService->convertRecipientsToUsers($user, $recipients);\n\n $shareData = [\n 'from_user_id' => $user->id,\n 'note' => $request->input('note'),\n 'start_time' => $request->input('start_time'),\n 'end_time' => $request->input('end_time'),\n ];\n\n // Create a share object against a notification provider channel\n if ($request->input('share')) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'notification_provider_channel' => $request->input('share'),\n ]\n )\n );\n\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n\n // Create a share object against each recipient\n foreach ($users as $recipient) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'to_user_id' => $recipient->id,\n ]\n )\n );\n\n // If parent_share_id has been selected yet\n if (! isset($shareData['parent_share_id'])) {\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachRequest(Activity $activity)\n {\n $this->authorize('coachRequest', $activity);\n\n $this->request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'coachers.*.type' => 'required|in:user',\n 'coachers.*.id' => 'required',\n ]);\n\n $coachers = $this->request->get('coachers');\n $user = $this->request->user();\n $users = $this->userService->convertRecipientsToUsers($user, $coachers);\n\n foreach ($users as $coacher) {\n CoachRequest::create([\n 'user_id' => $coacher->id,\n 'activity_id' => $activity->id,\n 'note' => $this->request->get('note'),\n 'start_time' => $this->request->get('start_time'),\n 'end_time' => $this->request->get('end_time'),\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function createActivityTopicTriggers(Activity $activity, LoggerInterface $logger): HttpFoundation\\JsonResponse\n {\n $this->authorize('analyzeTopicTriggers', $activity);\n\n if (! $activity->hasTranscription()) {\n return new HttpFoundation\\JsonResponse(\n [\n 'error' => 'Transcription not found.',\n ],\n JsonResponse::HTTP_NOT_FOUND\n );\n }\n\n $logger->info(__METHOD__ . ': queued for analysis', [\n 'activity' => $activity->id_string,\n ]);\n\n dispatch(new ActivityAnalytics\\Job\\AnalyzeActivityTopicTriggers($activity));\n\n return new HttpFoundation\\JsonResponse(null, JsonResponse::HTTP_CREATED);\n }\n\n public function fetchActivityTopicTriggers(\n Activity $activity,\n LoggerInterface $logger,\n ActivityTopicTriggerTransformer $transformer\n ): HttpFoundation\\JsonResponse {\n $this->authorize('fetchTopicTriggers', $activity);\n\n $logger->debug(__METHOD__, [\n 'activity' => $activity->id_string,\n ]);\n\n if (! $activity->isProcessed()) {\n return new HttpFoundation\\JsonResponse([]);\n }\n\n $payload = [];\n\n if ($activity->hasTopicTriggers()) {\n $payload = $activity->getTopicTriggersSorted()\n ->map(\n static fn (Activity\\TopicTrigger $activityTopicTrigger): array\n => $transformer->transform($activityTopicTrigger)\n )\n ->values()\n ->all();\n }\n\n return new HttpFoundation\\JsonResponse($payload);\n }\n\n /**\n * @param Activity $activity\n * @param StatsTransformer $statsTransformer\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function stats(Activity $activity, StatsTransformer $statsTransformer)\n {\n $this->authorize('stream', $activity);\n\n if (! $activity->hasTranscription()) {\n return $this->response->errorNotFound('Waveform data is not yet generated.');\n }\n\n $this->response\n ->getManager()\n ->parseIncludes(['wavedata'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($activity, $statsTransformer);\n }\n\n public function destroy(Activity $activity)\n {\n $this->authorize('delete', $activity);\n\n $activity->delete();\n\n \\Log::info('Soft delete activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n\n return $this->response->withNoContent();\n }\n\n public function note(Activity $activity)\n {\n $this->authorize('note', $activity);\n\n $this->request->validate([\n 'note' => 'required|min:1|max:2000',\n 'time' => 'required|numeric|min:0|max:86400',\n ]);\n\n $note = $this->request->input('note');\n $time = $this->request->input('time');\n\n $this->activityService->setActivity($activity);\n $this->activityService->takeNote($this->getUser(), $note, $time);\n\n return $this->response->withCreated();\n }\n\n /**\n * Mark an activity as private.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPrivate(Activity $activity)\n {\n $this->authorize('markAsPrivate', $activity);\n\n if ($activity->is_private === false) {\n $activity->is_private = true;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * Mark an activity as public.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPublic(Activity $activity)\n {\n $this->authorize('markAsPublic', $activity);\n\n if ($activity->is_private) {\n $activity->is_private = false;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws LogicException\n */\n public function fetchCloudFrontS3MediaKeys(Activity $activity, PlaybackService $playbackService): JsonResponse\n {\n $masterTrack = $activity->masterTrack()->first();\n\n if (! $masterTrack instanceof Track) {\n throw new LogicException(sprintf('Master track not found for activity \"%s\"', $activity->getUuid()));\n }\n\n return $this->response->withArray(\n $playbackService->generateCookies(\n $masterTrack,\n $this->request->ip(),\n ),\n );\n }\n\n /**\n * @throws ValidationException\n */\n private function updateOrCreateActivitySearch(Request $request, ?Search $search = null): Search\n {\n $request->validate([\n 'name' => 'required|string|min:2|max:100',\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $searchName = $request->input('name');\n\n if ($search !== null) {\n $search->update([\n 'name' => $searchName,\n ]);\n\n return $search;\n }\n\n $request->validate([\n 'filters' => ['required', 'array', new MultidimensionalArrayMaxCharRule(limit: 255)],\n 'nudges' => 'array|max:' . count(Nudge::MAP_CHANNEL),\n 'nudges.*.channel' => 'required|in:' . implode(',', Nudge::MAP_CHANNEL),\n 'nudges.*.frequency' => 'required|in:' . implode(',', Nudge::MAP_FREQUENCY),\n 'nudges.*.expiresAt' => [\n 'required',\n 'date',\n 'after:today',\n 'before_or_equal:' . now()->addYear()->format('Y-m-d'),\n ],\n ]);\n\n $searchCriteria = Criteria::createFromRequest(\n Collection::make($request->input('filters', []))->all(),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($searchCriteria, $user);\n $this->validateSearch($request, $filterSet, 'filters.');\n\n /** @var Search $search */\n $search = Search::create([\n 'name' => $searchName,\n 'uuid' => Uuid::uuid4()->toString(),\n 'user_id' => $user->getId(),\n ]);\n\n Collection::make($request->input('nudges', []))\n ->each(fn (array $attributes): Nudge => $this->nudgeFactory->createNudge($search, $attributes));\n\n $this->storeNamedSearchFilters(Collection::make($request->all()), $search, $filterSet, 'filters.');\n\n return $search;\n }\n\n private function resolveAccount(\n Team $team,\n Contact $contact,\n ServiceInterface $crmService,\n array $prospects,\n ): ?Account {\n $this->logger->info('Resolving account from contact');\n $account = $contact->getAccount();\n\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS)) {\n $this->logger->info('Team does not have feature to link activity to multiple prospects');\n\n return $account;\n }\n\n $this->logger->info('Resolving account from prospect data');\n $accountData = array_filter(\n $prospects,\n static fn (array $prospectData): bool => $prospectData['type'] === 'account'\n );\n\n if (! empty($accountData)) {\n $this->logger->info('Found account data in prospects');\n $accountData = reset($accountData);\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountData['id'])->first();\n\n if (! $account instanceof Account) {\n $this->logger->info('Account not found in database, syncing from CRM');\n $account = $crmService->syncAccount($accountData['id']);\n }\n }\n\n $this->logger->info('Resolved account', ['account' => $account->getId()]);\n\n return $account;\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":"40","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"40","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"64","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","depth":4,"on_screen":true,"value":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","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}]...
|
-7287184300264252456
|
-8385861013499833196
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use Carbon\Carbon;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\In;
use Illuminate\Validation\ValidationException;
use InvalidArgumentException;
use Jiminny\Component\ActivityAnalytics;
use Jiminny\Component\ActivitySearch;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Queue\Constants;
use Jiminny\Contracts\ES\Events\UpdateSingleEntity;
use Jiminny\Contracts\ES\UpdateTargetEnum;
use Jiminny\Contracts\Nudge\NudgeFactoryInterface;
use Jiminny\Contracts\Playlist\PlaylistTrackFactoryInterface;
use Jiminny\Contracts\Repositories\PlaylistActivityRepository;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Enums\TeamSetting;
use Jiminny\Events\Activities\AiAutomation\ActivityProspectAdded;
use Jiminny\Events\Activities\Coaching\Coached;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Controllers\CommentContextInterface;
use Jiminny\Http\Responses\Api\AbstractResponse;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\ActivityCommentTransformer;
use Jiminny\Http\Transformers\ActivityTopicTriggerTransformer;
use Jiminny\Http\Transformers\ActivityTransformer;
use Jiminny\Http\Transformers\AvailabilityNotificationTransformer;
use Jiminny\Http\Transformers\CoachingFeedbackTransformer;
use Jiminny\Http\Transformers\CoachingSectionsTransformer;
use Jiminny\Http\Transformers\SearchTransformer;
use Jiminny\Http\Transformers\StatsTransformer;
use Jiminny\Jobs\Crm\SaveActivity;
use Jiminny\Jobs\Crm\UpdateStage;
use Jiminny\Jobs\Telephony\StartRecording;
use Jiminny\Jobs\Telephony\StopRecording;
use Jiminny\Jobs\Telephony\ToggleRecording;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\CoachingFeedback;
use Jiminny\Models\CoachingSection;
use Jiminny\Models\CoachingSectionCriterion;
use Jiminny\Models\CoachingSectionFeedback;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\LanguageDialect;
use Jiminny\Models\Lead;
use Jiminny\Models\Nudge;
use Jiminny\Models\PlaybookCategory;
use Jiminny\Models\Playlist;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\Track;
use Jiminny\Models\User;
use Jiminny\Repositories\CoachingFeedbackRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Rules\CrmReference;
use Jiminny\Rules\MultidimensionalArrayMaxCharRule;
use Jiminny\Services\ActivityService;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Services\PlaybackService;
use Jiminny\Services\UserService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
use Ramsey\Uuid\Uuid;
use Sentry;
use Symfony\Component\HttpFoundation;
final class ActivityController extends Controller implements CommentContextInterface
{
// Number of minutes to look back on activities. i.e. a timeout on activity duration.
private const int LOOK_BACK = 180;
public function __construct(
private ProviderRegistry $providerRegistry,
private ActivityService $activityService,
Response $response,
private UserService $userService,
private ActivitySearch\Service\ActivitySearch $activitySearch,
private NudgeFactoryInterface $nudgeFactory,
private ActivityCommentService $activityCommentService,
private LoggerInterface $logger,
private readonly CoachingFeedbackRepository $coachingFeedbackRepository,
private readonly TeamRepository $teamRepository,
) {
parent::__construct($response);
}
public static function getCommentImplementation(): string
{
return Comment::class;
}
public function delete()
{
$this->request->validate([
'*' => 'uuid:activities',
]);
$deletedIds = [];
foreach ($this->request->all() as $activityId) {
$activity = Activity::idOrUuId($activityId);
try {
if ($this->authorize('delete', $activity)) {
$activity->delete();
$deletedIds[] = $activityId;
\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);
}
} catch (AuthorizationException $authorizationException) {
// They didn't have permission.
}
}
return $this->response->withArray($deletedIds);
}
public function update(Request $request, Activity $activity)
{
$this->authorize('updateMetadata', $activity);
$request->validate([
'title' => 'string|max:250',
'category_id' => 'uuid:playbook_categories',
'language' => [
new In(
LanguageDialect::query()
->with('language')
->cursor()
->map(static function (LanguageDialect $languageDialect): string {
return $languageDialect->getLanguageLocale();
})
->all()
),
],
]);
if ($request->has('title')) {
$activity->title = $request->input('title');
}
if ($request->has('category_id')) {
$category = PlaybookCategory::uuid($request->input('category_id'));
if ($category->playbook->team_id !== $request->user()->team_id) {
return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
if ($request->has('language')) {
if (! $activity->isInProgress()) {
return $this->response->withError(
'Activity language can only be set while the meeting is in progress.',
400
);
}
$activity->setLanguageCode($request->input('language'));
}
$activity->save();
return $this->response->withOk();
}
// XXX: This should be merged with the update method.
/**
* @param Activity $activity
*
* @throws AuthorizationException
* @throws SocialAccountTokenInvalidException
*
* @return mixed
*/
public function summarize(Activity $activity): mixed
{
$this->logger->info('[Log Activity] Summarizing activity ', [
'activityId' => $activity->getUuid(),
'payload' => $this->request->all(),
]);
$this->authorize('update', $activity);
$this->logger->info('[Log Activity] Validating summary');
// Validate the payload.
$this->validateSummary($activity);
// All objects must belong to this team.
/** @var User $user */
$user = $this->request->user();
$team = $user->getTeam();
$crmService = $this->providerRegistry->get($team->crm->provider);
try {
$crmUser = $user;
if ($user->isCrmRequired() === false) {
$crmUser = $team->owner;
}
$crmService->setUser($crmUser);
} catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());
}
$rawEntities = $this->request->input('entities');
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid(
$this->request->input('layout_id')
);
// Delay execution of CRM jobs to avoid locking issues.
$jobDelay = 0;
// If we have arrived from a notification, mark it as read.
$notificationId = $this->request->input('nId');
if ($notificationId) {
$notification = $user->unreadNotifications->where('id', $notificationId)->first();
if ($notification) {
$notification->markAsRead();
}
}
$title = $this->request->input('title');
$prospects = $this->request->input('prospects');
$opportunityId = $this->request->input('opportunity_id');
$stageId = $this->request->input('stage_id');
$categoryId = $this->request->input('category_id');
$summary = $this->request->input('summary');
$crmProviderId = $this->request->input('crm_id');
$isInternal = $this->request->input('is_internal') ?? false;
$lead = null;
$category = null;
$account = null;
$contact = null;
$opportunity = null;
$stage = null;
$callStage = null;
foreach ($prospects as $prospectData) {
$objectId = $prospectData['id'];
if ($objectId === null) {
continue;
}
$objectType = $prospectData['type'];
$this->logger->info('debug', ['prospect_data' => $prospectData]);
try {
if ($objectType === null) {
$this->logger->info('no object type');
if ($crmService instanceof SupportsObjectTypeParseInterface) {
$objectType = $crmService->parseObjectType($objectId);
}
}
switch ($objectType) {
case 'lead':
$this->logger->info('Processing lead');
/** @var Lead|null $lead */
$lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();
// Lead does not exist locally, import it.
if ($lead === null) {
$this->logger->info('Lead does not exist locally');
/** @var Lead $lead */
$lead = $crmService->syncLead($objectId);
}
$this->logger->info('Lead found', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
if ($stageId === null) {
$this->logger->info('Stage ID is null');
// If it was not provided, just assume it is the current stage.
$callStage = $lead->stage;
break;
}
$this->logger->info('Looking for stage');
// Determine if they have changed the stage.
/** @var Stage $stage */
$stage = $team->crm->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_LEAD)
->firstOrFail();
$this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);
if ($lead->stage_id && $lead->stage_id !== $stage->id) {
$this->logger->info('Stage has changed');
// Storage current stage on activity.
$callStage = $lead->stage;
// The stage has changed, update in remote CRM.
dispatch(new UpdateStage($activity, $lead, $callStage, $stage));
$this->logger->info(
sprintf(
'[%s] User changing lead stage from %s to %s',
$crmService->getDisplayName(),
$callStage->getName(),
$stage->getName()
),
[
'user' => $user->getUuid(),
'lead' => $lead->getUuid(),
]
);
} else {
$this->logger->info('Stage has not changed');
// Stage remains as current.
$callStage = $stage;
}
break;
case 'account':
$this->logger->info('Processing account');
// If the object is not a lead, it should be an account.
$account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();
// Account does not exist locally, import it.
if ($account === null) {
$this->logger->info('Account does not exist locally');
$account = $crmService->syncAccount($objectId);
}
$this->logger->info('Account found', ['accountId' => $account->id]);
break;
case 'contact':
$this->logger->info('processing contact');
$contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$this->logger->info('contact does not exist locally');
$contact = $crmService->syncContact($objectId);
}
$this->logger->info('resolving account');
$account = $this->resolveAccount($team, $contact, $crmService, $prospects);
break;
}
// If they have specified an opportunity, retrieve this with stage.
if ($opportunityId) {
$this->logger->info('opportunity id is set');
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if ($opportunity === null) {
$this->logger->info('opportunity does not exist locally');
$opportunity = $crmService->syncOpportunity($opportunityId);
}
if ($stageId === null) {
$this->logger->info('stage id is null');
// If it was not provided, just assume it is the current stage.
$callStage = $opportunity->stage ?? null;
} else {
$this->logger->info('looking for stage');
/** @var ?Stage $opportunityStage */
$opportunityStage = $team->crm
->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
// There is a chance we still cannot import this opportunity.
if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {
$this->logger->info('opportunity stage has changed');
// Storage current stage on activity.
$callStage = $opportunity->stage;
dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));
$this->logger->info(
sprintf(
'[%s] User changing opportunity stage from %s to %s',
$crmService->getDisplayName(),
$callStage->name,
$opportunityStage->name
),
[
'userId' => $user->id_string,
'opportunityId' => $opportunity->id_string,
]
);
} else {
$this->logger->info('opportunity stage has not changed');
// Stage remains as current.
$callStage = $opportunityStage;
}
}
}
if ($crmProviderId) {
// Cast $crmProviderId to string otherwise it won't use database index for some records
$linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();
// Check if this activity has already been assigned to a different activity.
if ($linkedActivity && $linkedActivity->id !== $activity->id) {
throw new InvalidArgumentException(
'Sorry, the linked task has already been logged under a different call. '
. 'Please choose another linked task.'
);
}
}
} catch (InvalidArgumentException $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($exception->getMessage());
} catch (Exception $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorInternalError(
'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'
);
}
}
if ($categoryId) {
$category = PlaybookCategory::uuid($categoryId);
if ($category->playbook->team_id !== $team->id) {
throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
$this->logger->info('Prospect data', [
'lead_id' => $lead?->getId(),
'account_id' => $account?->getId(),
'contact_id' => $contact?->getId(),
'opportunity_id' => $opportunity?->getId(),
'stage_id' => $stage?->getId(),
]);
if ($title) {
$activity->title = $title;
}
if ($summary) {
$activity->summary = $summary;
}
if ($crmProviderId) {
$activity->crm_provider_id = $crmProviderId;
}
if ($callStage) {
$this->logger->info('Setting stage id', ['stageId' => $callStage->id]);
$activity->stage_id = $callStage->id;
}
if ($lead) {
$this->logger->info('Setting lead id', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
// If we are changed from an account > lead, unset the account data.
$this->logger->info('Unsetting account id, opportunity id, contact id, value');
$activity->account_id = null;
$activity->opportunity_id = null;
$activity->contact_id = null;
$activity->value = null;
}
if ($account) {
$this->logger->info('Setting account id', ['accountId' => $account->id]);
$activity->account_id = $account->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('unsetting lead id');
$activity->lead_id = null;
// Unset the contact if switching different accounts. Will be set up below if still applicable.
if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {
$this->logger->info('Unsetting contact id');
$activity->contact_id = null;
}
}
if ($opportunity) {
$this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);
$this->logger->info('unsetting lead id');
$activity->opportunity_id = $opportunity->id;
$activity->value = $opportunity->value;
// If we are changed from an lead > account, unset the lead data.
$activity->lead_id = null;
}
if ($contact) {
$this->logger->info('setting contact id', ['contactId' => $contact->id]);
$activity->contact_id = $contact->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('Unsetting lead id');
$activity->lead_id = null;
}
$activity->is_internal = $isInternal;
$activity->save();
$activity->refresh();
$this->logger->notice('Activity saved', [
'activity_id' => $activity->getId(),
'lead_id' => $activity->lead_id,
'account_id' => $activity->account_id,
'contact_id' => $activity->contact_id,
'opportunity_id' => $activity->opportunity_id,
'stage_id' => $activity->stage_id,
'crm_provider_id' => $activity->getCrmProviderId(),
]);
// Store entities as field data on the activity.
$updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);
if ($activity->isLoggable()) {
// Follow-up Task or Event data.
$followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);
$this->logger->info('CRM LOG manual log triggered', [
'activityId' => $activity->getUuid(),
'followupData' => $followupData,
'userId' => $user->getUuid(),
]);
// Store data in the CRM.
// ++add check for crm_required
$job = new SaveActivity($activity, $followupData);
if ($updatedData) {
$job->delay(Carbon::now()->addMinutes($jobDelay));
}
dispatch($job);
// Manually dispatch log for Opportunity or Prospect added
if ($activity->hasOpportunity() || $activity->hasProspect()) {
event(new ActivityProspectAdded(
activity: $activity,
eventSource: 'manually-log-crm-data'
));
}
}
return $this->response->withOk();
}
/**
* Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.
*
* @param ServiceInterface $service
* @param Activity $activity
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array
{
$updatedData = [];
$existingData = $activity->data()->get();
// We need to delete any existing data to overwrite with latest values.
$activity->data()->delete();
$layoutEntities = $layout->entities()
->with('field', 'parent')
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->get();
/** @var LayoutEntity $entity */
foreach ($layoutEntities as $entity) {
// If the user has provided a value for this entity
if (array_key_exists($entity->id_string, $entities)) {
$value = $entities[$entity->id_string];
// Convert raw data into values that the CRM can consume.
if ($value) {
$value = $service->normalizeValue($entity->field->type, $value);
}
// Check the field is part of the activity-summary section.
if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {
// This is the internal database ID, not the external CRM ID.
$objectId = null;
switch ($entity->field->object_type) {
case Field::OBJECT_ACCOUNT:
$objectId = $activity->account_id;
break;
case Field::OBJECT_CONTACT:
$objectId = $activity->contact_id;
break;
case Field::OBJECT_OPPORTUNITY:
$objectId = $activity->opportunity_id;
break;
case Field::OBJECT_LEAD:
$objectId = $activity->lead_id;
break;
case Field::OBJECT_TASK:
case Field::OBJECT_EVENT:
$objectId = $activity->id;
break;
}
if ($objectId) {
/** @var FieldData $data */
$data = $activity->data()->create([
'crm_layout_entity_id' => $entity->id,
'crm_field_id' => $entity->crm_field_id,
'object_type' => $entity->field->object_type,
'object_id' => $objectId,
'value' => $value,
]);
// Never send read-only field data to the CRM.
if ($entity->read_only === false && $entity->is_visible) {
$existingValue = $existingData
->where('crm_layout_entity_id', $entity->id)
->where('crm_field_id', $entity->crm_field_id)
->where('object_type', $entity->field->object_type)
->where('object_id', $objectId)
->first();
// If the field was actually changed, we need to reflect this in the CRM too.
if ($existingValue === null || $existingValue->value !== $value) {
$updatedData[] = $data->id;
}
}
}
}
}
}
return $updatedData;
}
/**
* Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.
*
* @param ServiceInterface $crmService
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array
{
$fieldData = [];
foreach ($entities as $entityId => $value) {
// Only bother with fields that have a value.
if ($value) {
// Extract the entity from the UUID. Check the field is valid and part of the follow-up section.
$entity = $layout->entities()
->uuid($entityId, false)
->whereHas('parent', function ($query) {
$query->where('label', 'follow-up');
})
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->first();
if ($entity) {
// Convert raw data into values that the CRM can consume.
$value = $crmService->normalizeValue($entity->field->type, $value);
// Add the field and value to the payload.
$fieldData += [
$entity->field->crm_provider_id => $value,
];
}
}
}
return $fieldData;
}
/**
* @param Activity $activity
*/
private function validateSummary(Activity $activity): void
{
$team = $activity->user->team;
$crmProvider = $team->crm->provider;
$attributes = [];
$rules = [
'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,
'title' => 'string|max:250',
'prospects' => 'required|array',
'opportunity_id' => new CrmReference($crmProvider),
'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',
'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator
'summary' => 'max:50000',
'nId' => 'exists:notifications,id',
'crm_id' => new CrmReference($crmProvider),
'entities' => 'array',
'is_internal' => 'boolean',
];
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));
// Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.
$entities = $layout->entities()
->where('read_only', 0)
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->whereHas('parent', function ($query) use ($activity) {
if ($activity->isLoggable() === false) {
$query->where('label', '<>', 'follow-up');
}
});
$isInternal = $this->request->input('is_internal', false);
foreach ($entities->get() as $entity) {
$rules += $this->buildFieldValidator($entity, $isInternal);
$attributes += $this->buildFieldMessage($entity);
}
$this->request->validate($rules, [], $attributes);
}
private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array
{
return [
'entities.' . $entity->id_string => $entity->getValidator($isInternal),
];
}
/**
* @param LayoutEntity $entity
*
* @return array
*/
private function buildFieldMessage(LayoutEntity $entity): array
{
$label = $entity->label;
if ($label === null) {
$label = $entity->field->label;
}
return [
'entities.' . $entity->id_string => $label,
];
}
public function search(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->debugLog(
$user,
'User extracted from request',
['user' => $user->getId(), 'tz' => $user->getTimezone()]
);
$searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());
$this->debugLog(
$user,
'ActivitySearch criteria built',
['searchCriteria' => $searchCriteria]
);
$filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);
$this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);
$this->validateSearch($request, $filterSet);
$this->debugLog($user, 'Request validated');
$searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);
/** @var Collection<Activity> $activities */
$activities = $searchResponse['results'];
$this->debugLog($user, 'Activities ES response extracted');
$hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(
$user->getTeamId(),
TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),
);
if ($hideInternalMeetingsSetting?->getValue() === '1') {
$activities = $activities->filter(function (Activity $activity) {
if ($activity->is_internal && empty($activity->actual_start_time)) {
return false;
}
return true;
});
}
$this->debugLog($user, 'Internal meetings (?!) filtered');
$this->response->getManager()
->parseIncludes([
'category',
'organizer.group',
'prospect',
'stage',
'opportunity',
'stats',
'scorecards',
'masterTrack',
'activeParticipants',
'notification',
])
->setSerializer(new JsonSerializer());
$transformerExcludes = $this->request->input('exclude');
if ($transformerExcludes) {
$this->response->getManager()->parseExcludes($transformerExcludes);
}
$this->debugLog($user, 'Response Manager (?!) applied');
$transformer = new ActivityTransformer();
$transformer->setConsumer($user);
$this->debugLog($user, 'Activity Transformer added');
$resource = new \League\Fractal\Resource\Collection($activities, $transformer);
$page = $searchCriteria->getPageNumber();
$this->debugLog($user, 'Search criteria page number called', ['page' => $page]);
$histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');
$this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);
return $this->response->withArray([
'pagination' => [
'total' => $searchResponse['totalHits'],
'current' => $page,
'prev' => max($page - 1, 1),
'next' => $page + 1,
],
'results' => $this->response->getManager()->createData($resource)->toArray(),
'histogram' => $histogram,
]);
}
private function debugLog(User $user, string $logMessage, ?array $context = []): void
{
// Debug for Learning People Only
if ($user->getTeamId() !== 260) {
return;
}
Log::notice(
sprintf('[activity-search-controller] %s', $logMessage),
$context
);
}
/** @throws ValidationException */
private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void
{
$rules = [
'exclude' => 'array',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
];
if ($prefix !== null && mb_strpos($prefix, '.') !== false) {
$rules[rtrim($prefix, '.')] = sprintf(
'required|array|max:%d',
$filterSet->count()
);
}
$validationRules = $filterSet->getValidationRules($prefix)
->merge($rules)
->all();
$request->validate($validationRules);
}
public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$search = $this->updateOrCreateActivitySearch($request);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function updateActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('update', $search);
$this->updateOrCreateActivitySearch($request, $search);
return $this->response->withOk();
}
private function storeNamedSearchFilters(
Collection $request,
Search $search,
FilterDefinitionCollection $filterSet,
?string $prefix = null,
): self {
$arrayTypeProperties = $filterSet
->getPropertyTypes([
FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,
])
->all();
$supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);
foreach ($supportedRequestProperties as $requestPropertyName) {
if (! array_has($request, $requestPropertyName)) {
continue;
}
/** @var string|string[] $propertyValue */
$propertyValue = array_get($request, $requestPropertyName);
$propertyName = $prefix === null
? $requestPropertyName
: mb_substr($requestPropertyName, mb_strlen($prefix));
$isArrayType = array_has($arrayTypeProperties, $propertyName);
if (! $isArrayType) {
/** @var string $requestPropertyValue */
$search->filters()->updateOrCreate(
[
'filter' => $propertyName,
],
[
'value' => $propertyValue,
]
);
continue;
}
/** @var string[] $requestPropertyValue */
/** @var SearchFilter[]|Collection $existingFilterValues */
$existingFilterValuesKeyed = $search->filters()
->where('filter', $propertyName)
->get()
->keyBy('id');
// Iterate over values provided as request parameters
foreach ($propertyValue as $value) {
/** @var SearchFilter|null $valueFilter */
$valueFilter = $search->filters()
->where(
[
'filter' => $propertyName,
'value' => $value,
]
)
->first();
if ($valueFilter !== null) {
// Remove filter value pair from list to be deleted
$existingFilterValuesKeyed->forget($valueFilter->id);
} else {
// Add new filter/value pair
$search->filters()->updateOrCreate([
'filter' => $propertyName,
'value' => $value,
]);
}
}
// Delete filter value pairs for this filter that no longer exist in request parameters
foreach ($existingFilterValuesKeyed as $existingFilter) {
$existingFilter->delete();
}
}
/** @var Collection<int, SearchFilter> $filtersKeyed */
$filtersKeyed = $search->filters()->get()->keyBy('filter');
// wipe removed filters from this search
foreach ($filtersKeyed as $filterName => $filter) {
if (array_has($request, $prefix . $filterName)) {
continue;
}
// Remove all filter values for this filter
$search->filters()->where('filter', $filterName)->delete();
}
return $this;
}
/**
* @throws AuthorizationException
*/
public function fetchActivitySearch(
Search $search,
Request $request,
SearchTransformer $searchTransformer,
): JsonResponse {
$this->authorize('view', $search);
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withCollection(
$user->searches()->get(),
$searchTransformer
->withConsumer($user)
);
}
/**
* Deletes a saved search
*
* @param Request $request
* @param Search $search
*
* @throws Exception
*
* @return JsonResponse
*/
public function deleteActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('delete', $search);
// Orphan any AutomatedReports that use this search
$search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);
// Delete filters and the search itself
$search->filters()->delete();
$search->delete();
return $this->response->withOk();
}
public function live(Request $request, ElasticActivityRepository $repository): JsonResponse
{
$user = $this->getUserFromRequest($request);
$this->request->validate([
'sort_direction' => 'in:asc,desc',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
]);
$activities = $repository->getLiveCoachingEligibleActivities(
user: $user,
lookBackMinutes: self::LOOK_BACK,
limit: (int) $this->request->input('limit', 25),
page: (int) $this->request->input('page', 1),
sortBy: ['actual_start_time', 'scheduled_start_time'],
sortDirection: (string) $this->request->input('sort_direction', 'asc'),
);
$this->response
->getManager()
->parseIncludes(['organizer.group', 'prospect'])
->setSerializer(new JsonSerializer());
return $this->response->withCollection($activities, new ActivityTransformer());
}
/**
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function show(Activity $activity, ActivityService $activityService): JsonResponse
{
$this->authorize('show', $activity);
$user = $activity->getUser();
$team = $user->getTeam();
// Sync the opportunity with the latest data if possible.
if ($activity->opportunity_id) {
try {
$crmService = $this->providerRegistry->get($team->crm->provider);
if (! $user->isCrmRequired()) {
$crmService->setUser($team->getOwner());
} else {
$crmService->setUser($user);
}
$crmService->syncOpportunity($activity->opportunity->crm_provider_id);
} catch (Exception $exception) {
// Move on.
}
}
$activityData = $activityService->getActivityData($this->request->user(), $activity);
return response()->json($activityData);
}
public function createRecording(Activity $activity)
{
$this->authorize('record', $activity);
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Tell Twilio to start recording this activity.
if ($activity->recording_state === Activity::RECORDING_OFF) {
$job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withCreated();
}
return $this->response->errorGone('Activity is already recording.');
}
public function updateRecording(Request $request, Activity $activity)
{
$this->authorize('record', $activity);
$request->validate([
'preference' => 'boolean',
'state' => [
'string',
Rule::in([
Activity::RECORDING_IN_PROGRESS,
Activity::RECORDING_PAUSED,
]),
],
]);
if ($request->has('state')) {
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Toggle the recording state between paused and resumed.
if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {
$job = (new ToggleRecording($activity, $request->input('state')))
->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Recording is not toggleable.');
}
if ($request->has('preference')) {
$activity->update([
'recording_preference' => $request->input('preference') ? 1 : 0,
]);
return $this->response->withOk();
}
return $this->response->errorWrongArgs('Something went wrong');
}
public function stopRecording(Activity $activity)
{
$this->authorize('stopRecord', $activity);
// Tell Twilio to stop recording this activity.
if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {
$job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Activity is not recording.');
}
/**
* Add activity to this user's favorites playlist
*
* @throws AuthorizationException
*/
public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse
{
$this->authorize('favorite', $activity);
$user = $this->getUserFromRequest($this->request);
$favorite = $activity->wasFavoritedBy($user);
$name = $activity->activity_title ?? '';
// It needs to check at least one record.
if (! $favorite) {
$favoritePlaylist = $user->favoritePlaylist();
$playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(
$activity,
$user,
$favoritePlaylist
);
if ($playlistActivity !== null) {
$playlistActivity->update(
// Just update, don't sort.
['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],
);
} else {
$playlistActivity = $activity->playlistActivities()->create([
'playlist_id' => $favoritePlaylist->getId(),
'user_id' => $user->getId(),
'start_time' => 0,
'name' => mb_strimwidth($name, 0, 100),
]);
// Sort it on top.
$playlistActivity->update(
[
'sort' => $playlistActivityRepository->calculateNewSortOrder(
null,
$playlistActivity,
),
],
);
}
$playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);
return new JsonResponse([], JsonResponse::HTTP_CREATED);
}
return new JsonResponse(
[
'error' => [
'code' => AbstractResponse::CODE_CONFLICT,
'http_code' => JsonResponse::HTTP_CONFLICT,
'message' => 'Resource Already Exists',
],
],
JsonResponse::HTTP_CONFLICT,
);
}
/**
* Remove activity from this user's favorites playlist
*
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function unfavorite(Activity $activity)
{
$user = $t...
|
32852
|
NULL
|
NULL
|
NULL
|
|
32856
|
1255
|
36
|
2026-05-13T09:40:00.553747+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665200553_m2.jpg...
|
PhpStorm
|
faVsco.js – ActivityController.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use Carbon\Carbon;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\In;
use Illuminate\Validation\ValidationException;
use InvalidArgumentException;
use Jiminny\Component\ActivityAnalytics;
use Jiminny\Component\ActivitySearch;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Queue\Constants;
use Jiminny\Contracts\ES\Events\UpdateSingleEntity;
use Jiminny\Contracts\ES\UpdateTargetEnum;
use Jiminny\Contracts\Nudge\NudgeFactoryInterface;
use Jiminny\Contracts\Playlist\PlaylistTrackFactoryInterface;
use Jiminny\Contracts\Repositories\PlaylistActivityRepository;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Enums\TeamSetting;
use Jiminny\Events\Activities\AiAutomation\ActivityProspectAdded;
use Jiminny\Events\Activities\Coaching\Coached;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Controllers\CommentContextInterface;
use Jiminny\Http\Responses\Api\AbstractResponse;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\ActivityCommentTransformer;
use Jiminny\Http\Transformers\ActivityTopicTriggerTransformer;
use Jiminny\Http\Transformers\ActivityTransformer;
use Jiminny\Http\Transformers\AvailabilityNotificationTransformer;
use Jiminny\Http\Transformers\CoachingFeedbackTransformer;
use Jiminny\Http\Transformers\CoachingSectionsTransformer;
use Jiminny\Http\Transformers\SearchTransformer;
use Jiminny\Http\Transformers\StatsTransformer;
use Jiminny\Jobs\Crm\SaveActivity;
use Jiminny\Jobs\Crm\UpdateStage;
use Jiminny\Jobs\Telephony\StartRecording;
use Jiminny\Jobs\Telephony\StopRecording;
use Jiminny\Jobs\Telephony\ToggleRecording;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\CoachingFeedback;
use Jiminny\Models\CoachingSection;
use Jiminny\Models\CoachingSectionCriterion;
use Jiminny\Models\CoachingSectionFeedback;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\LanguageDialect;
use Jiminny\Models\Lead;
use Jiminny\Models\Nudge;
use Jiminny\Models\PlaybookCategory;
use Jiminny\Models\Playlist;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\Track;
use Jiminny\Models\User;
use Jiminny\Repositories\CoachingFeedbackRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Rules\CrmReference;
use Jiminny\Rules\MultidimensionalArrayMaxCharRule;
use Jiminny\Services\ActivityService;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Services\PlaybackService;
use Jiminny\Services\UserService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
use Ramsey\Uuid\Uuid;
use Sentry;
use Symfony\Component\HttpFoundation;
final class ActivityController extends Controller implements CommentContextInterface
{
// Number of minutes to look back on activities. i.e. a timeout on activity duration.
private const int LOOK_BACK = 180;
public function __construct(
private ProviderRegistry $providerRegistry,
private ActivityService $activityService,
Response $response,
private UserService $userService,
private ActivitySearch\Service\ActivitySearch $activitySearch,
private NudgeFactoryInterface $nudgeFactory,
private ActivityCommentService $activityCommentService,
private LoggerInterface $logger,
private readonly CoachingFeedbackRepository $coachingFeedbackRepository,
private readonly TeamRepository $teamRepository,
) {
parent::__construct($response);
}
public static function getCommentImplementation(): string
{
return Comment::class;
}
public function delete()
{
$this->request->validate([
'*' => 'uuid:activities',
]);
$deletedIds = [];
foreach ($this->request->all() as $activityId) {
$activity = Activity::idOrUuId($activityId);
try {
if ($this->authorize('delete', $activity)) {
$activity->delete();
$deletedIds[] = $activityId;
\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);
}
} catch (AuthorizationException $authorizationException) {
// They didn't have permission.
}
}
return $this->response->withArray($deletedIds);
}
public function update(Request $request, Activity $activity)
{
$this->authorize('updateMetadata', $activity);
$request->validate([
'title' => 'string|max:250',
'category_id' => 'uuid:playbook_categories',
'language' => [
new In(
LanguageDialect::query()
->with('language')
->cursor()
->map(static function (LanguageDialect $languageDialect): string {
return $languageDialect->getLanguageLocale();
})
->all()
),
],
]);
if ($request->has('title')) {
$activity->title = $request->input('title');
}
if ($request->has('category_id')) {
$category = PlaybookCategory::uuid($request->input('category_id'));
if ($category->playbook->team_id !== $request->user()->team_id) {
return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
if ($request->has('language')) {
if (! $activity->isInProgress()) {
return $this->response->withError(
'Activity language can only be set while the meeting is in progress.',
400
);
}
$activity->setLanguageCode($request->input('language'));
}
$activity->save();
return $this->response->withOk();
}
// XXX: This should be merged with the update method.
/**
* @param Activity $activity
*
* @throws AuthorizationException
* @throws SocialAccountTokenInvalidException
*
* @return mixed
*/
public function summarize(Activity $activity): mixed
{
$this->logger->info('[Log Activity] Summarizing activity ', [
'activityId' => $activity->getUuid(),
'payload' => $this->request->all(),
]);
$this->authorize('update', $activity);
$this->logger->info('[Log Activity] Validating summary');
// Validate the payload.
$this->validateSummary($activity);
// All objects must belong to this team.
/** @var User $user */
$user = $this->request->user();
$team = $user->getTeam();
$crmService = $this->providerRegistry->get($team->crm->provider);
try {
$crmUser = $user;
if ($user->isCrmRequired() === false) {
$crmUser = $team->owner;
}
$crmService->setUser($crmUser);
} catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());
}
$rawEntities = $this->request->input('entities');
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid(
$this->request->input('layout_id')
);
// Delay execution of CRM jobs to avoid locking issues.
$jobDelay = 0;
// If we have arrived from a notification, mark it as read.
$notificationId = $this->request->input('nId');
if ($notificationId) {
$notification = $user->unreadNotifications->where('id', $notificationId)->first();
if ($notification) {
$notification->markAsRead();
}
}
$title = $this->request->input('title');
$prospects = $this->request->input('prospects');
$opportunityId = $this->request->input('opportunity_id');
$stageId = $this->request->input('stage_id');
$categoryId = $this->request->input('category_id');
$summary = $this->request->input('summary');
$crmProviderId = $this->request->input('crm_id');
$isInternal = $this->request->input('is_internal') ?? false;
$lead = null;
$category = null;
$account = null;
$contact = null;
$opportunity = null;
$stage = null;
$callStage = null;
foreach ($prospects as $prospectData) {
$objectId = $prospectData['id'];
if ($objectId === null) {
continue;
}
$objectType = $prospectData['type'];
$this->logger->info('debug', ['prospect_data' => $prospectData]);
try {
if ($objectType === null) {
$this->logger->info('no object type');
if ($crmService instanceof SupportsObjectTypeParseInterface) {
$objectType = $crmService->parseObjectType($objectId);
}
}
switch ($objectType) {
case 'lead':
$this->logger->info('Processing lead');
/** @var Lead|null $lead */
$lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();
// Lead does not exist locally, import it.
if ($lead === null) {
$this->logger->info('Lead does not exist locally');
/** @var Lead $lead */
$lead = $crmService->syncLead($objectId);
}
$this->logger->info('Lead found', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
if ($stageId === null) {
$this->logger->info('Stage ID is null');
// If it was not provided, just assume it is the current stage.
$callStage = $lead->stage;
break;
}
$this->logger->info('Looking for stage');
// Determine if they have changed the stage.
/** @var Stage $stage */
$stage = $team->crm->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_LEAD)
->firstOrFail();
$this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);
if ($lead->stage_id && $lead->stage_id !== $stage->id) {
$this->logger->info('Stage has changed');
// Storage current stage on activity.
$callStage = $lead->stage;
// The stage has changed, update in remote CRM.
dispatch(new UpdateStage($activity, $lead, $callStage, $stage));
$this->logger->info(
sprintf(
'[%s] User changing lead stage from %s to %s',
$crmService->getDisplayName(),
$callStage->getName(),
$stage->getName()
),
[
'user' => $user->getUuid(),
'lead' => $lead->getUuid(),
]
);
} else {
$this->logger->info('Stage has not changed');
// Stage remains as current.
$callStage = $stage;
}
break;
case 'account':
$this->logger->info('Processing account');
// If the object is not a lead, it should be an account.
$account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();
// Account does not exist locally, import it.
if ($account === null) {
$this->logger->info('Account does not exist locally');
$account = $crmService->syncAccount($objectId);
}
$this->logger->info('Account found', ['accountId' => $account->id]);
break;
case 'contact':
$this->logger->info('processing contact');
$contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$this->logger->info('contact does not exist locally');
$contact = $crmService->syncContact($objectId);
}
$this->logger->info('resolving account');
$account = $this->resolveAccount($team, $contact, $crmService, $prospects);
break;
}
// If they have specified an opportunity, retrieve this with stage.
if ($opportunityId) {
$this->logger->info('opportunity id is set');
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if ($opportunity === null) {
$this->logger->info('opportunity does not exist locally');
$opportunity = $crmService->syncOpportunity($opportunityId);
}
if ($stageId === null) {
$this->logger->info('stage id is null');
// If it was not provided, just assume it is the current stage.
$callStage = $opportunity->stage ?? null;
} else {
$this->logger->info('looking for stage');
/** @var ?Stage $opportunityStage */
$opportunityStage = $team->crm
->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
// There is a chance we still cannot import this opportunity.
if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {
$this->logger->info('opportunity stage has changed');
// Storage current stage on activity.
$callStage = $opportunity->stage;
dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));
$this->logger->info(
sprintf(
'[%s] User changing opportunity stage from %s to %s',
$crmService->getDisplayName(),
$callStage->name,
$opportunityStage->name
),
[
'userId' => $user->id_string,
'opportunityId' => $opportunity->id_string,
]
);
} else {
$this->logger->info('opportunity stage has not changed');
// Stage remains as current.
$callStage = $opportunityStage;
}
}
}
if ($crmProviderId) {
// Cast $crmProviderId to string otherwise it won't use database index for some records
$linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();
// Check if this activity has already been assigned to a different activity.
if ($linkedActivity && $linkedActivity->id !== $activity->id) {
throw new InvalidArgumentException(
'Sorry, the linked task has already been logged under a different call. '
. 'Please choose another linked task.'
);
}
}
} catch (InvalidArgumentException $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($exception->getMessage());
} catch (Exception $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorInternalError(
'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'
);
}
}
if ($categoryId) {
$category = PlaybookCategory::uuid($categoryId);
if ($category->playbook->team_id !== $team->id) {
throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
$this->logger->info('Prospect data', [
'lead_id' => $lead?->getId(),
'account_id' => $account?->getId(),
'contact_id' => $contact?->getId(),
'opportunity_id' => $opportunity?->getId(),
'stage_id' => $stage?->getId(),
]);
if ($title) {
$activity->title = $title;
}
if ($summary) {
$activity->summary = $summary;
}
if ($crmProviderId) {
$activity->crm_provider_id = $crmProviderId;
}
if ($callStage) {
$this->logger->info('Setting stage id', ['stageId' => $callStage->id]);
$activity->stage_id = $callStage->id;
}
if ($lead) {
$this->logger->info('Setting lead id', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
// If we are changed from an account > lead, unset the account data.
$this->logger->info('Unsetting account id, opportunity id, contact id, value');
$activity->account_id = null;
$activity->opportunity_id = null;
$activity->contact_id = null;
$activity->value = null;
}
if ($account) {
$this->logger->info('Setting account id', ['accountId' => $account->id]);
$activity->account_id = $account->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('unsetting lead id');
$activity->lead_id = null;
// Unset the contact if switching different accounts. Will be set up below if still applicable.
if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {
$this->logger->info('Unsetting contact id');
$activity->contact_id = null;
}
}
if ($opportunity) {
$this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);
$this->logger->info('unsetting lead id');
$activity->opportunity_id = $opportunity->id;
$activity->value = $opportunity->value;
// If we are changed from an lead > account, unset the lead data.
$activity->lead_id = null;
}
if ($contact) {
$this->logger->info('setting contact id', ['contactId' => $contact->id]);
$activity->contact_id = $contact->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('Unsetting lead id');
$activity->lead_id = null;
}
$activity->is_internal = $isInternal;
$activity->save();
$activity->refresh();
$this->logger->notice('Activity saved', [
'activity_id' => $activity->getId(),
'lead_id' => $activity->lead_id,
'account_id' => $activity->account_id,
'contact_id' => $activity->contact_id,
'opportunity_id' => $activity->opportunity_id,
'stage_id' => $activity->stage_id,
'crm_provider_id' => $activity->getCrmProviderId(),
]);
// Store entities as field data on the activity.
$updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);
if ($activity->isLoggable()) {
// Follow-up Task or Event data.
$followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);
$this->logger->info('CRM LOG manual log triggered', [
'activityId' => $activity->getUuid(),
'followupData' => $followupData,
'userId' => $user->getUuid(),
]);
// Store data in the CRM.
// ++add check for crm_required
$job = new SaveActivity($activity, $followupData);
if ($updatedData) {
$job->delay(Carbon::now()->addMinutes($jobDelay));
}
dispatch($job);
// Manually dispatch log for Opportunity or Prospect added
if ($activity->hasOpportunity() || $activity->hasProspect()) {
event(new ActivityProspectAdded(
activity: $activity,
eventSource: 'manually-log-crm-data'
));
}
}
return $this->response->withOk();
}
/**
* Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.
*
* @param ServiceInterface $service
* @param Activity $activity
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array
{
$updatedData = [];
$existingData = $activity->data()->get();
// We need to delete any existing data to overwrite with latest values.
$activity->data()->delete();
$layoutEntities = $layout->entities()
->with('field', 'parent')
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->get();
/** @var LayoutEntity $entity */
foreach ($layoutEntities as $entity) {
// If the user has provided a value for this entity
if (array_key_exists($entity->id_string, $entities)) {
$value = $entities[$entity->id_string];
// Convert raw data into values that the CRM can consume.
if ($value) {
$value = $service->normalizeValue($entity->field->type, $value);
}
// Check the field is part of the activity-summary section.
if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {
// This is the internal database ID, not the external CRM ID.
$objectId = null;
switch ($entity->field->object_type) {
case Field::OBJECT_ACCOUNT:
$objectId = $activity->account_id;
break;
case Field::OBJECT_CONTACT:
$objectId = $activity->contact_id;
break;
case Field::OBJECT_OPPORTUNITY:
$objectId = $activity->opportunity_id;
break;
case Field::OBJECT_LEAD:
$objectId = $activity->lead_id;
break;
case Field::OBJECT_TASK:
case Field::OBJECT_EVENT:
$objectId = $activity->id;
break;
}
if ($objectId) {
/** @var FieldData $data */
$data = $activity->data()->create([
'crm_layout_entity_id' => $entity->id,
'crm_field_id' => $entity->crm_field_id,
'object_type' => $entity->field->object_type,
'object_id' => $objectId,
'value' => $value,
]);
// Never send read-only field data to the CRM.
if ($entity->read_only === false && $entity->is_visible) {
$existingValue = $existingData
->where('crm_layout_entity_id', $entity->id)
->where('crm_field_id', $entity->crm_field_id)
->where('object_type', $entity->field->object_type)
->where('object_id', $objectId)
->first();
// If the field was actually changed, we need to reflect this in the CRM too.
if ($existingValue === null || $existingValue->value !== $value) {
$updatedData[] = $data->id;
}
}
}
}
}
}
return $updatedData;
}
/**
* Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.
*
* @param ServiceInterface $crmService
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array
{
$fieldData = [];
foreach ($entities as $entityId => $value) {
// Only bother with fields that have a value.
if ($value) {
// Extract the entity from the UUID. Check the field is valid and part of the follow-up section.
$entity = $layout->entities()
->uuid($entityId, false)
->whereHas('parent', function ($query) {
$query->where('label', 'follow-up');
})
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->first();
if ($entity) {
// Convert raw data into values that the CRM can consume.
$value = $crmService->normalizeValue($entity->field->type, $value);
// Add the field and value to the payload.
$fieldData += [
$entity->field->crm_provider_id => $value,
];
}
}
}
return $fieldData;
}
/**
* @param Activity $activity
*/
private function validateSummary(Activity $activity): void
{
$team = $activity->user->team;
$crmProvider = $team->crm->provider;
$attributes = [];
$rules = [
'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,
'title' => 'string|max:250',
'prospects' => 'required|array',
'opportunity_id' => new CrmReference($crmProvider),
'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',
'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator
'summary' => 'max:50000',
'nId' => 'exists:notifications,id',
'crm_id' => new CrmReference($crmProvider),
'entities' => 'array',
'is_internal' => 'boolean',
];
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));
// Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.
$entities = $layout->entities()
->where('read_only', 0)
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->whereHas('parent', function ($query) use ($activity) {
if ($activity->isLoggable() === false) {
$query->where('label', '<>', 'follow-up');
}
});
$isInternal = $this->request->input('is_internal', false);
foreach ($entities->get() as $entity) {
$rules += $this->buildFieldValidator($entity, $isInternal);
$attributes += $this->buildFieldMessage($entity);
}
$this->request->validate($rules, [], $attributes);
}
private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array
{
return [
'entities.' . $entity->id_string => $entity->getValidator($isInternal),
];
}
/**
* @param LayoutEntity $entity
*
* @return array
*/
private function buildFieldMessage(LayoutEntity $entity): array
{
$label = $entity->label;
if ($label === null) {
$label = $entity->field->label;
}
return [
'entities.' . $entity->id_string => $label,
];
}
public function search(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->debugLog(
$user,
'User extracted from request',
['user' => $user->getId(), 'tz' => $user->getTimezone()]
);
$searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());
$this->debugLog(
$user,
'ActivitySearch criteria built',
['searchCriteria' => $searchCriteria]
);
$filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);
$this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);
$this->validateSearch($request, $filterSet);
$this->debugLog($user, 'Request validated');
$searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);
/** @var Collection<Activity> $activities */
$activities = $searchResponse['results'];
$this->debugLog($user, 'Activities ES response extracted');
$hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(
$user->getTeamId(),
TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),
);
if ($hideInternalMeetingsSetting?->getValue() === '1') {
$activities = $activities->filter(function (Activity $activity) {
if ($activity->is_internal && empty($activity->actual_start_time)) {
return false;
}
return true;
});
}
$this->debugLog($user, 'Internal meetings (?!) filtered');
$this->response->getManager()
->parseIncludes([
'category',
'organizer.group',
'prospect',
'stage',
'opportunity',
'stats',
'scorecards',
'masterTrack',
'activeParticipants',
'notification',
])
->setSerializer(new JsonSerializer());
$transformerExcludes = $this->request->input('exclude');
if ($transformerExcludes) {
$this->response->getManager()->parseExcludes($transformerExcludes);
}
$this->debugLog($user, 'Response Manager (?!) applied');
$transformer = new ActivityTransformer();
$transformer->setConsumer($user);
$this->debugLog($user, 'Activity Transformer added');
$resource = new \League\Fractal\Resource\Collection($activities, $transformer);
$page = $searchCriteria->getPageNumber();
$this->debugLog($user, 'Search criteria page number called', ['page' => $page]);
$histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');
$this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);
return $this->response->withArray([
'pagination' => [
'total' => $searchResponse['totalHits'],
'current' => $page,
'prev' => max($page - 1, 1),
'next' => $page + 1,
],
'results' => $this->response->getManager()->createData($resource)->toArray(),
'histogram' => $histogram,
]);
}
private function debugLog(User $user, string $logMessage, ?array $context = []): void
{
// Debug for Learning People Only
if ($user->getTeamId() !== 260) {
return;
}
Log::notice(
sprintf('[activity-search-controller] %s', $logMessage),
$context
);
}
/** @throws ValidationException */
private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void
{
$rules = [
'exclude' => 'array',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
];
if ($prefix !== null && mb_strpos($prefix, '.') !== false) {
$rules[rtrim($prefix, '.')] = sprintf(
'required|array|max:%d',
$filterSet->count()
);
}
$validationRules = $filterSet->getValidationRules($prefix)
->merge($rules)
->all();
$request->validate($validationRules);
}
public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$search = $this->updateOrCreateActivitySearch($request);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function updateActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('update', $search);
$this->updateOrCreateActivitySearch($request, $search);
return $this->response->withOk();
}
private function storeNamedSearchFilters(
Collection $request,
Search $search,
FilterDefinitionCollection $filterSet,
?string $prefix = null,
): self {
$arrayTypeProperties = $filterSet
->getPropertyTypes([
FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,
])
->all();
$supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);
foreach ($supportedRequestProperties as $requestPropertyName) {
if (! array_has($request, $requestPropertyName)) {
continue;
}
/** @var string|string[] $propertyValue */
$propertyValue = array_get($request, $requestPropertyName);
$propertyName = $prefix === null
? $requestPropertyName
: mb_substr($requestPropertyName, mb_strlen($prefix));
$isArrayType = array_has($arrayTypeProperties, $propertyName);
if (! $isArrayType) {
/** @var string $requestPropertyValue */
$search->filters()->updateOrCreate(
[
'filter' => $propertyName,
],
[
'value' => $propertyValue,
]
);
continue;
}
/** @var string[] $requestPropertyValue */
/** @var SearchFilter[]|Collection $existingFilterValues */
$existingFilterValuesKeyed = $search->filters()
->where('filter', $propertyName)
->get()
->keyBy('id');
// Iterate over values provided as request parameters
foreach ($propertyValue as $value) {
/** @var SearchFilter|null $valueFilter */
$valueFilter = $search->filters()
->where(
[
'filter' => $propertyName,
'value' => $value,
]
)
->first();
if ($valueFilter !== null) {
// Remove filter value pair from list to be deleted
$existingFilterValuesKeyed->forget($valueFilter->id);
} else {
// Add new filter/value pair
$search->filters()->updateOrCreate([
'filter' => $propertyName,
'value' => $value,
]);
}
}
// Delete filter value pairs for this filter that no longer exist in request parameters
foreach ($existingFilterValuesKeyed as $existingFilter) {
$existingFilter->delete();
}
}
/** @var Collection<int, SearchFilter> $filtersKeyed */
$filtersKeyed = $search->filters()->get()->keyBy('filter');
// wipe removed filters from this search
foreach ($filtersKeyed as $filterName => $filter) {
if (array_has($request, $prefix . $filterName)) {
continue;
}
// Remove all filter values for this filter
$search->filters()->where('filter', $filterName)->delete();
}
return $this;
}
/**
* @throws AuthorizationException
*/
public function fetchActivitySearch(
Search $search,
Request $request,
SearchTransformer $searchTransformer,
): JsonResponse {
$this->authorize('view', $search);
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withCollection(
$user->searches()->get(),
$searchTransformer
->withConsumer($user)
);
}
/**
* Deletes a saved search
*
* @param Request $request
* @param Search $search
*
* @throws Exception
*
* @return JsonResponse
*/
public function deleteActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('delete', $search);
// Orphan any AutomatedReports that use this search
$search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);
// Delete filters and the search itself
$search->filters()->delete();
$search->delete();
return $this->response->withOk();
}
public function live(Request $request, ElasticActivityRepository $repository): JsonResponse
{
$user = $this->getUserFromRequest($request);
$this->request->validate([
'sort_direction' => 'in:asc,desc',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
]);
$activities = $repository->getLiveCoachingEligibleActivities(
user: $user,
lookBackMinutes: self::LOOK_BACK,
limit: (int) $this->request->input('limit', 25),
page: (int) $this->request->input('page', 1),
sortBy: ['actual_start_time', 'scheduled_start_time'],
sortDirection: (string) $this->request->input('sort_direction', 'asc'),
);
$this->response
->getManager()
->parseIncludes(['organizer.group', 'prospect'])
->setSerializer(new JsonSerializer());
return $this->response->withCollection($activities, new ActivityTransformer());
}
/**
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function show(Activity $activity, ActivityService $activityService): JsonResponse
{
$this->authorize('show', $activity);
$user = $activity->getUser();
$team = $user->getTeam();
// Sync the opportunity with the latest data if possible.
if ($activity->opportunity_id) {
try {
$crmService = $this->providerRegistry->get($team->crm->provider);
if (! $user->isCrmRequired()) {
$crmService->setUser($team->getOwner());
} else {
$crmService->setUser($user);
}
$crmService->syncOpportunity($activity->opportunity->crm_provider_id);
} catch (Exception $exception) {
// Move on.
}
}
$activityData = $activityService->getActivityData($this->request->user(), $activity);
return response()->json($activityData);
}
public function createRecording(Activity $activity)
{
$this->authorize('record', $activity);
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Tell Twilio to start recording this activity.
if ($activity->recording_state === Activity::RECORDING_OFF) {
$job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withCreated();
}
return $this->response->errorGone('Activity is already recording.');
}
public function updateRecording(Request $request, Activity $activity)
{
$this->authorize('record', $activity);
$request->validate([
'preference' => 'boolean',
'state' => [
'string',
Rule::in([
Activity::RECORDING_IN_PROGRESS,
Activity::RECORDING_PAUSED,
]),
],
]);
if ($request->has('state')) {
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Toggle the recording state between paused and resumed.
if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {
$job = (new ToggleRecording($activity, $request->input('state')))
->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Recording is not toggleable.');
}
if ($request->has('preference')) {
$activity->update([
'recording_preference' => $request->input('preference') ? 1 : 0,
]);
return $this->response->withOk();
}
return $this->response->errorWrongArgs('Something went wrong');
}
public function stopRecording(Activity $activity)
{
$this->authorize('stopRecord', $activity);
// Tell Twilio to stop recording this activity.
if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {
$job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Activity is not recording.');
}
/**
* Add activity to this user's favorites playlist
*
* @throws AuthorizationException
*/
public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse
{
$this->authorize('favorite', $activity);
$user = $this->getUserFromRequest($this->request);
$favorite = $activity->wasFavoritedBy($user);
$name = $activity->activity_title ?? '';
// It needs to check at least one record.
if (! $favorite) {
$favoritePlaylist = $user->favoritePlaylist();
$playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(
$activity,
$user,
$favoritePlaylist
);
if ($playlistActivity !== null) {
$playlistActivity->update(
// Just update, don't sort.
['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],
);
} else {
$playlistActivity = $activity->playlistActivities()->create([
'playlist_id' => $favoritePlaylist->getId(),
'user_id' => $user->getId(),
'start_time' => 0,
'name' => mb_strimwidth($name, 0, 100),
]);
// Sort it on top.
$playlistActivity->update(
[
'sort' => $playlistActivityRepository->calculateNewSortOrder(
null,
$playlistActivity,
),
],
);
}
$playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);
return new JsonResponse([], JsonResponse::HTTP_CREATED);
}
return new JsonResponse(
[
'error' => [
'code' => AbstractResponse::CODE_CONFLICT,
'http_code' => JsonResponse::HTTP_CONFLICT,
'message' => 'Resource Already Exists',
],
],
JsonResponse::HTTP_CONFLICT,
);
}
/**
* Remove activity from this user's favorites playlist
*
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function unfavorite(Activity $activity)
{
$user = $t...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.034242023,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Analyzing…","depth":4,"bounds":{"left":0.37200797,"top":0.07581804,"width":0.019946808,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.39361703,"top":0.074221864,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.40093085,"top":0.074221864,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Http\\Controllers\\API;\n\nuse Carbon\\Carbon;\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Exception;\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Validation\\Rule;\nuse Illuminate\\Validation\\Rules\\In;\nuse Illuminate\\Validation\\ValidationException;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ActivityAnalytics;\nuse Jiminny\\Component\\ActivitySearch;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Contracts\\ES\\Events\\UpdateSingleEntity;\nuse Jiminny\\Contracts\\ES\\UpdateTargetEnum;\nuse Jiminny\\Contracts\\Nudge\\NudgeFactoryInterface;\nuse Jiminny\\Contracts\\Playlist\\PlaylistTrackFactoryInterface;\nuse Jiminny\\Contracts\\Repositories\\PlaylistActivityRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Enums\\TeamSetting;\nuse Jiminny\\Events\\Activities\\AiAutomation\\ActivityProspectAdded;\nuse Jiminny\\Events\\Activities\\Coaching\\Coached;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Controllers\\CommentContextInterface;\nuse Jiminny\\Http\\Responses\\Api\\AbstractResponse;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\ActivityCommentTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTopicTriggerTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTransformer;\nuse Jiminny\\Http\\Transformers\\AvailabilityNotificationTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingFeedbackTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingSectionsTransformer;\nuse Jiminny\\Http\\Transformers\\SearchTransformer;\nuse Jiminny\\Http\\Transformers\\StatsTransformer;\nuse Jiminny\\Jobs\\Crm\\SaveActivity;\nuse Jiminny\\Jobs\\Crm\\UpdateStage;\nuse Jiminny\\Jobs\\Telephony\\StartRecording;\nuse Jiminny\\Jobs\\Telephony\\StopRecording;\nuse Jiminny\\Jobs\\Telephony\\ToggleRecording;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\CoachingFeedback;\nuse Jiminny\\Models\\CoachingSection;\nuse Jiminny\\Models\\CoachingSectionCriterion;\nuse Jiminny\\Models\\CoachingSectionFeedback;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\LanguageDialect;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Nudge;\nuse Jiminny\\Models\\PlaybookCategory;\nuse Jiminny\\Models\\Playlist;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\Track;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\CoachingFeedbackRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Rules\\MultidimensionalArrayMaxCharRule;\nuse Jiminny\\Services\\ActivityService;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Services\\PlaybackService;\nuse Jiminny\\Services\\UserService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\nuse Ramsey\\Uuid\\Uuid;\nuse Sentry;\nuse Symfony\\Component\\HttpFoundation;\n\nfinal class ActivityController extends Controller implements CommentContextInterface\n{\n // Number of minutes to look back on activities. i.e. a timeout on activity duration.\n private const int LOOK_BACK = 180;\n\n public function __construct(\n private ProviderRegistry $providerRegistry,\n private ActivityService $activityService,\n Response $response,\n private UserService $userService,\n private ActivitySearch\\Service\\ActivitySearch $activitySearch,\n private NudgeFactoryInterface $nudgeFactory,\n private ActivityCommentService $activityCommentService,\n private LoggerInterface $logger,\n private readonly CoachingFeedbackRepository $coachingFeedbackRepository,\n private readonly TeamRepository $teamRepository,\n ) {\n parent::__construct($response);\n }\n\n public static function getCommentImplementation(): string\n {\n return Comment::class;\n }\n\n public function delete()\n {\n $this->request->validate([\n '*' => 'uuid:activities',\n ]);\n\n $deletedIds = [];\n foreach ($this->request->all() as $activityId) {\n $activity = Activity::idOrUuId($activityId);\n\n try {\n if ($this->authorize('delete', $activity)) {\n $activity->delete();\n $deletedIds[] = $activityId;\n\n \\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n }\n } catch (AuthorizationException $authorizationException) {\n // They didn't have permission.\n }\n }\n\n return $this->response->withArray($deletedIds);\n }\n\n public function update(Request $request, Activity $activity)\n {\n $this->authorize('updateMetadata', $activity);\n\n $request->validate([\n 'title' => 'string|max:250',\n 'category_id' => 'uuid:playbook_categories',\n 'language' => [\n new In(\n LanguageDialect::query()\n ->with('language')\n ->cursor()\n ->map(static function (LanguageDialect $languageDialect): string {\n return $languageDialect->getLanguageLocale();\n })\n ->all()\n ),\n ],\n ]);\n\n if ($request->has('title')) {\n $activity->title = $request->input('title');\n }\n\n if ($request->has('category_id')) {\n $category = PlaybookCategory::uuid($request->input('category_id'));\n\n if ($category->playbook->team_id !== $request->user()->team_id) {\n return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n if ($request->has('language')) {\n if (! $activity->isInProgress()) {\n return $this->response->withError(\n 'Activity language can only be set while the meeting is in progress.',\n 400\n );\n }\n\n $activity->setLanguageCode($request->input('language'));\n }\n\n $activity->save();\n\n return $this->response->withOk();\n }\n\n // XXX: This should be merged with the update method.\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws SocialAccountTokenInvalidException\n *\n * @return mixed\n */\n public function summarize(Activity $activity): mixed\n {\n $this->logger->info('[Log Activity] Summarizing activity ', [\n 'activityId' => $activity->getUuid(),\n 'payload' => $this->request->all(),\n ]);\n $this->authorize('update', $activity);\n\n $this->logger->info('[Log Activity] Validating summary');\n // Validate the payload.\n $this->validateSummary($activity);\n\n // All objects must belong to this team.\n /** @var User $user */\n $user = $this->request->user();\n $team = $user->getTeam();\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n try {\n $crmUser = $user;\n if ($user->isCrmRequired() === false) {\n $crmUser = $team->owner;\n }\n $crmService->setUser($crmUser);\n } catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());\n }\n\n $rawEntities = $this->request->input('entities');\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid(\n $this->request->input('layout_id')\n );\n\n // Delay execution of CRM jobs to avoid locking issues.\n $jobDelay = 0;\n\n // If we have arrived from a notification, mark it as read.\n $notificationId = $this->request->input('nId');\n if ($notificationId) {\n $notification = $user->unreadNotifications->where('id', $notificationId)->first();\n\n if ($notification) {\n $notification->markAsRead();\n }\n }\n\n $title = $this->request->input('title');\n $prospects = $this->request->input('prospects');\n $opportunityId = $this->request->input('opportunity_id');\n $stageId = $this->request->input('stage_id');\n $categoryId = $this->request->input('category_id');\n $summary = $this->request->input('summary');\n $crmProviderId = $this->request->input('crm_id');\n $isInternal = $this->request->input('is_internal') ?? false;\n\n $lead = null;\n $category = null;\n $account = null;\n $contact = null;\n $opportunity = null;\n $stage = null;\n $callStage = null;\n\n foreach ($prospects as $prospectData) {\n $objectId = $prospectData['id'];\n\n if ($objectId === null) {\n continue;\n }\n\n $objectType = $prospectData['type'];\n $this->logger->info('debug', ['prospect_data' => $prospectData]);\n\n try {\n if ($objectType === null) {\n $this->logger->info('no object type');\n if ($crmService instanceof SupportsObjectTypeParseInterface) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n }\n\n switch ($objectType) {\n case 'lead':\n $this->logger->info('Processing lead');\n /** @var Lead|null $lead */\n $lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();\n\n // Lead does not exist locally, import it.\n if ($lead === null) {\n $this->logger->info('Lead does not exist locally');\n /** @var Lead $lead */\n $lead = $crmService->syncLead($objectId);\n }\n\n $this->logger->info('Lead found', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n if ($stageId === null) {\n $this->logger->info('Stage ID is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $lead->stage;\n\n break;\n }\n\n $this->logger->info('Looking for stage');\n // Determine if they have changed the stage.\n /** @var Stage $stage */\n $stage = $team->crm->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_LEAD)\n ->firstOrFail();\n\n $this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);\n if ($lead->stage_id && $lead->stage_id !== $stage->id) {\n $this->logger->info('Stage has changed');\n // Storage current stage on activity.\n $callStage = $lead->stage;\n\n // The stage has changed, update in remote CRM.\n dispatch(new UpdateStage($activity, $lead, $callStage, $stage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing lead stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->getName(),\n $stage->getName()\n ),\n [\n 'user' => $user->getUuid(),\n 'lead' => $lead->getUuid(),\n ]\n );\n } else {\n $this->logger->info('Stage has not changed');\n // Stage remains as current.\n $callStage = $stage;\n }\n\n break;\n\n case 'account':\n $this->logger->info('Processing account');\n // If the object is not a lead, it should be an account.\n $account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();\n\n // Account does not exist locally, import it.\n if ($account === null) {\n $this->logger->info('Account does not exist locally');\n $account = $crmService->syncAccount($objectId);\n }\n\n $this->logger->info('Account found', ['accountId' => $account->id]);\n\n break;\n case 'contact':\n $this->logger->info('processing contact');\n $contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $this->logger->info('contact does not exist locally');\n $contact = $crmService->syncContact($objectId);\n }\n\n $this->logger->info('resolving account');\n $account = $this->resolveAccount($team, $contact, $crmService, $prospects);\n\n break;\n }\n\n // If they have specified an opportunity, retrieve this with stage.\n if ($opportunityId) {\n $this->logger->info('opportunity id is set');\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if ($opportunity === null) {\n $this->logger->info('opportunity does not exist locally');\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n if ($stageId === null) {\n $this->logger->info('stage id is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $opportunity->stage ?? null;\n } else {\n $this->logger->info('looking for stage');\n /** @var ?Stage $opportunityStage */\n $opportunityStage = $team->crm\n ->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n // There is a chance we still cannot import this opportunity.\n if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {\n $this->logger->info('opportunity stage has changed');\n // Storage current stage on activity.\n $callStage = $opportunity->stage;\n\n dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing opportunity stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->name,\n $opportunityStage->name\n ),\n [\n 'userId' => $user->id_string,\n 'opportunityId' => $opportunity->id_string,\n ]\n );\n } else {\n $this->logger->info('opportunity stage has not changed');\n // Stage remains as current.\n $callStage = $opportunityStage;\n }\n }\n }\n\n if ($crmProviderId) {\n // Cast $crmProviderId to string otherwise it won't use database index for some records\n $linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();\n\n // Check if this activity has already been assigned to a different activity.\n if ($linkedActivity && $linkedActivity->id !== $activity->id) {\n throw new InvalidArgumentException(\n 'Sorry, the linked task has already been logged under a different call. '\n . 'Please choose another linked task.'\n );\n }\n }\n } catch (InvalidArgumentException $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($exception->getMessage());\n } catch (Exception $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorInternalError(\n 'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'\n );\n }\n }\n\n if ($categoryId) {\n $category = PlaybookCategory::uuid($categoryId);\n\n if ($category->playbook->team_id !== $team->id) {\n throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n $this->logger->info('Prospect data', [\n 'lead_id' => $lead?->getId(),\n 'account_id' => $account?->getId(),\n 'contact_id' => $contact?->getId(),\n 'opportunity_id' => $opportunity?->getId(),\n 'stage_id' => $stage?->getId(),\n ]);\n\n if ($title) {\n $activity->title = $title;\n }\n\n if ($summary) {\n $activity->summary = $summary;\n }\n\n if ($crmProviderId) {\n $activity->crm_provider_id = $crmProviderId;\n }\n\n if ($callStage) {\n $this->logger->info('Setting stage id', ['stageId' => $callStage->id]);\n $activity->stage_id = $callStage->id;\n }\n\n if ($lead) {\n $this->logger->info('Setting lead id', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n // If we are changed from an account > lead, unset the account data.\n $this->logger->info('Unsetting account id, opportunity id, contact id, value');\n $activity->account_id = null;\n $activity->opportunity_id = null;\n $activity->contact_id = null;\n $activity->value = null;\n }\n\n if ($account) {\n $this->logger->info('Setting account id', ['accountId' => $account->id]);\n $activity->account_id = $account->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('unsetting lead id');\n $activity->lead_id = null;\n\n // Unset the contact if switching different accounts. Will be set up below if still applicable.\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {\n $this->logger->info('Unsetting contact id');\n $activity->contact_id = null;\n }\n }\n\n if ($opportunity) {\n $this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);\n $this->logger->info('unsetting lead id');\n $activity->opportunity_id = $opportunity->id;\n $activity->value = $opportunity->value;\n\n // If we are changed from an lead > account, unset the lead data.\n $activity->lead_id = null;\n }\n\n if ($contact) {\n $this->logger->info('setting contact id', ['contactId' => $contact->id]);\n $activity->contact_id = $contact->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('Unsetting lead id');\n $activity->lead_id = null;\n }\n\n $activity->is_internal = $isInternal;\n $activity->save();\n $activity->refresh();\n\n $this->logger->notice('Activity saved', [\n 'activity_id' => $activity->getId(),\n 'lead_id' => $activity->lead_id,\n 'account_id' => $activity->account_id,\n 'contact_id' => $activity->contact_id,\n 'opportunity_id' => $activity->opportunity_id,\n 'stage_id' => $activity->stage_id,\n 'crm_provider_id' => $activity->getCrmProviderId(),\n ]);\n\n // Store entities as field data on the activity.\n $updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);\n\n if ($activity->isLoggable()) {\n // Follow-up Task or Event data.\n $followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);\n\n $this->logger->info('CRM LOG manual log triggered', [\n 'activityId' => $activity->getUuid(),\n 'followupData' => $followupData,\n 'userId' => $user->getUuid(),\n ]);\n\n // Store data in the CRM.\n // ++add check for crm_required\n $job = new SaveActivity($activity, $followupData);\n\n if ($updatedData) {\n $job->delay(Carbon::now()->addMinutes($jobDelay));\n }\n\n dispatch($job);\n\n // Manually dispatch log for Opportunity or Prospect added\n if ($activity->hasOpportunity() || $activity->hasProspect()) {\n event(new ActivityProspectAdded(\n activity: $activity,\n eventSource: 'manually-log-crm-data'\n ));\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.\n *\n * @param ServiceInterface $service\n * @param Activity $activity\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array\n {\n $updatedData = [];\n $existingData = $activity->data()->get();\n\n // We need to delete any existing data to overwrite with latest values.\n $activity->data()->delete();\n\n $layoutEntities = $layout->entities()\n ->with('field', 'parent')\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->get();\n\n /** @var LayoutEntity $entity */\n foreach ($layoutEntities as $entity) {\n // If the user has provided a value for this entity\n if (array_key_exists($entity->id_string, $entities)) {\n $value = $entities[$entity->id_string];\n\n // Convert raw data into values that the CRM can consume.\n if ($value) {\n $value = $service->normalizeValue($entity->field->type, $value);\n }\n\n // Check the field is part of the activity-summary section.\n if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {\n // This is the internal database ID, not the external CRM ID.\n $objectId = null;\n\n switch ($entity->field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $objectId = $activity->account_id;\n\n break;\n\n case Field::OBJECT_CONTACT:\n $objectId = $activity->contact_id;\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n $objectId = $activity->opportunity_id;\n\n break;\n\n case Field::OBJECT_LEAD:\n $objectId = $activity->lead_id;\n\n break;\n\n case Field::OBJECT_TASK:\n case Field::OBJECT_EVENT:\n $objectId = $activity->id;\n\n break;\n }\n\n if ($objectId) {\n /** @var FieldData $data */\n $data = $activity->data()->create([\n 'crm_layout_entity_id' => $entity->id,\n 'crm_field_id' => $entity->crm_field_id,\n 'object_type' => $entity->field->object_type,\n 'object_id' => $objectId,\n 'value' => $value,\n ]);\n\n // Never send read-only field data to the CRM.\n if ($entity->read_only === false && $entity->is_visible) {\n $existingValue = $existingData\n ->where('crm_layout_entity_id', $entity->id)\n ->where('crm_field_id', $entity->crm_field_id)\n ->where('object_type', $entity->field->object_type)\n ->where('object_id', $objectId)\n ->first();\n\n // If the field was actually changed, we need to reflect this in the CRM too.\n if ($existingValue === null || $existingValue->value !== $value) {\n $updatedData[] = $data->id;\n }\n }\n }\n }\n }\n }\n\n return $updatedData;\n }\n\n /**\n * Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.\n *\n * @param ServiceInterface $crmService\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array\n {\n $fieldData = [];\n foreach ($entities as $entityId => $value) {\n // Only bother with fields that have a value.\n if ($value) {\n // Extract the entity from the UUID. Check the field is valid and part of the follow-up section.\n $entity = $layout->entities()\n ->uuid($entityId, false)\n ->whereHas('parent', function ($query) {\n $query->where('label', 'follow-up');\n })\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->first();\n\n if ($entity) {\n // Convert raw data into values that the CRM can consume.\n $value = $crmService->normalizeValue($entity->field->type, $value);\n\n // Add the field and value to the payload.\n $fieldData += [\n $entity->field->crm_provider_id => $value,\n ];\n }\n }\n }\n\n return $fieldData;\n }\n\n /**\n * @param Activity $activity\n */\n private function validateSummary(Activity $activity): void\n {\n $team = $activity->user->team;\n $crmProvider = $team->crm->provider;\n $attributes = [];\n\n $rules = [\n 'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,\n 'title' => 'string|max:250',\n 'prospects' => 'required|array',\n 'opportunity_id' => new CrmReference($crmProvider),\n 'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',\n 'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator\n 'summary' => 'max:50000',\n 'nId' => 'exists:notifications,id',\n 'crm_id' => new CrmReference($crmProvider),\n 'entities' => 'array',\n 'is_internal' => 'boolean',\n ];\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));\n\n // Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.\n $entities = $layout->entities()\n ->where('read_only', 0)\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->whereHas('parent', function ($query) use ($activity) {\n if ($activity->isLoggable() === false) {\n $query->where('label', '<>', 'follow-up');\n }\n });\n\n $isInternal = $this->request->input('is_internal', false);\n\n foreach ($entities->get() as $entity) {\n $rules += $this->buildFieldValidator($entity, $isInternal);\n $attributes += $this->buildFieldMessage($entity);\n }\n\n $this->request->validate($rules, [], $attributes);\n }\n\n private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array\n {\n return [\n 'entities.' . $entity->id_string => $entity->getValidator($isInternal),\n ];\n }\n\n /**\n * @param LayoutEntity $entity\n *\n * @return array\n */\n private function buildFieldMessage(LayoutEntity $entity): array\n {\n $label = $entity->label;\n if ($label === null) {\n $label = $entity->field->label;\n }\n\n return [\n 'entities.' . $entity->id_string => $label,\n ];\n }\n\n public function search(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->debugLog(\n $user,\n 'User extracted from request',\n ['user' => $user->getId(), 'tz' => $user->getTimezone()]\n );\n\n $searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());\n\n $this->debugLog(\n $user,\n 'ActivitySearch criteria built',\n ['searchCriteria' => $searchCriteria]\n );\n\n $filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);\n\n $this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);\n\n $this->validateSearch($request, $filterSet);\n\n $this->debugLog($user, 'Request validated');\n\n $searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);\n\n /** @var Collection<Activity> $activities */\n $activities = $searchResponse['results'];\n\n $this->debugLog($user, 'Activities ES response extracted');\n\n $hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(\n $user->getTeamId(),\n TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),\n );\n\n if ($hideInternalMeetingsSetting?->getValue() === '1') {\n $activities = $activities->filter(function (Activity $activity) {\n if ($activity->is_internal && empty($activity->actual_start_time)) {\n return false;\n }\n\n return true;\n });\n }\n\n $this->debugLog($user, 'Internal meetings (?!) filtered');\n\n $this->response->getManager()\n ->parseIncludes([\n 'category',\n 'organizer.group',\n 'prospect',\n 'stage',\n 'opportunity',\n 'stats',\n 'scorecards',\n 'masterTrack',\n 'activeParticipants',\n 'notification',\n ])\n ->setSerializer(new JsonSerializer());\n\n $transformerExcludes = $this->request->input('exclude');\n if ($transformerExcludes) {\n $this->response->getManager()->parseExcludes($transformerExcludes);\n }\n\n $this->debugLog($user, 'Response Manager (?!) applied');\n\n $transformer = new ActivityTransformer();\n $transformer->setConsumer($user);\n\n $this->debugLog($user, 'Activity Transformer added');\n\n $resource = new \\League\\Fractal\\Resource\\Collection($activities, $transformer);\n $page = $searchCriteria->getPageNumber();\n\n $this->debugLog($user, 'Search criteria page number called', ['page' => $page]);\n\n $histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');\n\n $this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);\n\n return $this->response->withArray([\n 'pagination' => [\n 'total' => $searchResponse['totalHits'],\n 'current' => $page,\n 'prev' => max($page - 1, 1),\n 'next' => $page + 1,\n ],\n 'results' => $this->response->getManager()->createData($resource)->toArray(),\n 'histogram' => $histogram,\n ]);\n }\n\n private function debugLog(User $user, string $logMessage, ?array $context = []): void\n {\n // Debug for Learning People Only\n if ($user->getTeamId() !== 260) {\n return;\n }\n\n Log::notice(\n sprintf('[activity-search-controller] %s', $logMessage),\n $context\n );\n }\n\n /** @throws ValidationException */\n private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void\n {\n $rules = [\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ];\n\n if ($prefix !== null && mb_strpos($prefix, '.') !== false) {\n $rules[rtrim($prefix, '.')] = sprintf(\n 'required|array|max:%d',\n $filterSet->count()\n );\n }\n\n $validationRules = $filterSet->getValidationRules($prefix)\n ->merge($rules)\n ->all();\n\n $request->validate($validationRules);\n }\n\n public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $search = $this->updateOrCreateActivitySearch($request);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function updateActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('update', $search);\n\n $this->updateOrCreateActivitySearch($request, $search);\n\n return $this->response->withOk();\n }\n\n private function storeNamedSearchFilters(\n Collection $request,\n Search $search,\n FilterDefinitionCollection $filterSet,\n ?string $prefix = null,\n ): self {\n $arrayTypeProperties = $filterSet\n ->getPropertyTypes([\n FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,\n ])\n ->all();\n\n $supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);\n\n foreach ($supportedRequestProperties as $requestPropertyName) {\n if (! array_has($request, $requestPropertyName)) {\n continue;\n }\n\n /** @var string|string[] $propertyValue */\n $propertyValue = array_get($request, $requestPropertyName);\n $propertyName = $prefix === null\n ? $requestPropertyName\n : mb_substr($requestPropertyName, mb_strlen($prefix));\n\n $isArrayType = array_has($arrayTypeProperties, $propertyName);\n\n if (! $isArrayType) {\n /** @var string $requestPropertyValue */\n\n $search->filters()->updateOrCreate(\n [\n 'filter' => $propertyName,\n ],\n [\n 'value' => $propertyValue,\n ]\n );\n\n continue;\n }\n\n /** @var string[] $requestPropertyValue */\n\n /** @var SearchFilter[]|Collection $existingFilterValues */\n $existingFilterValuesKeyed = $search->filters()\n ->where('filter', $propertyName)\n ->get()\n ->keyBy('id');\n\n // Iterate over values provided as request parameters\n foreach ($propertyValue as $value) {\n /** @var SearchFilter|null $valueFilter */\n $valueFilter = $search->filters()\n ->where(\n [\n 'filter' => $propertyName,\n 'value' => $value,\n ]\n )\n ->first();\n\n if ($valueFilter !== null) {\n // Remove filter value pair from list to be deleted\n $existingFilterValuesKeyed->forget($valueFilter->id);\n } else {\n // Add new filter/value pair\n $search->filters()->updateOrCreate([\n 'filter' => $propertyName,\n 'value' => $value,\n ]);\n }\n }\n\n // Delete filter value pairs for this filter that no longer exist in request parameters\n foreach ($existingFilterValuesKeyed as $existingFilter) {\n $existingFilter->delete();\n }\n }\n\n /** @var Collection<int, SearchFilter> $filtersKeyed */\n $filtersKeyed = $search->filters()->get()->keyBy('filter');\n\n // wipe removed filters from this search\n foreach ($filtersKeyed as $filterName => $filter) {\n if (array_has($request, $prefix . $filterName)) {\n continue;\n }\n\n // Remove all filter values for this filter\n $search->filters()->where('filter', $filterName)->delete();\n }\n\n return $this;\n }\n\n /**\n * @throws AuthorizationException\n */\n public function fetchActivitySearch(\n Search $search,\n Request $request,\n SearchTransformer $searchTransformer,\n ): JsonResponse {\n $this->authorize('view', $search);\n\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection(\n $user->searches()->get(),\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n /**\n * Deletes a saved search\n *\n * @param Request $request\n * @param Search $search\n *\n * @throws Exception\n *\n * @return JsonResponse\n */\n public function deleteActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('delete', $search);\n\n // Orphan any AutomatedReports that use this search\n $search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);\n\n // Delete filters and the search itself\n $search->filters()->delete();\n $search->delete();\n\n return $this->response->withOk();\n }\n\n public function live(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n $user = $this->getUserFromRequest($request);\n\n $this->request->validate([\n 'sort_direction' => 'in:asc,desc',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ]);\n\n $activities = $repository->getLiveCoachingEligibleActivities(\n user: $user,\n lookBackMinutes: self::LOOK_BACK,\n limit: (int) $this->request->input('limit', 25),\n page: (int) $this->request->input('page', 1),\n sortBy: ['actual_start_time', 'scheduled_start_time'],\n sortDirection: (string) $this->request->input('sort_direction', 'asc'),\n );\n\n $this->response\n ->getManager()\n ->parseIncludes(['organizer.group', 'prospect'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($activities, new ActivityTransformer());\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function show(Activity $activity, ActivityService $activityService): JsonResponse\n {\n $this->authorize('show', $activity);\n\n $user = $activity->getUser();\n $team = $user->getTeam();\n\n // Sync the opportunity with the latest data if possible.\n if ($activity->opportunity_id) {\n try {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n if (! $user->isCrmRequired()) {\n $crmService->setUser($team->getOwner());\n } else {\n $crmService->setUser($user);\n }\n\n $crmService->syncOpportunity($activity->opportunity->crm_provider_id);\n } catch (Exception $exception) {\n // Move on.\n }\n }\n\n $activityData = $activityService->getActivityData($this->request->user(), $activity);\n\n return response()->json($activityData);\n }\n\n public function createRecording(Activity $activity)\n {\n $this->authorize('record', $activity);\n\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Tell Twilio to start recording this activity.\n if ($activity->recording_state === Activity::RECORDING_OFF) {\n $job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withCreated();\n }\n\n return $this->response->errorGone('Activity is already recording.');\n }\n\n public function updateRecording(Request $request, Activity $activity)\n {\n $this->authorize('record', $activity);\n\n $request->validate([\n 'preference' => 'boolean',\n 'state' => [\n 'string',\n Rule::in([\n Activity::RECORDING_IN_PROGRESS,\n Activity::RECORDING_PAUSED,\n ]),\n ],\n ]);\n\n if ($request->has('state')) {\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Toggle the recording state between paused and resumed.\n if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {\n $job = (new ToggleRecording($activity, $request->input('state')))\n ->onQueue(Constants::QUEUE_CONFERENCES);\n\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Recording is not toggleable.');\n }\n\n if ($request->has('preference')) {\n $activity->update([\n 'recording_preference' => $request->input('preference') ? 1 : 0,\n ]);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorWrongArgs('Something went wrong');\n }\n\n public function stopRecording(Activity $activity)\n {\n $this->authorize('stopRecord', $activity);\n\n // Tell Twilio to stop recording this activity.\n if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {\n $job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Activity is not recording.');\n }\n\n /**\n * Add activity to this user's favorites playlist\n *\n * @throws AuthorizationException\n */\n public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse\n {\n $this->authorize('favorite', $activity);\n\n $user = $this->getUserFromRequest($this->request);\n $favorite = $activity->wasFavoritedBy($user);\n $name = $activity->activity_title ?? '';\n\n // It needs to check at least one record.\n if (! $favorite) {\n $favoritePlaylist = $user->favoritePlaylist();\n\n $playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(\n $activity,\n $user,\n $favoritePlaylist\n );\n\n if ($playlistActivity !== null) {\n $playlistActivity->update(\n // Just update, don't sort.\n ['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],\n );\n } else {\n $playlistActivity = $activity->playlistActivities()->create([\n 'playlist_id' => $favoritePlaylist->getId(),\n 'user_id' => $user->getId(),\n 'start_time' => 0,\n 'name' => mb_strimwidth($name, 0, 100),\n ]);\n // Sort it on top.\n $playlistActivity->update(\n [\n 'sort' => $playlistActivityRepository->calculateNewSortOrder(\n null,\n $playlistActivity,\n ),\n ],\n );\n }\n\n $playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);\n\n return new JsonResponse([], JsonResponse::HTTP_CREATED);\n }\n\n return new JsonResponse(\n [\n 'error' => [\n 'code' => AbstractResponse::CODE_CONFLICT,\n 'http_code' => JsonResponse::HTTP_CONFLICT,\n 'message' => 'Resource Already Exists',\n ],\n ],\n JsonResponse::HTTP_CONFLICT,\n );\n }\n\n /**\n * Remove activity from this user's favorites playlist\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unfavorite(Activity $activity)\n {\n $user = $this->request->user();\n\n $favorites = $activity->favoritedBy($user);\n\n if ($favorites && $favorites->isEmpty()) {\n return $this->response->errorNotFound('Favorite not found.');\n }\n\n $this->authorize('unfavorite', [$activity, $favorites]);\n\n // When you unfavorite an activity,\n // it should remove all the activities in it, including snippets.\n $isDeleted = $favorites->each(function ($favorite) {\n $favorite->forceDelete();\n });\n\n if ($isDeleted) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not remove favorite.');\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function notify(Activity $activity)\n {\n $this->authorize('notify', $activity);\n\n $user = $this->request->user();\n\n $existingNotification = $activity->availabilityNotifications()\n ->where('user_id', $user->id)\n ->exists();\n\n if ($existingNotification) {\n return $this->response->errorWrongArgs('Notification is already configured.');\n }\n\n $notification = Activity\\AvailabilityNotification::create([\n 'user_id' => $user->id,\n 'activity_id' => $activity->id,\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($notification, new AvailabilityNotificationTransformer());\n }\n\n /**\n * @param Activity $activity\n * @param Activity\\AvailabilityNotification $notification\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unnotify(Activity $activity, Activity\\AvailabilityNotification $notification)\n {\n $this->authorize('unnotify', [$activity, $notification]);\n\n if ($notification->sent_at || $notification->delete()) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not delete notification.');\n }\n\n public function play(Request $request, Activity $activity)\n {\n $this->authorize('stream', $activity);\n\n $request->validate([\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $activity->plays()->create([\n 'user_id' => $user->getId(),\n 'start_time' => $request->input('start_time'),\n ]);\n\n return $this->response->withCreated();\n }\n\n /**\n * @param Activity $activity\n *\n * @return mixed\n */\n public function comment(Activity $activity)\n {\n return $this->newComment($activity);\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @return mixed\n */\n public function replyComment(Activity $activity, Comment $comment)\n {\n return $this->newComment($activity, $comment);\n }\n\n /**\n * @param Activity $activity\n * @param Comment|null $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n protected function newComment(Activity $activity, ?Comment $comment = null)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n 'type' => 'integer|between:0,3',\n 'visibility' => sprintf('nullable|integer|between:1,%d', count(Comment::getVisibilityLevels())),\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n $threadStartId = null;\n if ($comment) {\n $threadStartId = $comment->thread_start_id ?: $comment->id;\n }\n\n try {\n $newComment = Comment::create([\n 'parent_comment_id' => $comment->id ?? null,\n 'thread_start_id' => $threadStartId,\n 'activity_id' => $activity->id,\n 'user_id' => $this->request->user()->id,\n 'comment' => trim($this->request->input('comment')),\n 'start_time' => $this->request->input('start_time', 0),\n 'end_time' => $this->request->input('end_time', 0),\n 'type' => $this->request->input('type', Comment::TYPE_NEUTRAL),\n 'visibility' => $this->request->input('visibility', Comment::VISIBILITY_PUBLIC),\n ]);\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($newComment, new ActivityCommentTransformer());\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not create comment.' . $exception->getMessage());\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function updateComment(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n try {\n $comment->update([\n 'comment' => trim($this->request->input('comment')),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment.');\n }\n }\n\n public function updateCommentVisibility(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'visibility' => sprintf('integer|between:1,%d', count(Comment::getVisibilityLevels())),\n ]);\n\n $visibility = $this->request->input('visibility');\n\n if ($comment->parent !== null) {\n return $this->response->errorWrongArgs('Comment visibility can only be updated on top level comments.');\n }\n\n try {\n $this->activityCommentService->updateCommentVisibility($comment, $visibility);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment\\'s visibility.');\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function deleteComment(Activity $activity, Comment $comment)\n {\n $this->authorize('deleteComment', [$activity, $comment]);\n\n // Delete comment and any children.\n $comment->delete();\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function fetchComments()\n {\n $user = $this->request->user();\n $this->request->validate([\n 'forUserId' => 'uuid:users,team_id,' . $user->team_id,\n 'types' => 'array',\n 'types.*' => 'integer|between:0,3',\n ]);\n $forUser = null;\n\n $types = [Comment::TYPE_NEUTRAL, Comment::TYPE_GAME_CHANGER, Comment::TYPE_POSITIVE];\n $user = $this->request->user();\n if ($this->request->has('forUserId')) {\n $forUser = $user->team->users()->uuid($this->request->input('forUserId'));\n }\n\n $comments = Comment::query()\n ->whereHas('activity', static function (Builder $builder) use ($user, $forUser): void {\n $builder\n // I left feedback on my own activity; or\n ->where('activities.user_id', $user->getId());\n if ($forUser) {\n // I left feedback on any activity for this user.\n $builder->orWhere([\n 'user_id' => $user->getId(),\n 'activities.user_id' => $forUser->getId(),\n ]);\n }\n })\n ->whereIn('type', $this->request->input('types', $types))\n ->orderBy('created_at', 'desc')\n ->get();\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity', 'user'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($comments, new ActivityCommentTransformer());\n }\n\n public function deleteCoachingFeedback(Activity $activity, CoachingFeedback $coachingFeedback)\n {\n $this->authorize('deleteCoachingFeedback', [$activity, $coachingFeedback]);\n $activity = $coachingFeedback->getActivity();\n\n if ($coachingFeedback->delete()) {\n event(new UpdateSingleEntity(\n entityId: $activity->getId(),\n updateTarget: UpdateTargetEnum::ACTIVITY,\n purpose: 'delete-coaching-feedback',\n ));\n\n return $this->response->withOk();\n }\n\n return $this->response->withError('Delete operation failed. Contact support.', 500);\n }\n\n /**\n * Add new or update Coaching feedback\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws \\Illuminate\\Validation\\ValidationException\n *\n * @return mixed\n */\n public function putCoachingFeedback(Request $request, Activity $activity)\n {\n $user = $request->user();\n\n if (! $user instanceof User) {\n abort(403);\n }\n $teamId = $user->getTeamId();\n\n $this->authorize('coach', $activity);\n\n $this->request->validate([\n 'coach_id' => 'required|uuid:users,team_id,' . $teamId,\n 'coachee_id' => 'required|uuid:users,team_id,' . $teamId,\n 'visibility' => ['required', Rule::in(CoachingFeedback::VISIBILITIES)],\n 'coaching_sections.*.uuid' => 'required|uuid:coaching_sections',\n 'coaching_sections.*.score' => ['required', Rule::in(CoachingSectionFeedback::SCORES)],\n 'coaching_sections.*.summary' => 'string|max:10000',\n 'coaching_sections.*.criteria.*.uuid' => 'required|uuid:coaching_section_criteria',\n 'coaching_sections.*.criteria.*.note' => 'required|string|max:10000',\n 'sharedWithUsers' => [\n 'required_if:visibility,' . CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS,\n 'array',\n ],\n 'sharedWithUsers.*' => [\n 'uuid:users,team_id,' . $teamId,\n ],\n ]);\n\n /** @var User $coach */\n $coach = User::uuid($this->request->input('coach_id'));\n /** @var User $coachee */\n $coachee = User::uuid($this->request->input('coachee_id'));\n $coachingSectionFeedbacks = $this->request->input('coaching_sections');\n\n $previousRecord = $this->coachingFeedbackRepository->getOneForActivityByCoacheeAndCoach(\n $coachee->getId(),\n $coach->getId(),\n $activity->getId()\n );\n $recordIsNew = false;\n if ($previousRecord === null) {\n $recordIsNew = true;\n }\n\n if (! $coachee->isSameTeamId($coach)) {\n return $this->response->errorForbidden('User not member of your team.');\n }\n\n if (! is_array($coachingSectionFeedbacks) || count($coachingSectionFeedbacks) < 1) {\n return $this->response->withError('At least one Coaching Framework Section shall be scored.', 422);\n }\n\n if (! $activity->participants()->where('participants.user_id', $coachee->id)->exists()) {\n return $this->response->withError('Coached user did not participate activity.', 422);\n }\n\n $visibility = $this->request->input('visibility');\n\n $shouldSendNotification = $recordIsNew;\n if ($recordIsNew === false && $visibility !== $previousRecord->getVisibility()) {\n $shouldSendNotification = true;\n }\n\n /**\n * Create CoachingFeedback\n *\n * @var CoachingFeedback $coachingFeedback\n */\n $coachingFeedback = $activity->coachingFeedbacks()->updateOrCreate(\n [\n 'coach_id' => $coach->id,\n 'coachee_id' => $coachee->id,\n ],\n [\n 'framework_id' => $activity->category->id,\n 'visibility' => $visibility,\n ]\n );\n\n $sharedUserIds = [];\n if ($visibility === CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS) {\n foreach ($this->request->input('sharedWithUsers') as $sharedWithUserUuid) {\n /** @var User $user */\n $user = User::uuid($sharedWithUserUuid);\n $sharedUserIds[] = $user->getId();\n }\n }\n\n $syncResult = $coachingFeedback->customAccessUsers()->sync($sharedUserIds);\n\n $scores = [];\n\n\n /**\n * Create CoachingSectionsFeedbacks.\n *\n * @var CoachingSectionFeedback $coachingSectionFeedback\n */\n foreach ($coachingSectionFeedbacks as $coachingSectionFeedbackInput) {\n $coachingSection = CoachingSection::uuid($coachingSectionFeedbackInput['uuid']);\n $coachingSectionFeedback = $coachingFeedback->sectionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_id' => $coachingSection->id,\n ],\n [\n 'score' => array_get($coachingSectionFeedbackInput, 'score'),\n 'summary' => array_get($coachingSectionFeedbackInput, 'summary') ?? '',\n ]\n );\n\n $scores[] = array_get($coachingSectionFeedbackInput, 'score');\n\n $criteria = array_get($coachingSectionFeedbackInput, 'criteria');\n if (is_array($criteria) && ! empty($criteria)) {\n foreach ($criteria as $criteriaFeedbackInput) {\n $coachingSectionFeedback->criterionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_criterion_id' => CoachingSectionCriterion::uuid(array_get($criteriaFeedbackInput, 'uuid'))\n ->id,\n ],\n ['note' => array_get($criteriaFeedbackInput, 'note')],\n );\n }\n }\n }\n\n $coachingFeedback->average_score = array_sum($scores) / count($scores);\n\n if ($recordIsNew === false && $coachingFeedback->getAverageScore() !== $previousRecord->getAverageScore()) {\n $shouldSendNotification = true;\n }\n if (! empty($syncResult['attached']) || ! empty($syncResult['detached']) || ! empty($syncResult['updated'])) {\n $shouldSendNotification = true;\n }\n\n $coachingFeedback->save();\n // ensure updated at for coaching feedback on section feedback summary added.\n $coachingFeedback->touch();\n\n if ($shouldSendNotification) {\n event(new Coached($coachingFeedback));\n }\n\n Datadog::increment('jiminny.activity.score.update', 1, ['company' => $activity->user->team->slug]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n $coachingFeedbackTransformer = new CoachingFeedbackTransformer();\n $coachingFeedbackTransformer->setConsumer($this->getUserFromRequest($request));\n\n return $this->response->withItem($coachingFeedback, $coachingFeedbackTransformer);\n }\n\n\n /**\n * Retrieve category criteria for coaching.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachingSections(Activity $activity)\n {\n $this->authorize('coach', $activity);\n\n if ($activity->category === null) {\n return $this->response->errorUnprocessable('Category has not yet been assigned.');\n }\n\n $criteria = $activity\n ->category\n ->coachingSections()\n ->where('is_enabled', 1)\n ->orderBy('sequence', 'asc');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($criteria->get(), new CoachingSectionsTransformer());\n }\n\n /**\n * @throws AuthorizationException\n * @throws ValidationException\n *\n * @return mixed\n */\n public function addToPlaylist(Activity $activity, PlaylistTrackFactoryInterface $playlistTrackFactory)\n {\n $this->request->validate([\n 'playlists' => 'required|array',\n 'playlists.*' => 'uuid:playlists',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'name' => 'required|max:100',\n ]);\n\n $this->authorize('addToPlaylist', [$activity, $this->request->input('playlists')]);\n\n $startTime = $this->request->input('start_time');\n $endTime = $this->request->input('end_time');\n $name = $this->request->input('name');\n /** @var User $user */\n $user = $this->request->user();\n\n // Get playlist by uuid.\n foreach ($this->request->input('playlists') as $playlistId) {\n // Pull out the playlist model.\n $playlist = Playlist::uuid($playlistId);\n\n $playlistTrackFactory->createTrack($playlist, $user, [\n 'name' => $name,\n 'activity' => $activity,\n 'start_time' => $startTime,\n 'end_time' => $endTime,\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function share(Request $request, Activity $activity): JsonResponse\n {\n $this->authorize('share', $activity);\n\n $request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'recipients.*.type' => 'in:user,group',\n 'recipients.*.id' => 'string|max:40',\n 'share' => 'string|max:255',\n ]);\n\n $user = $request->user();\n\n $recipients = $request->get('recipients');\n $users = $this->userService->convertRecipientsToUsers($user, $recipients);\n\n $shareData = [\n 'from_user_id' => $user->id,\n 'note' => $request->input('note'),\n 'start_time' => $request->input('start_time'),\n 'end_time' => $request->input('end_time'),\n ];\n\n // Create a share object against a notification provider channel\n if ($request->input('share')) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'notification_provider_channel' => $request->input('share'),\n ]\n )\n );\n\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n\n // Create a share object against each recipient\n foreach ($users as $recipient) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'to_user_id' => $recipient->id,\n ]\n )\n );\n\n // If parent_share_id has been selected yet\n if (! isset($shareData['parent_share_id'])) {\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachRequest(Activity $activity)\n {\n $this->authorize('coachRequest', $activity);\n\n $this->request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'coachers.*.type' => 'required|in:user',\n 'coachers.*.id' => 'required',\n ]);\n\n $coachers = $this->request->get('coachers');\n $user = $this->request->user();\n $users = $this->userService->convertRecipientsToUsers($user, $coachers);\n\n foreach ($users as $coacher) {\n CoachRequest::create([\n 'user_id' => $coacher->id,\n 'activity_id' => $activity->id,\n 'note' => $this->request->get('note'),\n 'start_time' => $this->request->get('start_time'),\n 'end_time' => $this->request->get('end_time'),\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function createActivityTopicTriggers(Activity $activity, LoggerInterface $logger): HttpFoundation\\JsonResponse\n {\n $this->authorize('analyzeTopicTriggers', $activity);\n\n if (! $activity->hasTranscription()) {\n return new HttpFoundation\\JsonResponse(\n [\n 'error' => 'Transcription not found.',\n ],\n JsonResponse::HTTP_NOT_FOUND\n );\n }\n\n $logger->info(__METHOD__ . ': queued for analysis', [\n 'activity' => $activity->id_string,\n ]);\n\n dispatch(new ActivityAnalytics\\Job\\AnalyzeActivityTopicTriggers($activity));\n\n return new HttpFoundation\\JsonResponse(null, JsonResponse::HTTP_CREATED);\n }\n\n public function fetchActivityTopicTriggers(\n Activity $activity,\n LoggerInterface $logger,\n ActivityTopicTriggerTransformer $transformer\n ): HttpFoundation\\JsonResponse {\n $this->authorize('fetchTopicTriggers', $activity);\n\n $logger->debug(__METHOD__, [\n 'activity' => $activity->id_string,\n ]);\n\n if (! $activity->isProcessed()) {\n return new HttpFoundation\\JsonResponse([]);\n }\n\n $payload = [];\n\n if ($activity->hasTopicTriggers()) {\n $payload = $activity->getTopicTriggersSorted()\n ->map(\n static fn (Activity\\TopicTrigger $activityTopicTrigger): array\n => $transformer->transform($activityTopicTrigger)\n )\n ->values()\n ->all();\n }\n\n return new HttpFoundation\\JsonResponse($payload);\n }\n\n /**\n * @param Activity $activity\n * @param StatsTransformer $statsTransformer\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function stats(Activity $activity, StatsTransformer $statsTransformer)\n {\n $this->authorize('stream', $activity);\n\n if (! $activity->hasTranscription()) {\n return $this->response->errorNotFound('Waveform data is not yet generated.');\n }\n\n $this->response\n ->getManager()\n ->parseIncludes(['wavedata'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($activity, $statsTransformer);\n }\n\n public function destroy(Activity $activity)\n {\n $this->authorize('delete', $activity);\n\n $activity->delete();\n\n \\Log::info('Soft delete activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n\n return $this->response->withNoContent();\n }\n\n public function note(Activity $activity)\n {\n $this->authorize('note', $activity);\n\n $this->request->validate([\n 'note' => 'required|min:1|max:2000',\n 'time' => 'required|numeric|min:0|max:86400',\n ]);\n\n $note = $this->request->input('note');\n $time = $this->request->input('time');\n\n $this->activityService->setActivity($activity);\n $this->activityService->takeNote($this->getUser(), $note, $time);\n\n return $this->response->withCreated();\n }\n\n /**\n * Mark an activity as private.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPrivate(Activity $activity)\n {\n $this->authorize('markAsPrivate', $activity);\n\n if ($activity->is_private === false) {\n $activity->is_private = true;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * Mark an activity as public.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPublic(Activity $activity)\n {\n $this->authorize('markAsPublic', $activity);\n\n if ($activity->is_private) {\n $activity->is_private = false;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws LogicException\n */\n public function fetchCloudFrontS3MediaKeys(Activity $activity, PlaybackService $playbackService): JsonResponse\n {\n $masterTrack = $activity->masterTrack()->first();\n\n if (! $masterTrack instanceof Track) {\n throw new LogicException(sprintf('Master track not found for activity \"%s\"', $activity->getUuid()));\n }\n\n return $this->response->withArray(\n $playbackService->generateCookies(\n $masterTrack,\n $this->request->ip(),\n ),\n );\n }\n\n /**\n * @throws ValidationException\n */\n private function updateOrCreateActivitySearch(Request $request, ?Search $search = null): Search\n {\n $request->validate([\n 'name' => 'required|string|min:2|max:100',\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $searchName = $request->input('name');\n\n if ($search !== null) {\n $search->update([\n 'name' => $searchName,\n ]);\n\n return $search;\n }\n\n $request->validate([\n 'filters' => ['required', 'array', new MultidimensionalArrayMaxCharRule(limit: 255)],\n 'nudges' => 'array|max:' . count(Nudge::MAP_CHANNEL),\n 'nudges.*.channel' => 'required|in:' . implode(',', Nudge::MAP_CHANNEL),\n 'nudges.*.frequency' => 'required|in:' . implode(',', Nudge::MAP_FREQUENCY),\n 'nudges.*.expiresAt' => [\n 'required',\n 'date',\n 'after:today',\n 'before_or_equal:' . now()->addYear()->format('Y-m-d'),\n ],\n ]);\n\n $searchCriteria = Criteria::createFromRequest(\n Collection::make($request->input('filters', []))->all(),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($searchCriteria, $user);\n $this->validateSearch($request, $filterSet, 'filters.');\n\n /** @var Search $search */\n $search = Search::create([\n 'name' => $searchName,\n 'uuid' => Uuid::uuid4()->toString(),\n 'user_id' => $user->getId(),\n ]);\n\n Collection::make($request->input('nudges', []))\n ->each(fn (array $attributes): Nudge => $this->nudgeFactory->createNudge($search, $attributes));\n\n $this->storeNamedSearchFilters(Collection::make($request->all()), $search, $filterSet, 'filters.');\n\n return $search;\n }\n\n private function resolveAccount(\n Team $team,\n Contact $contact,\n ServiceInterface $crmService,\n array $prospects,\n ): ?Account {\n $this->logger->info('Resolving account from contact');\n $account = $contact->getAccount();\n\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS)) {\n $this->logger->info('Team does not have feature to link activity to multiple prospects');\n\n return $account;\n }\n\n $this->logger->info('Resolving account from prospect data');\n $accountData = array_filter(\n $prospects,\n static fn (array $prospectData): bool => $prospectData['type'] === 'account'\n );\n\n if (! empty($accountData)) {\n $this->logger->info('Found account data in prospects');\n $accountData = reset($accountData);\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountData['id'])->first();\n\n if (! $account instanceof Account) {\n $this->logger->info('Account not found in database, syncing from CRM');\n $account = $crmService->syncAccount($accountData['id']);\n }\n }\n\n $this->logger->info('Resolved account', ['account' => $account->getId()]);\n\n return $account;\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Http\\Controllers\\API;\n\nuse Carbon\\Carbon;\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Exception;\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Validation\\Rule;\nuse Illuminate\\Validation\\Rules\\In;\nuse Illuminate\\Validation\\ValidationException;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ActivityAnalytics;\nuse Jiminny\\Component\\ActivitySearch;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Contracts\\ES\\Events\\UpdateSingleEntity;\nuse Jiminny\\Contracts\\ES\\UpdateTargetEnum;\nuse Jiminny\\Contracts\\Nudge\\NudgeFactoryInterface;\nuse Jiminny\\Contracts\\Playlist\\PlaylistTrackFactoryInterface;\nuse Jiminny\\Contracts\\Repositories\\PlaylistActivityRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Enums\\TeamSetting;\nuse Jiminny\\Events\\Activities\\AiAutomation\\ActivityProspectAdded;\nuse Jiminny\\Events\\Activities\\Coaching\\Coached;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Controllers\\CommentContextInterface;\nuse Jiminny\\Http\\Responses\\Api\\AbstractResponse;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\ActivityCommentTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTopicTriggerTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTransformer;\nuse Jiminny\\Http\\Transformers\\AvailabilityNotificationTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingFeedbackTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingSectionsTransformer;\nuse Jiminny\\Http\\Transformers\\SearchTransformer;\nuse Jiminny\\Http\\Transformers\\StatsTransformer;\nuse Jiminny\\Jobs\\Crm\\SaveActivity;\nuse Jiminny\\Jobs\\Crm\\UpdateStage;\nuse Jiminny\\Jobs\\Telephony\\StartRecording;\nuse Jiminny\\Jobs\\Telephony\\StopRecording;\nuse Jiminny\\Jobs\\Telephony\\ToggleRecording;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\CoachingFeedback;\nuse Jiminny\\Models\\CoachingSection;\nuse Jiminny\\Models\\CoachingSectionCriterion;\nuse Jiminny\\Models\\CoachingSectionFeedback;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\LanguageDialect;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Nudge;\nuse Jiminny\\Models\\PlaybookCategory;\nuse Jiminny\\Models\\Playlist;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\Track;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\CoachingFeedbackRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Rules\\MultidimensionalArrayMaxCharRule;\nuse Jiminny\\Services\\ActivityService;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Services\\PlaybackService;\nuse Jiminny\\Services\\UserService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\nuse Ramsey\\Uuid\\Uuid;\nuse Sentry;\nuse Symfony\\Component\\HttpFoundation;\n\nfinal class ActivityController extends Controller implements CommentContextInterface\n{\n // Number of minutes to look back on activities. i.e. a timeout on activity duration.\n private const int LOOK_BACK = 180;\n\n public function __construct(\n private ProviderRegistry $providerRegistry,\n private ActivityService $activityService,\n Response $response,\n private UserService $userService,\n private ActivitySearch\\Service\\ActivitySearch $activitySearch,\n private NudgeFactoryInterface $nudgeFactory,\n private ActivityCommentService $activityCommentService,\n private LoggerInterface $logger,\n private readonly CoachingFeedbackRepository $coachingFeedbackRepository,\n private readonly TeamRepository $teamRepository,\n ) {\n parent::__construct($response);\n }\n\n public static function getCommentImplementation(): string\n {\n return Comment::class;\n }\n\n public function delete()\n {\n $this->request->validate([\n '*' => 'uuid:activities',\n ]);\n\n $deletedIds = [];\n foreach ($this->request->all() as $activityId) {\n $activity = Activity::idOrUuId($activityId);\n\n try {\n if ($this->authorize('delete', $activity)) {\n $activity->delete();\n $deletedIds[] = $activityId;\n\n \\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n }\n } catch (AuthorizationException $authorizationException) {\n // They didn't have permission.\n }\n }\n\n return $this->response->withArray($deletedIds);\n }\n\n public function update(Request $request, Activity $activity)\n {\n $this->authorize('updateMetadata', $activity);\n\n $request->validate([\n 'title' => 'string|max:250',\n 'category_id' => 'uuid:playbook_categories',\n 'language' => [\n new In(\n LanguageDialect::query()\n ->with('language')\n ->cursor()\n ->map(static function (LanguageDialect $languageDialect): string {\n return $languageDialect->getLanguageLocale();\n })\n ->all()\n ),\n ],\n ]);\n\n if ($request->has('title')) {\n $activity->title = $request->input('title');\n }\n\n if ($request->has('category_id')) {\n $category = PlaybookCategory::uuid($request->input('category_id'));\n\n if ($category->playbook->team_id !== $request->user()->team_id) {\n return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n if ($request->has('language')) {\n if (! $activity->isInProgress()) {\n return $this->response->withError(\n 'Activity language can only be set while the meeting is in progress.',\n 400\n );\n }\n\n $activity->setLanguageCode($request->input('language'));\n }\n\n $activity->save();\n\n return $this->response->withOk();\n }\n\n // XXX: This should be merged with the update method.\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws SocialAccountTokenInvalidException\n *\n * @return mixed\n */\n public function summarize(Activity $activity): mixed\n {\n $this->logger->info('[Log Activity] Summarizing activity ', [\n 'activityId' => $activity->getUuid(),\n 'payload' => $this->request->all(),\n ]);\n $this->authorize('update', $activity);\n\n $this->logger->info('[Log Activity] Validating summary');\n // Validate the payload.\n $this->validateSummary($activity);\n\n // All objects must belong to this team.\n /** @var User $user */\n $user = $this->request->user();\n $team = $user->getTeam();\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n try {\n $crmUser = $user;\n if ($user->isCrmRequired() === false) {\n $crmUser = $team->owner;\n }\n $crmService->setUser($crmUser);\n } catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());\n }\n\n $rawEntities = $this->request->input('entities');\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid(\n $this->request->input('layout_id')\n );\n\n // Delay execution of CRM jobs to avoid locking issues.\n $jobDelay = 0;\n\n // If we have arrived from a notification, mark it as read.\n $notificationId = $this->request->input('nId');\n if ($notificationId) {\n $notification = $user->unreadNotifications->where('id', $notificationId)->first();\n\n if ($notification) {\n $notification->markAsRead();\n }\n }\n\n $title = $this->request->input('title');\n $prospects = $this->request->input('prospects');\n $opportunityId = $this->request->input('opportunity_id');\n $stageId = $this->request->input('stage_id');\n $categoryId = $this->request->input('category_id');\n $summary = $this->request->input('summary');\n $crmProviderId = $this->request->input('crm_id');\n $isInternal = $this->request->input('is_internal') ?? false;\n\n $lead = null;\n $category = null;\n $account = null;\n $contact = null;\n $opportunity = null;\n $stage = null;\n $callStage = null;\n\n foreach ($prospects as $prospectData) {\n $objectId = $prospectData['id'];\n\n if ($objectId === null) {\n continue;\n }\n\n $objectType = $prospectData['type'];\n $this->logger->info('debug', ['prospect_data' => $prospectData]);\n\n try {\n if ($objectType === null) {\n $this->logger->info('no object type');\n if ($crmService instanceof SupportsObjectTypeParseInterface) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n }\n\n switch ($objectType) {\n case 'lead':\n $this->logger->info('Processing lead');\n /** @var Lead|null $lead */\n $lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();\n\n // Lead does not exist locally, import it.\n if ($lead === null) {\n $this->logger->info('Lead does not exist locally');\n /** @var Lead $lead */\n $lead = $crmService->syncLead($objectId);\n }\n\n $this->logger->info('Lead found', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n if ($stageId === null) {\n $this->logger->info('Stage ID is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $lead->stage;\n\n break;\n }\n\n $this->logger->info('Looking for stage');\n // Determine if they have changed the stage.\n /** @var Stage $stage */\n $stage = $team->crm->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_LEAD)\n ->firstOrFail();\n\n $this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);\n if ($lead->stage_id && $lead->stage_id !== $stage->id) {\n $this->logger->info('Stage has changed');\n // Storage current stage on activity.\n $callStage = $lead->stage;\n\n // The stage has changed, update in remote CRM.\n dispatch(new UpdateStage($activity, $lead, $callStage, $stage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing lead stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->getName(),\n $stage->getName()\n ),\n [\n 'user' => $user->getUuid(),\n 'lead' => $lead->getUuid(),\n ]\n );\n } else {\n $this->logger->info('Stage has not changed');\n // Stage remains as current.\n $callStage = $stage;\n }\n\n break;\n\n case 'account':\n $this->logger->info('Processing account');\n // If the object is not a lead, it should be an account.\n $account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();\n\n // Account does not exist locally, import it.\n if ($account === null) {\n $this->logger->info('Account does not exist locally');\n $account = $crmService->syncAccount($objectId);\n }\n\n $this->logger->info('Account found', ['accountId' => $account->id]);\n\n break;\n case 'contact':\n $this->logger->info('processing contact');\n $contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $this->logger->info('contact does not exist locally');\n $contact = $crmService->syncContact($objectId);\n }\n\n $this->logger->info('resolving account');\n $account = $this->resolveAccount($team, $contact, $crmService, $prospects);\n\n break;\n }\n\n // If they have specified an opportunity, retrieve this with stage.\n if ($opportunityId) {\n $this->logger->info('opportunity id is set');\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if ($opportunity === null) {\n $this->logger->info('opportunity does not exist locally');\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n if ($stageId === null) {\n $this->logger->info('stage id is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $opportunity->stage ?? null;\n } else {\n $this->logger->info('looking for stage');\n /** @var ?Stage $opportunityStage */\n $opportunityStage = $team->crm\n ->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n // There is a chance we still cannot import this opportunity.\n if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {\n $this->logger->info('opportunity stage has changed');\n // Storage current stage on activity.\n $callStage = $opportunity->stage;\n\n dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing opportunity stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->name,\n $opportunityStage->name\n ),\n [\n 'userId' => $user->id_string,\n 'opportunityId' => $opportunity->id_string,\n ]\n );\n } else {\n $this->logger->info('opportunity stage has not changed');\n // Stage remains as current.\n $callStage = $opportunityStage;\n }\n }\n }\n\n if ($crmProviderId) {\n // Cast $crmProviderId to string otherwise it won't use database index for some records\n $linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();\n\n // Check if this activity has already been assigned to a different activity.\n if ($linkedActivity && $linkedActivity->id !== $activity->id) {\n throw new InvalidArgumentException(\n 'Sorry, the linked task has already been logged under a different call. '\n . 'Please choose another linked task.'\n );\n }\n }\n } catch (InvalidArgumentException $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($exception->getMessage());\n } catch (Exception $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorInternalError(\n 'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'\n );\n }\n }\n\n if ($categoryId) {\n $category = PlaybookCategory::uuid($categoryId);\n\n if ($category->playbook->team_id !== $team->id) {\n throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n $this->logger->info('Prospect data', [\n 'lead_id' => $lead?->getId(),\n 'account_id' => $account?->getId(),\n 'contact_id' => $contact?->getId(),\n 'opportunity_id' => $opportunity?->getId(),\n 'stage_id' => $stage?->getId(),\n ]);\n\n if ($title) {\n $activity->title = $title;\n }\n\n if ($summary) {\n $activity->summary = $summary;\n }\n\n if ($crmProviderId) {\n $activity->crm_provider_id = $crmProviderId;\n }\n\n if ($callStage) {\n $this->logger->info('Setting stage id', ['stageId' => $callStage->id]);\n $activity->stage_id = $callStage->id;\n }\n\n if ($lead) {\n $this->logger->info('Setting lead id', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n // If we are changed from an account > lead, unset the account data.\n $this->logger->info('Unsetting account id, opportunity id, contact id, value');\n $activity->account_id = null;\n $activity->opportunity_id = null;\n $activity->contact_id = null;\n $activity->value = null;\n }\n\n if ($account) {\n $this->logger->info('Setting account id', ['accountId' => $account->id]);\n $activity->account_id = $account->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('unsetting lead id');\n $activity->lead_id = null;\n\n // Unset the contact if switching different accounts. Will be set up below if still applicable.\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {\n $this->logger->info('Unsetting contact id');\n $activity->contact_id = null;\n }\n }\n\n if ($opportunity) {\n $this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);\n $this->logger->info('unsetting lead id');\n $activity->opportunity_id = $opportunity->id;\n $activity->value = $opportunity->value;\n\n // If we are changed from an lead > account, unset the lead data.\n $activity->lead_id = null;\n }\n\n if ($contact) {\n $this->logger->info('setting contact id', ['contactId' => $contact->id]);\n $activity->contact_id = $contact->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('Unsetting lead id');\n $activity->lead_id = null;\n }\n\n $activity->is_internal = $isInternal;\n $activity->save();\n $activity->refresh();\n\n $this->logger->notice('Activity saved', [\n 'activity_id' => $activity->getId(),\n 'lead_id' => $activity->lead_id,\n 'account_id' => $activity->account_id,\n 'contact_id' => $activity->contact_id,\n 'opportunity_id' => $activity->opportunity_id,\n 'stage_id' => $activity->stage_id,\n 'crm_provider_id' => $activity->getCrmProviderId(),\n ]);\n\n // Store entities as field data on the activity.\n $updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);\n\n if ($activity->isLoggable()) {\n // Follow-up Task or Event data.\n $followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);\n\n $this->logger->info('CRM LOG manual log triggered', [\n 'activityId' => $activity->getUuid(),\n 'followupData' => $followupData,\n 'userId' => $user->getUuid(),\n ]);\n\n // Store data in the CRM.\n // ++add check for crm_required\n $job = new SaveActivity($activity, $followupData);\n\n if ($updatedData) {\n $job->delay(Carbon::now()->addMinutes($jobDelay));\n }\n\n dispatch($job);\n\n // Manually dispatch log for Opportunity or Prospect added\n if ($activity->hasOpportunity() || $activity->hasProspect()) {\n event(new ActivityProspectAdded(\n activity: $activity,\n eventSource: 'manually-log-crm-data'\n ));\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.\n *\n * @param ServiceInterface $service\n * @param Activity $activity\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array\n {\n $updatedData = [];\n $existingData = $activity->data()->get();\n\n // We need to delete any existing data to overwrite with latest values.\n $activity->data()->delete();\n\n $layoutEntities = $layout->entities()\n ->with('field', 'parent')\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->get();\n\n /** @var LayoutEntity $entity */\n foreach ($layoutEntities as $entity) {\n // If the user has provided a value for this entity\n if (array_key_exists($entity->id_string, $entities)) {\n $value = $entities[$entity->id_string];\n\n // Convert raw data into values that the CRM can consume.\n if ($value) {\n $value = $service->normalizeValue($entity->field->type, $value);\n }\n\n // Check the field is part of the activity-summary section.\n if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {\n // This is the internal database ID, not the external CRM ID.\n $objectId = null;\n\n switch ($entity->field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $objectId = $activity->account_id;\n\n break;\n\n case Field::OBJECT_CONTACT:\n $objectId = $activity->contact_id;\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n $objectId = $activity->opportunity_id;\n\n break;\n\n case Field::OBJECT_LEAD:\n $objectId = $activity->lead_id;\n\n break;\n\n case Field::OBJECT_TASK:\n case Field::OBJECT_EVENT:\n $objectId = $activity->id;\n\n break;\n }\n\n if ($objectId) {\n /** @var FieldData $data */\n $data = $activity->data()->create([\n 'crm_layout_entity_id' => $entity->id,\n 'crm_field_id' => $entity->crm_field_id,\n 'object_type' => $entity->field->object_type,\n 'object_id' => $objectId,\n 'value' => $value,\n ]);\n\n // Never send read-only field data to the CRM.\n if ($entity->read_only === false && $entity->is_visible) {\n $existingValue = $existingData\n ->where('crm_layout_entity_id', $entity->id)\n ->where('crm_field_id', $entity->crm_field_id)\n ->where('object_type', $entity->field->object_type)\n ->where('object_id', $objectId)\n ->first();\n\n // If the field was actually changed, we need to reflect this in the CRM too.\n if ($existingValue === null || $existingValue->value !== $value) {\n $updatedData[] = $data->id;\n }\n }\n }\n }\n }\n }\n\n return $updatedData;\n }\n\n /**\n * Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.\n *\n * @param ServiceInterface $crmService\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array\n {\n $fieldData = [];\n foreach ($entities as $entityId => $value) {\n // Only bother with fields that have a value.\n if ($value) {\n // Extract the entity from the UUID. Check the field is valid and part of the follow-up section.\n $entity = $layout->entities()\n ->uuid($entityId, false)\n ->whereHas('parent', function ($query) {\n $query->where('label', 'follow-up');\n })\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->first();\n\n if ($entity) {\n // Convert raw data into values that the CRM can consume.\n $value = $crmService->normalizeValue($entity->field->type, $value);\n\n // Add the field and value to the payload.\n $fieldData += [\n $entity->field->crm_provider_id => $value,\n ];\n }\n }\n }\n\n return $fieldData;\n }\n\n /**\n * @param Activity $activity\n */\n private function validateSummary(Activity $activity): void\n {\n $team = $activity->user->team;\n $crmProvider = $team->crm->provider;\n $attributes = [];\n\n $rules = [\n 'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,\n 'title' => 'string|max:250',\n 'prospects' => 'required|array',\n 'opportunity_id' => new CrmReference($crmProvider),\n 'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',\n 'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator\n 'summary' => 'max:50000',\n 'nId' => 'exists:notifications,id',\n 'crm_id' => new CrmReference($crmProvider),\n 'entities' => 'array',\n 'is_internal' => 'boolean',\n ];\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));\n\n // Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.\n $entities = $layout->entities()\n ->where('read_only', 0)\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->whereHas('parent', function ($query) use ($activity) {\n if ($activity->isLoggable() === false) {\n $query->where('label', '<>', 'follow-up');\n }\n });\n\n $isInternal = $this->request->input('is_internal', false);\n\n foreach ($entities->get() as $entity) {\n $rules += $this->buildFieldValidator($entity, $isInternal);\n $attributes += $this->buildFieldMessage($entity);\n }\n\n $this->request->validate($rules, [], $attributes);\n }\n\n private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array\n {\n return [\n 'entities.' . $entity->id_string => $entity->getValidator($isInternal),\n ];\n }\n\n /**\n * @param LayoutEntity $entity\n *\n * @return array\n */\n private function buildFieldMessage(LayoutEntity $entity): array\n {\n $label = $entity->label;\n if ($label === null) {\n $label = $entity->field->label;\n }\n\n return [\n 'entities.' . $entity->id_string => $label,\n ];\n }\n\n public function search(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->debugLog(\n $user,\n 'User extracted from request',\n ['user' => $user->getId(), 'tz' => $user->getTimezone()]\n );\n\n $searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());\n\n $this->debugLog(\n $user,\n 'ActivitySearch criteria built',\n ['searchCriteria' => $searchCriteria]\n );\n\n $filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);\n\n $this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);\n\n $this->validateSearch($request, $filterSet);\n\n $this->debugLog($user, 'Request validated');\n\n $searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);\n\n /** @var Collection<Activity> $activities */\n $activities = $searchResponse['results'];\n\n $this->debugLog($user, 'Activities ES response extracted');\n\n $hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(\n $user->getTeamId(),\n TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),\n );\n\n if ($hideInternalMeetingsSetting?->getValue() === '1') {\n $activities = $activities->filter(function (Activity $activity) {\n if ($activity->is_internal && empty($activity->actual_start_time)) {\n return false;\n }\n\n return true;\n });\n }\n\n $this->debugLog($user, 'Internal meetings (?!) filtered');\n\n $this->response->getManager()\n ->parseIncludes([\n 'category',\n 'organizer.group',\n 'prospect',\n 'stage',\n 'opportunity',\n 'stats',\n 'scorecards',\n 'masterTrack',\n 'activeParticipants',\n 'notification',\n ])\n ->setSerializer(new JsonSerializer());\n\n $transformerExcludes = $this->request->input('exclude');\n if ($transformerExcludes) {\n $this->response->getManager()->parseExcludes($transformerExcludes);\n }\n\n $this->debugLog($user, 'Response Manager (?!) applied');\n\n $transformer = new ActivityTransformer();\n $transformer->setConsumer($user);\n\n $this->debugLog($user, 'Activity Transformer added');\n\n $resource = new \\League\\Fractal\\Resource\\Collection($activities, $transformer);\n $page = $searchCriteria->getPageNumber();\n\n $this->debugLog($user, 'Search criteria page number called', ['page' => $page]);\n\n $histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');\n\n $this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);\n\n return $this->response->withArray([\n 'pagination' => [\n 'total' => $searchResponse['totalHits'],\n 'current' => $page,\n 'prev' => max($page - 1, 1),\n 'next' => $page + 1,\n ],\n 'results' => $this->response->getManager()->createData($resource)->toArray(),\n 'histogram' => $histogram,\n ]);\n }\n\n private function debugLog(User $user, string $logMessage, ?array $context = []): void\n {\n // Debug for Learning People Only\n if ($user->getTeamId() !== 260) {\n return;\n }\n\n Log::notice(\n sprintf('[activity-search-controller] %s', $logMessage),\n $context\n );\n }\n\n /** @throws ValidationException */\n private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void\n {\n $rules = [\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ];\n\n if ($prefix !== null && mb_strpos($prefix, '.') !== false) {\n $rules[rtrim($prefix, '.')] = sprintf(\n 'required|array|max:%d',\n $filterSet->count()\n );\n }\n\n $validationRules = $filterSet->getValidationRules($prefix)\n ->merge($rules)\n ->all();\n\n $request->validate($validationRules);\n }\n\n public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $search = $this->updateOrCreateActivitySearch($request);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function updateActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('update', $search);\n\n $this->updateOrCreateActivitySearch($request, $search);\n\n return $this->response->withOk();\n }\n\n private function storeNamedSearchFilters(\n Collection $request,\n Search $search,\n FilterDefinitionCollection $filterSet,\n ?string $prefix = null,\n ): self {\n $arrayTypeProperties = $filterSet\n ->getPropertyTypes([\n FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,\n ])\n ->all();\n\n $supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);\n\n foreach ($supportedRequestProperties as $requestPropertyName) {\n if (! array_has($request, $requestPropertyName)) {\n continue;\n }\n\n /** @var string|string[] $propertyValue */\n $propertyValue = array_get($request, $requestPropertyName);\n $propertyName = $prefix === null\n ? $requestPropertyName\n : mb_substr($requestPropertyName, mb_strlen($prefix));\n\n $isArrayType = array_has($arrayTypeProperties, $propertyName);\n\n if (! $isArrayType) {\n /** @var string $requestPropertyValue */\n\n $search->filters()->updateOrCreate(\n [\n 'filter' => $propertyName,\n ],\n [\n 'value' => $propertyValue,\n ]\n );\n\n continue;\n }\n\n /** @var string[] $requestPropertyValue */\n\n /** @var SearchFilter[]|Collection $existingFilterValues */\n $existingFilterValuesKeyed = $search->filters()\n ->where('filter', $propertyName)\n ->get()\n ->keyBy('id');\n\n // Iterate over values provided as request parameters\n foreach ($propertyValue as $value) {\n /** @var SearchFilter|null $valueFilter */\n $valueFilter = $search->filters()\n ->where(\n [\n 'filter' => $propertyName,\n 'value' => $value,\n ]\n )\n ->first();\n\n if ($valueFilter !== null) {\n // Remove filter value pair from list to be deleted\n $existingFilterValuesKeyed->forget($valueFilter->id);\n } else {\n // Add new filter/value pair\n $search->filters()->updateOrCreate([\n 'filter' => $propertyName,\n 'value' => $value,\n ]);\n }\n }\n\n // Delete filter value pairs for this filter that no longer exist in request parameters\n foreach ($existingFilterValuesKeyed as $existingFilter) {\n $existingFilter->delete();\n }\n }\n\n /** @var Collection<int, SearchFilter> $filtersKeyed */\n $filtersKeyed = $search->filters()->get()->keyBy('filter');\n\n // wipe removed filters from this search\n foreach ($filtersKeyed as $filterName => $filter) {\n if (array_has($request, $prefix . $filterName)) {\n continue;\n }\n\n // Remove all filter values for this filter\n $search->filters()->where('filter', $filterName)->delete();\n }\n\n return $this;\n }\n\n /**\n * @throws AuthorizationException\n */\n public function fetchActivitySearch(\n Search $search,\n Request $request,\n SearchTransformer $searchTransformer,\n ): JsonResponse {\n $this->authorize('view', $search);\n\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection(\n $user->searches()->get(),\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n /**\n * Deletes a saved search\n *\n * @param Request $request\n * @param Search $search\n *\n * @throws Exception\n *\n * @return JsonResponse\n */\n public function deleteActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('delete', $search);\n\n // Orphan any AutomatedReports that use this search\n $search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);\n\n // Delete filters and the search itself\n $search->filters()->delete();\n $search->delete();\n\n return $this->response->withOk();\n }\n\n public function live(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n $user = $this->getUserFromRequest($request);\n\n $this->request->validate([\n 'sort_direction' => 'in:asc,desc',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ]);\n\n $activities = $repository->getLiveCoachingEligibleActivities(\n user: $user,\n lookBackMinutes: self::LOOK_BACK,\n limit: (int) $this->request->input('limit', 25),\n page: (int) $this->request->input('page', 1),\n sortBy: ['actual_start_time', 'scheduled_start_time'],\n sortDirection: (string) $this->request->input('sort_direction', 'asc'),\n );\n\n $this->response\n ->getManager()\n ->parseIncludes(['organizer.group', 'prospect'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($activities, new ActivityTransformer());\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function show(Activity $activity, ActivityService $activityService): JsonResponse\n {\n $this->authorize('show', $activity);\n\n $user = $activity->getUser();\n $team = $user->getTeam();\n\n // Sync the opportunity with the latest data if possible.\n if ($activity->opportunity_id) {\n try {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n if (! $user->isCrmRequired()) {\n $crmService->setUser($team->getOwner());\n } else {\n $crmService->setUser($user);\n }\n\n $crmService->syncOpportunity($activity->opportunity->crm_provider_id);\n } catch (Exception $exception) {\n // Move on.\n }\n }\n\n $activityData = $activityService->getActivityData($this->request->user(), $activity);\n\n return response()->json($activityData);\n }\n\n public function createRecording(Activity $activity)\n {\n $this->authorize('record', $activity);\n\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Tell Twilio to start recording this activity.\n if ($activity->recording_state === Activity::RECORDING_OFF) {\n $job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withCreated();\n }\n\n return $this->response->errorGone('Activity is already recording.');\n }\n\n public function updateRecording(Request $request, Activity $activity)\n {\n $this->authorize('record', $activity);\n\n $request->validate([\n 'preference' => 'boolean',\n 'state' => [\n 'string',\n Rule::in([\n Activity::RECORDING_IN_PROGRESS,\n Activity::RECORDING_PAUSED,\n ]),\n ],\n ]);\n\n if ($request->has('state')) {\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Toggle the recording state between paused and resumed.\n if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {\n $job = (new ToggleRecording($activity, $request->input('state')))\n ->onQueue(Constants::QUEUE_CONFERENCES);\n\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Recording is not toggleable.');\n }\n\n if ($request->has('preference')) {\n $activity->update([\n 'recording_preference' => $request->input('preference') ? 1 : 0,\n ]);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorWrongArgs('Something went wrong');\n }\n\n public function stopRecording(Activity $activity)\n {\n $this->authorize('stopRecord', $activity);\n\n // Tell Twilio to stop recording this activity.\n if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {\n $job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Activity is not recording.');\n }\n\n /**\n * Add activity to this user's favorites playlist\n *\n * @throws AuthorizationException\n */\n public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse\n {\n $this->authorize('favorite', $activity);\n\n $user = $this->getUserFromRequest($this->request);\n $favorite = $activity->wasFavoritedBy($user);\n $name = $activity->activity_title ?? '';\n\n // It needs to check at least one record.\n if (! $favorite) {\n $favoritePlaylist = $user->favoritePlaylist();\n\n $playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(\n $activity,\n $user,\n $favoritePlaylist\n );\n\n if ($playlistActivity !== null) {\n $playlistActivity->update(\n // Just update, don't sort.\n ['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],\n );\n } else {\n $playlistActivity = $activity->playlistActivities()->create([\n 'playlist_id' => $favoritePlaylist->getId(),\n 'user_id' => $user->getId(),\n 'start_time' => 0,\n 'name' => mb_strimwidth($name, 0, 100),\n ]);\n // Sort it on top.\n $playlistActivity->update(\n [\n 'sort' => $playlistActivityRepository->calculateNewSortOrder(\n null,\n $playlistActivity,\n ),\n ],\n );\n }\n\n $playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);\n\n return new JsonResponse([], JsonResponse::HTTP_CREATED);\n }\n\n return new JsonResponse(\n [\n 'error' => [\n 'code' => AbstractResponse::CODE_CONFLICT,\n 'http_code' => JsonResponse::HTTP_CONFLICT,\n 'message' => 'Resource Already Exists',\n ],\n ],\n JsonResponse::HTTP_CONFLICT,\n );\n }\n\n /**\n * Remove activity from this user's favorites playlist\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unfavorite(Activity $activity)\n {\n $user = $this->request->user();\n\n $favorites = $activity->favoritedBy($user);\n\n if ($favorites && $favorites->isEmpty()) {\n return $this->response->errorNotFound('Favorite not found.');\n }\n\n $this->authorize('unfavorite', [$activity, $favorites]);\n\n // When you unfavorite an activity,\n // it should remove all the activities in it, including snippets.\n $isDeleted = $favorites->each(function ($favorite) {\n $favorite->forceDelete();\n });\n\n if ($isDeleted) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not remove favorite.');\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function notify(Activity $activity)\n {\n $this->authorize('notify', $activity);\n\n $user = $this->request->user();\n\n $existingNotification = $activity->availabilityNotifications()\n ->where('user_id', $user->id)\n ->exists();\n\n if ($existingNotification) {\n return $this->response->errorWrongArgs('Notification is already configured.');\n }\n\n $notification = Activity\\AvailabilityNotification::create([\n 'user_id' => $user->id,\n 'activity_id' => $activity->id,\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($notification, new AvailabilityNotificationTransformer());\n }\n\n /**\n * @param Activity $activity\n * @param Activity\\AvailabilityNotification $notification\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unnotify(Activity $activity, Activity\\AvailabilityNotification $notification)\n {\n $this->authorize('unnotify', [$activity, $notification]);\n\n if ($notification->sent_at || $notification->delete()) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not delete notification.');\n }\n\n public function play(Request $request, Activity $activity)\n {\n $this->authorize('stream', $activity);\n\n $request->validate([\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $activity->plays()->create([\n 'user_id' => $user->getId(),\n 'start_time' => $request->input('start_time'),\n ]);\n\n return $this->response->withCreated();\n }\n\n /**\n * @param Activity $activity\n *\n * @return mixed\n */\n public function comment(Activity $activity)\n {\n return $this->newComment($activity);\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @return mixed\n */\n public function replyComment(Activity $activity, Comment $comment)\n {\n return $this->newComment($activity, $comment);\n }\n\n /**\n * @param Activity $activity\n * @param Comment|null $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n protected function newComment(Activity $activity, ?Comment $comment = null)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n 'type' => 'integer|between:0,3',\n 'visibility' => sprintf('nullable|integer|between:1,%d', count(Comment::getVisibilityLevels())),\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n $threadStartId = null;\n if ($comment) {\n $threadStartId = $comment->thread_start_id ?: $comment->id;\n }\n\n try {\n $newComment = Comment::create([\n 'parent_comment_id' => $comment->id ?? null,\n 'thread_start_id' => $threadStartId,\n 'activity_id' => $activity->id,\n 'user_id' => $this->request->user()->id,\n 'comment' => trim($this->request->input('comment')),\n 'start_time' => $this->request->input('start_time', 0),\n 'end_time' => $this->request->input('end_time', 0),\n 'type' => $this->request->input('type', Comment::TYPE_NEUTRAL),\n 'visibility' => $this->request->input('visibility', Comment::VISIBILITY_PUBLIC),\n ]);\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($newComment, new ActivityCommentTransformer());\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not create comment.' . $exception->getMessage());\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function updateComment(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n try {\n $comment->update([\n 'comment' => trim($this->request->input('comment')),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment.');\n }\n }\n\n public function updateCommentVisibility(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'visibility' => sprintf('integer|between:1,%d', count(Comment::getVisibilityLevels())),\n ]);\n\n $visibility = $this->request->input('visibility');\n\n if ($comment->parent !== null) {\n return $this->response->errorWrongArgs('Comment visibility can only be updated on top level comments.');\n }\n\n try {\n $this->activityCommentService->updateCommentVisibility($comment, $visibility);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment\\'s visibility.');\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function deleteComment(Activity $activity, Comment $comment)\n {\n $this->authorize('deleteComment', [$activity, $comment]);\n\n // Delete comment and any children.\n $comment->delete();\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function fetchComments()\n {\n $user = $this->request->user();\n $this->request->validate([\n 'forUserId' => 'uuid:users,team_id,' . $user->team_id,\n 'types' => 'array',\n 'types.*' => 'integer|between:0,3',\n ]);\n $forUser = null;\n\n $types = [Comment::TYPE_NEUTRAL, Comment::TYPE_GAME_CHANGER, Comment::TYPE_POSITIVE];\n $user = $this->request->user();\n if ($this->request->has('forUserId')) {\n $forUser = $user->team->users()->uuid($this->request->input('forUserId'));\n }\n\n $comments = Comment::query()\n ->whereHas('activity', static function (Builder $builder) use ($user, $forUser): void {\n $builder\n // I left feedback on my own activity; or\n ->where('activities.user_id', $user->getId());\n if ($forUser) {\n // I left feedback on any activity for this user.\n $builder->orWhere([\n 'user_id' => $user->getId(),\n 'activities.user_id' => $forUser->getId(),\n ]);\n }\n })\n ->whereIn('type', $this->request->input('types', $types))\n ->orderBy('created_at', 'desc')\n ->get();\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity', 'user'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($comments, new ActivityCommentTransformer());\n }\n\n public function deleteCoachingFeedback(Activity $activity, CoachingFeedback $coachingFeedback)\n {\n $this->authorize('deleteCoachingFeedback', [$activity, $coachingFeedback]);\n $activity = $coachingFeedback->getActivity();\n\n if ($coachingFeedback->delete()) {\n event(new UpdateSingleEntity(\n entityId: $activity->getId(),\n updateTarget: UpdateTargetEnum::ACTIVITY,\n purpose: 'delete-coaching-feedback',\n ));\n\n return $this->response->withOk();\n }\n\n return $this->response->withError('Delete operation failed. Contact support.', 500);\n }\n\n /**\n * Add new or update Coaching feedback\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws \\Illuminate\\Validation\\ValidationException\n *\n * @return mixed\n */\n public function putCoachingFeedback(Request $request, Activity $activity)\n {\n $user = $request->user();\n\n if (! $user instanceof User) {\n abort(403);\n }\n $teamId = $user->getTeamId();\n\n $this->authorize('coach', $activity);\n\n $this->request->validate([\n 'coach_id' => 'required|uuid:users,team_id,' . $teamId,\n 'coachee_id' => 'required|uuid:users,team_id,' . $teamId,\n 'visibility' => ['required', Rule::in(CoachingFeedback::VISIBILITIES)],\n 'coaching_sections.*.uuid' => 'required|uuid:coaching_sections',\n 'coaching_sections.*.score' => ['required', Rule::in(CoachingSectionFeedback::SCORES)],\n 'coaching_sections.*.summary' => 'string|max:10000',\n 'coaching_sections.*.criteria.*.uuid' => 'required|uuid:coaching_section_criteria',\n 'coaching_sections.*.criteria.*.note' => 'required|string|max:10000',\n 'sharedWithUsers' => [\n 'required_if:visibility,' . CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS,\n 'array',\n ],\n 'sharedWithUsers.*' => [\n 'uuid:users,team_id,' . $teamId,\n ],\n ]);\n\n /** @var User $coach */\n $coach = User::uuid($this->request->input('coach_id'));\n /** @var User $coachee */\n $coachee = User::uuid($this->request->input('coachee_id'));\n $coachingSectionFeedbacks = $this->request->input('coaching_sections');\n\n $previousRecord = $this->coachingFeedbackRepository->getOneForActivityByCoacheeAndCoach(\n $coachee->getId(),\n $coach->getId(),\n $activity->getId()\n );\n $recordIsNew = false;\n if ($previousRecord === null) {\n $recordIsNew = true;\n }\n\n if (! $coachee->isSameTeamId($coach)) {\n return $this->response->errorForbidden('User not member of your team.');\n }\n\n if (! is_array($coachingSectionFeedbacks) || count($coachingSectionFeedbacks) < 1) {\n return $this->response->withError('At least one Coaching Framework Section shall be scored.', 422);\n }\n\n if (! $activity->participants()->where('participants.user_id', $coachee->id)->exists()) {\n return $this->response->withError('Coached user did not participate activity.', 422);\n }\n\n $visibility = $this->request->input('visibility');\n\n $shouldSendNotification = $recordIsNew;\n if ($recordIsNew === false && $visibility !== $previousRecord->getVisibility()) {\n $shouldSendNotification = true;\n }\n\n /**\n * Create CoachingFeedback\n *\n * @var CoachingFeedback $coachingFeedback\n */\n $coachingFeedback = $activity->coachingFeedbacks()->updateOrCreate(\n [\n 'coach_id' => $coach->id,\n 'coachee_id' => $coachee->id,\n ],\n [\n 'framework_id' => $activity->category->id,\n 'visibility' => $visibility,\n ]\n );\n\n $sharedUserIds = [];\n if ($visibility === CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS) {\n foreach ($this->request->input('sharedWithUsers') as $sharedWithUserUuid) {\n /** @var User $user */\n $user = User::uuid($sharedWithUserUuid);\n $sharedUserIds[] = $user->getId();\n }\n }\n\n $syncResult = $coachingFeedback->customAccessUsers()->sync($sharedUserIds);\n\n $scores = [];\n\n\n /**\n * Create CoachingSectionsFeedbacks.\n *\n * @var CoachingSectionFeedback $coachingSectionFeedback\n */\n foreach ($coachingSectionFeedbacks as $coachingSectionFeedbackInput) {\n $coachingSection = CoachingSection::uuid($coachingSectionFeedbackInput['uuid']);\n $coachingSectionFeedback = $coachingFeedback->sectionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_id' => $coachingSection->id,\n ],\n [\n 'score' => array_get($coachingSectionFeedbackInput, 'score'),\n 'summary' => array_get($coachingSectionFeedbackInput, 'summary') ?? '',\n ]\n );\n\n $scores[] = array_get($coachingSectionFeedbackInput, 'score');\n\n $criteria = array_get($coachingSectionFeedbackInput, 'criteria');\n if (is_array($criteria) && ! empty($criteria)) {\n foreach ($criteria as $criteriaFeedbackInput) {\n $coachingSectionFeedback->criterionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_criterion_id' => CoachingSectionCriterion::uuid(array_get($criteriaFeedbackInput, 'uuid'))\n ->id,\n ],\n ['note' => array_get($criteriaFeedbackInput, 'note')],\n );\n }\n }\n }\n\n $coachingFeedback->average_score = array_sum($scores) / count($scores);\n\n if ($recordIsNew === false && $coachingFeedback->getAverageScore() !== $previousRecord->getAverageScore()) {\n $shouldSendNotification = true;\n }\n if (! empty($syncResult['attached']) || ! empty($syncResult['detached']) || ! empty($syncResult['updated'])) {\n $shouldSendNotification = true;\n }\n\n $coachingFeedback->save();\n // ensure updated at for coaching feedback on section feedback summary added.\n $coachingFeedback->touch();\n\n if ($shouldSendNotification) {\n event(new Coached($coachingFeedback));\n }\n\n Datadog::increment('jiminny.activity.score.update', 1, ['company' => $activity->user->team->slug]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n $coachingFeedbackTransformer = new CoachingFeedbackTransformer();\n $coachingFeedbackTransformer->setConsumer($this->getUserFromRequest($request));\n\n return $this->response->withItem($coachingFeedback, $coachingFeedbackTransformer);\n }\n\n\n /**\n * Retrieve category criteria for coaching.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachingSections(Activity $activity)\n {\n $this->authorize('coach', $activity);\n\n if ($activity->category === null) {\n return $this->response->errorUnprocessable('Category has not yet been assigned.');\n }\n\n $criteria = $activity\n ->category\n ->coachingSections()\n ->where('is_enabled', 1)\n ->orderBy('sequence', 'asc');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($criteria->get(), new CoachingSectionsTransformer());\n }\n\n /**\n * @throws AuthorizationException\n * @throws ValidationException\n *\n * @return mixed\n */\n public function addToPlaylist(Activity $activity, PlaylistTrackFactoryInterface $playlistTrackFactory)\n {\n $this->request->validate([\n 'playlists' => 'required|array',\n 'playlists.*' => 'uuid:playlists',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'name' => 'required|max:100',\n ]);\n\n $this->authorize('addToPlaylist', [$activity, $this->request->input('playlists')]);\n\n $startTime = $this->request->input('start_time');\n $endTime = $this->request->input('end_time');\n $name = $this->request->input('name');\n /** @var User $user */\n $user = $this->request->user();\n\n // Get playlist by uuid.\n foreach ($this->request->input('playlists') as $playlistId) {\n // Pull out the playlist model.\n $playlist = Playlist::uuid($playlistId);\n\n $playlistTrackFactory->createTrack($playlist, $user, [\n 'name' => $name,\n 'activity' => $activity,\n 'start_time' => $startTime,\n 'end_time' => $endTime,\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function share(Request $request, Activity $activity): JsonResponse\n {\n $this->authorize('share', $activity);\n\n $request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'recipients.*.type' => 'in:user,group',\n 'recipients.*.id' => 'string|max:40',\n 'share' => 'string|max:255',\n ]);\n\n $user = $request->user();\n\n $recipients = $request->get('recipients');\n $users = $this->userService->convertRecipientsToUsers($user, $recipients);\n\n $shareData = [\n 'from_user_id' => $user->id,\n 'note' => $request->input('note'),\n 'start_time' => $request->input('start_time'),\n 'end_time' => $request->input('end_time'),\n ];\n\n // Create a share object against a notification provider channel\n if ($request->input('share')) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'notification_provider_channel' => $request->input('share'),\n ]\n )\n );\n\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n\n // Create a share object against each recipient\n foreach ($users as $recipient) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'to_user_id' => $recipient->id,\n ]\n )\n );\n\n // If parent_share_id has been selected yet\n if (! isset($shareData['parent_share_id'])) {\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachRequest(Activity $activity)\n {\n $this->authorize('coachRequest', $activity);\n\n $this->request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'coachers.*.type' => 'required|in:user',\n 'coachers.*.id' => 'required',\n ]);\n\n $coachers = $this->request->get('coachers');\n $user = $this->request->user();\n $users = $this->userService->convertRecipientsToUsers($user, $coachers);\n\n foreach ($users as $coacher) {\n CoachRequest::create([\n 'user_id' => $coacher->id,\n 'activity_id' => $activity->id,\n 'note' => $this->request->get('note'),\n 'start_time' => $this->request->get('start_time'),\n 'end_time' => $this->request->get('end_time'),\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function createActivityTopicTriggers(Activity $activity, LoggerInterface $logger): HttpFoundation\\JsonResponse\n {\n $this->authorize('analyzeTopicTriggers', $activity);\n\n if (! $activity->hasTranscription()) {\n return new HttpFoundation\\JsonResponse(\n [\n 'error' => 'Transcription not found.',\n ],\n JsonResponse::HTTP_NOT_FOUND\n );\n }\n\n $logger->info(__METHOD__ . ': queued for analysis', [\n 'activity' => $activity->id_string,\n ]);\n\n dispatch(new ActivityAnalytics\\Job\\AnalyzeActivityTopicTriggers($activity));\n\n return new HttpFoundation\\JsonResponse(null, JsonResponse::HTTP_CREATED);\n }\n\n public function fetchActivityTopicTriggers(\n Activity $activity,\n LoggerInterface $logger,\n ActivityTopicTriggerTransformer $transformer\n ): HttpFoundation\\JsonResponse {\n $this->authorize('fetchTopicTriggers', $activity);\n\n $logger->debug(__METHOD__, [\n 'activity' => $activity->id_string,\n ]);\n\n if (! $activity->isProcessed()) {\n return new HttpFoundation\\JsonResponse([]);\n }\n\n $payload = [];\n\n if ($activity->hasTopicTriggers()) {\n $payload = $activity->getTopicTriggersSorted()\n ->map(\n static fn (Activity\\TopicTrigger $activityTopicTrigger): array\n => $transformer->transform($activityTopicTrigger)\n )\n ->values()\n ->all();\n }\n\n return new HttpFoundation\\JsonResponse($payload);\n }\n\n /**\n * @param Activity $activity\n * @param StatsTransformer $statsTransformer\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function stats(Activity $activity, StatsTransformer $statsTransformer)\n {\n $this->authorize('stream', $activity);\n\n if (! $activity->hasTranscription()) {\n return $this->response->errorNotFound('Waveform data is not yet generated.');\n }\n\n $this->response\n ->getManager()\n ->parseIncludes(['wavedata'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($activity, $statsTransformer);\n }\n\n public function destroy(Activity $activity)\n {\n $this->authorize('delete', $activity);\n\n $activity->delete();\n\n \\Log::info('Soft delete activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n\n return $this->response->withNoContent();\n }\n\n public function note(Activity $activity)\n {\n $this->authorize('note', $activity);\n\n $this->request->validate([\n 'note' => 'required|min:1|max:2000',\n 'time' => 'required|numeric|min:0|max:86400',\n ]);\n\n $note = $this->request->input('note');\n $time = $this->request->input('time');\n\n $this->activityService->setActivity($activity);\n $this->activityService->takeNote($this->getUser(), $note, $time);\n\n return $this->response->withCreated();\n }\n\n /**\n * Mark an activity as private.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPrivate(Activity $activity)\n {\n $this->authorize('markAsPrivate', $activity);\n\n if ($activity->is_private === false) {\n $activity->is_private = true;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * Mark an activity as public.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPublic(Activity $activity)\n {\n $this->authorize('markAsPublic', $activity);\n\n if ($activity->is_private) {\n $activity->is_private = false;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws LogicException\n */\n public function fetchCloudFrontS3MediaKeys(Activity $activity, PlaybackService $playbackService): JsonResponse\n {\n $masterTrack = $activity->masterTrack()->first();\n\n if (! $masterTrack instanceof Track) {\n throw new LogicException(sprintf('Master track not found for activity \"%s\"', $activity->getUuid()));\n }\n\n return $this->response->withArray(\n $playbackService->generateCookies(\n $masterTrack,\n $this->request->ip(),\n ),\n );\n }\n\n /**\n * @throws ValidationException\n */\n private function updateOrCreateActivitySearch(Request $request, ?Search $search = null): Search\n {\n $request->validate([\n 'name' => 'required|string|min:2|max:100',\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $searchName = $request->input('name');\n\n if ($search !== null) {\n $search->update([\n 'name' => $searchName,\n ]);\n\n return $search;\n }\n\n $request->validate([\n 'filters' => ['required', 'array', new MultidimensionalArrayMaxCharRule(limit: 255)],\n 'nudges' => 'array|max:' . count(Nudge::MAP_CHANNEL),\n 'nudges.*.channel' => 'required|in:' . implode(',', Nudge::MAP_CHANNEL),\n 'nudges.*.frequency' => 'required|in:' . implode(',', Nudge::MAP_FREQUENCY),\n 'nudges.*.expiresAt' => [\n 'required',\n 'date',\n 'after:today',\n 'before_or_equal:' . now()->addYear()->format('Y-m-d'),\n ],\n ]);\n\n $searchCriteria = Criteria::createFromRequest(\n Collection::make($request->input('filters', []))->all(),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($searchCriteria, $user);\n $this->validateSearch($request, $filterSet, 'filters.');\n\n /** @var Search $search */\n $search = Search::create([\n 'name' => $searchName,\n 'uuid' => Uuid::uuid4()->toString(),\n 'user_id' => $user->getId(),\n ]);\n\n Collection::make($request->input('nudges', []))\n ->each(fn (array $attributes): Nudge => $this->nudgeFactory->createNudge($search, $attributes));\n\n $this->storeNamedSearchFilters(Collection::make($request->all()), $search, $filterSet, 'filters.');\n\n return $search;\n }\n\n private function resolveAccount(\n Team $team,\n Contact $contact,\n ServiceInterface $crmService,\n array $prospects,\n ): ?Account {\n $this->logger->info('Resolving account from contact');\n $account = $contact->getAccount();\n\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS)) {\n $this->logger->info('Team does not have feature to link activity to multiple prospects');\n\n return $account;\n }\n\n $this->logger->info('Resolving account from prospect data');\n $accountData = array_filter(\n $prospects,\n static fn (array $prospectData): bool => $prospectData['type'] === 'account'\n );\n\n if (! empty($accountData)) {\n $this->logger->info('Found account data in prospects');\n $accountData = reset($accountData);\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountData['id'])->first();\n\n if (! $account instanceof Account) {\n $this->logger->info('Account not found in database, syncing from CRM');\n $account = $crmService->syncAccount($accountData['id']);\n }\n }\n\n $this->logger->info('Resolved account', ['account' => $account->getId()]);\n\n return $account;\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.40957448,"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.41821808,"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.42918882,"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.43783244,"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.44647607,"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.4574468,"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.46841756,"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.4950133,"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.50598407,"top":0.09896249,"width":0.029587766,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"bounds":{"left":0.7084442,"top":0.09896249,"width":0.02825798,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"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":"40","depth":4,"bounds":{"left":0.67785907,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.69015956,"top":0.123703115,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"40","depth":4,"bounds":{"left":0.6994681,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"64","depth":4,"bounds":{"left":0.7117686,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.7237367,"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.73105055,"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 * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","depth":4,"on_screen":true,"value":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","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}]...
|
-7287184300264252456
|
-8385861013499833196
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use Carbon\Carbon;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\In;
use Illuminate\Validation\ValidationException;
use InvalidArgumentException;
use Jiminny\Component\ActivityAnalytics;
use Jiminny\Component\ActivitySearch;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Queue\Constants;
use Jiminny\Contracts\ES\Events\UpdateSingleEntity;
use Jiminny\Contracts\ES\UpdateTargetEnum;
use Jiminny\Contracts\Nudge\NudgeFactoryInterface;
use Jiminny\Contracts\Playlist\PlaylistTrackFactoryInterface;
use Jiminny\Contracts\Repositories\PlaylistActivityRepository;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Enums\TeamSetting;
use Jiminny\Events\Activities\AiAutomation\ActivityProspectAdded;
use Jiminny\Events\Activities\Coaching\Coached;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Controllers\CommentContextInterface;
use Jiminny\Http\Responses\Api\AbstractResponse;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\ActivityCommentTransformer;
use Jiminny\Http\Transformers\ActivityTopicTriggerTransformer;
use Jiminny\Http\Transformers\ActivityTransformer;
use Jiminny\Http\Transformers\AvailabilityNotificationTransformer;
use Jiminny\Http\Transformers\CoachingFeedbackTransformer;
use Jiminny\Http\Transformers\CoachingSectionsTransformer;
use Jiminny\Http\Transformers\SearchTransformer;
use Jiminny\Http\Transformers\StatsTransformer;
use Jiminny\Jobs\Crm\SaveActivity;
use Jiminny\Jobs\Crm\UpdateStage;
use Jiminny\Jobs\Telephony\StartRecording;
use Jiminny\Jobs\Telephony\StopRecording;
use Jiminny\Jobs\Telephony\ToggleRecording;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\CoachingFeedback;
use Jiminny\Models\CoachingSection;
use Jiminny\Models\CoachingSectionCriterion;
use Jiminny\Models\CoachingSectionFeedback;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\LanguageDialect;
use Jiminny\Models\Lead;
use Jiminny\Models\Nudge;
use Jiminny\Models\PlaybookCategory;
use Jiminny\Models\Playlist;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\Track;
use Jiminny\Models\User;
use Jiminny\Repositories\CoachingFeedbackRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Rules\CrmReference;
use Jiminny\Rules\MultidimensionalArrayMaxCharRule;
use Jiminny\Services\ActivityService;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Services\PlaybackService;
use Jiminny\Services\UserService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
use Ramsey\Uuid\Uuid;
use Sentry;
use Symfony\Component\HttpFoundation;
final class ActivityController extends Controller implements CommentContextInterface
{
// Number of minutes to look back on activities. i.e. a timeout on activity duration.
private const int LOOK_BACK = 180;
public function __construct(
private ProviderRegistry $providerRegistry,
private ActivityService $activityService,
Response $response,
private UserService $userService,
private ActivitySearch\Service\ActivitySearch $activitySearch,
private NudgeFactoryInterface $nudgeFactory,
private ActivityCommentService $activityCommentService,
private LoggerInterface $logger,
private readonly CoachingFeedbackRepository $coachingFeedbackRepository,
private readonly TeamRepository $teamRepository,
) {
parent::__construct($response);
}
public static function getCommentImplementation(): string
{
return Comment::class;
}
public function delete()
{
$this->request->validate([
'*' => 'uuid:activities',
]);
$deletedIds = [];
foreach ($this->request->all() as $activityId) {
$activity = Activity::idOrUuId($activityId);
try {
if ($this->authorize('delete', $activity)) {
$activity->delete();
$deletedIds[] = $activityId;
\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);
}
} catch (AuthorizationException $authorizationException) {
// They didn't have permission.
}
}
return $this->response->withArray($deletedIds);
}
public function update(Request $request, Activity $activity)
{
$this->authorize('updateMetadata', $activity);
$request->validate([
'title' => 'string|max:250',
'category_id' => 'uuid:playbook_categories',
'language' => [
new In(
LanguageDialect::query()
->with('language')
->cursor()
->map(static function (LanguageDialect $languageDialect): string {
return $languageDialect->getLanguageLocale();
})
->all()
),
],
]);
if ($request->has('title')) {
$activity->title = $request->input('title');
}
if ($request->has('category_id')) {
$category = PlaybookCategory::uuid($request->input('category_id'));
if ($category->playbook->team_id !== $request->user()->team_id) {
return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
if ($request->has('language')) {
if (! $activity->isInProgress()) {
return $this->response->withError(
'Activity language can only be set while the meeting is in progress.',
400
);
}
$activity->setLanguageCode($request->input('language'));
}
$activity->save();
return $this->response->withOk();
}
// XXX: This should be merged with the update method.
/**
* @param Activity $activity
*
* @throws AuthorizationException
* @throws SocialAccountTokenInvalidException
*
* @return mixed
*/
public function summarize(Activity $activity): mixed
{
$this->logger->info('[Log Activity] Summarizing activity ', [
'activityId' => $activity->getUuid(),
'payload' => $this->request->all(),
]);
$this->authorize('update', $activity);
$this->logger->info('[Log Activity] Validating summary');
// Validate the payload.
$this->validateSummary($activity);
// All objects must belong to this team.
/** @var User $user */
$user = $this->request->user();
$team = $user->getTeam();
$crmService = $this->providerRegistry->get($team->crm->provider);
try {
$crmUser = $user;
if ($user->isCrmRequired() === false) {
$crmUser = $team->owner;
}
$crmService->setUser($crmUser);
} catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());
}
$rawEntities = $this->request->input('entities');
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid(
$this->request->input('layout_id')
);
// Delay execution of CRM jobs to avoid locking issues.
$jobDelay = 0;
// If we have arrived from a notification, mark it as read.
$notificationId = $this->request->input('nId');
if ($notificationId) {
$notification = $user->unreadNotifications->where('id', $notificationId)->first();
if ($notification) {
$notification->markAsRead();
}
}
$title = $this->request->input('title');
$prospects = $this->request->input('prospects');
$opportunityId = $this->request->input('opportunity_id');
$stageId = $this->request->input('stage_id');
$categoryId = $this->request->input('category_id');
$summary = $this->request->input('summary');
$crmProviderId = $this->request->input('crm_id');
$isInternal = $this->request->input('is_internal') ?? false;
$lead = null;
$category = null;
$account = null;
$contact = null;
$opportunity = null;
$stage = null;
$callStage = null;
foreach ($prospects as $prospectData) {
$objectId = $prospectData['id'];
if ($objectId === null) {
continue;
}
$objectType = $prospectData['type'];
$this->logger->info('debug', ['prospect_data' => $prospectData]);
try {
if ($objectType === null) {
$this->logger->info('no object type');
if ($crmService instanceof SupportsObjectTypeParseInterface) {
$objectType = $crmService->parseObjectType($objectId);
}
}
switch ($objectType) {
case 'lead':
$this->logger->info('Processing lead');
/** @var Lead|null $lead */
$lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();
// Lead does not exist locally, import it.
if ($lead === null) {
$this->logger->info('Lead does not exist locally');
/** @var Lead $lead */
$lead = $crmService->syncLead($objectId);
}
$this->logger->info('Lead found', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
if ($stageId === null) {
$this->logger->info('Stage ID is null');
// If it was not provided, just assume it is the current stage.
$callStage = $lead->stage;
break;
}
$this->logger->info('Looking for stage');
// Determine if they have changed the stage.
/** @var Stage $stage */
$stage = $team->crm->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_LEAD)
->firstOrFail();
$this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);
if ($lead->stage_id && $lead->stage_id !== $stage->id) {
$this->logger->info('Stage has changed');
// Storage current stage on activity.
$callStage = $lead->stage;
// The stage has changed, update in remote CRM.
dispatch(new UpdateStage($activity, $lead, $callStage, $stage));
$this->logger->info(
sprintf(
'[%s] User changing lead stage from %s to %s',
$crmService->getDisplayName(),
$callStage->getName(),
$stage->getName()
),
[
'user' => $user->getUuid(),
'lead' => $lead->getUuid(),
]
);
} else {
$this->logger->info('Stage has not changed');
// Stage remains as current.
$callStage = $stage;
}
break;
case 'account':
$this->logger->info('Processing account');
// If the object is not a lead, it should be an account.
$account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();
// Account does not exist locally, import it.
if ($account === null) {
$this->logger->info('Account does not exist locally');
$account = $crmService->syncAccount($objectId);
}
$this->logger->info('Account found', ['accountId' => $account->id]);
break;
case 'contact':
$this->logger->info('processing contact');
$contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$this->logger->info('contact does not exist locally');
$contact = $crmService->syncContact($objectId);
}
$this->logger->info('resolving account');
$account = $this->resolveAccount($team, $contact, $crmService, $prospects);
break;
}
// If they have specified an opportunity, retrieve this with stage.
if ($opportunityId) {
$this->logger->info('opportunity id is set');
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if ($opportunity === null) {
$this->logger->info('opportunity does not exist locally');
$opportunity = $crmService->syncOpportunity($opportunityId);
}
if ($stageId === null) {
$this->logger->info('stage id is null');
// If it was not provided, just assume it is the current stage.
$callStage = $opportunity->stage ?? null;
} else {
$this->logger->info('looking for stage');
/** @var ?Stage $opportunityStage */
$opportunityStage = $team->crm
->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
// There is a chance we still cannot import this opportunity.
if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {
$this->logger->info('opportunity stage has changed');
// Storage current stage on activity.
$callStage = $opportunity->stage;
dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));
$this->logger->info(
sprintf(
'[%s] User changing opportunity stage from %s to %s',
$crmService->getDisplayName(),
$callStage->name,
$opportunityStage->name
),
[
'userId' => $user->id_string,
'opportunityId' => $opportunity->id_string,
]
);
} else {
$this->logger->info('opportunity stage has not changed');
// Stage remains as current.
$callStage = $opportunityStage;
}
}
}
if ($crmProviderId) {
// Cast $crmProviderId to string otherwise it won't use database index for some records
$linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();
// Check if this activity has already been assigned to a different activity.
if ($linkedActivity && $linkedActivity->id !== $activity->id) {
throw new InvalidArgumentException(
'Sorry, the linked task has already been logged under a different call. '
. 'Please choose another linked task.'
);
}
}
} catch (InvalidArgumentException $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($exception->getMessage());
} catch (Exception $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorInternalError(
'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'
);
}
}
if ($categoryId) {
$category = PlaybookCategory::uuid($categoryId);
if ($category->playbook->team_id !== $team->id) {
throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
$this->logger->info('Prospect data', [
'lead_id' => $lead?->getId(),
'account_id' => $account?->getId(),
'contact_id' => $contact?->getId(),
'opportunity_id' => $opportunity?->getId(),
'stage_id' => $stage?->getId(),
]);
if ($title) {
$activity->title = $title;
}
if ($summary) {
$activity->summary = $summary;
}
if ($crmProviderId) {
$activity->crm_provider_id = $crmProviderId;
}
if ($callStage) {
$this->logger->info('Setting stage id', ['stageId' => $callStage->id]);
$activity->stage_id = $callStage->id;
}
if ($lead) {
$this->logger->info('Setting lead id', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
// If we are changed from an account > lead, unset the account data.
$this->logger->info('Unsetting account id, opportunity id, contact id, value');
$activity->account_id = null;
$activity->opportunity_id = null;
$activity->contact_id = null;
$activity->value = null;
}
if ($account) {
$this->logger->info('Setting account id', ['accountId' => $account->id]);
$activity->account_id = $account->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('unsetting lead id');
$activity->lead_id = null;
// Unset the contact if switching different accounts. Will be set up below if still applicable.
if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {
$this->logger->info('Unsetting contact id');
$activity->contact_id = null;
}
}
if ($opportunity) {
$this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);
$this->logger->info('unsetting lead id');
$activity->opportunity_id = $opportunity->id;
$activity->value = $opportunity->value;
// If we are changed from an lead > account, unset the lead data.
$activity->lead_id = null;
}
if ($contact) {
$this->logger->info('setting contact id', ['contactId' => $contact->id]);
$activity->contact_id = $contact->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('Unsetting lead id');
$activity->lead_id = null;
}
$activity->is_internal = $isInternal;
$activity->save();
$activity->refresh();
$this->logger->notice('Activity saved', [
'activity_id' => $activity->getId(),
'lead_id' => $activity->lead_id,
'account_id' => $activity->account_id,
'contact_id' => $activity->contact_id,
'opportunity_id' => $activity->opportunity_id,
'stage_id' => $activity->stage_id,
'crm_provider_id' => $activity->getCrmProviderId(),
]);
// Store entities as field data on the activity.
$updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);
if ($activity->isLoggable()) {
// Follow-up Task or Event data.
$followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);
$this->logger->info('CRM LOG manual log triggered', [
'activityId' => $activity->getUuid(),
'followupData' => $followupData,
'userId' => $user->getUuid(),
]);
// Store data in the CRM.
// ++add check for crm_required
$job = new SaveActivity($activity, $followupData);
if ($updatedData) {
$job->delay(Carbon::now()->addMinutes($jobDelay));
}
dispatch($job);
// Manually dispatch log for Opportunity or Prospect added
if ($activity->hasOpportunity() || $activity->hasProspect()) {
event(new ActivityProspectAdded(
activity: $activity,
eventSource: 'manually-log-crm-data'
));
}
}
return $this->response->withOk();
}
/**
* Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.
*
* @param ServiceInterface $service
* @param Activity $activity
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array
{
$updatedData = [];
$existingData = $activity->data()->get();
// We need to delete any existing data to overwrite with latest values.
$activity->data()->delete();
$layoutEntities = $layout->entities()
->with('field', 'parent')
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->get();
/** @var LayoutEntity $entity */
foreach ($layoutEntities as $entity) {
// If the user has provided a value for this entity
if (array_key_exists($entity->id_string, $entities)) {
$value = $entities[$entity->id_string];
// Convert raw data into values that the CRM can consume.
if ($value) {
$value = $service->normalizeValue($entity->field->type, $value);
}
// Check the field is part of the activity-summary section.
if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {
// This is the internal database ID, not the external CRM ID.
$objectId = null;
switch ($entity->field->object_type) {
case Field::OBJECT_ACCOUNT:
$objectId = $activity->account_id;
break;
case Field::OBJECT_CONTACT:
$objectId = $activity->contact_id;
break;
case Field::OBJECT_OPPORTUNITY:
$objectId = $activity->opportunity_id;
break;
case Field::OBJECT_LEAD:
$objectId = $activity->lead_id;
break;
case Field::OBJECT_TASK:
case Field::OBJECT_EVENT:
$objectId = $activity->id;
break;
}
if ($objectId) {
/** @var FieldData $data */
$data = $activity->data()->create([
'crm_layout_entity_id' => $entity->id,
'crm_field_id' => $entity->crm_field_id,
'object_type' => $entity->field->object_type,
'object_id' => $objectId,
'value' => $value,
]);
// Never send read-only field data to the CRM.
if ($entity->read_only === false && $entity->is_visible) {
$existingValue = $existingData
->where('crm_layout_entity_id', $entity->id)
->where('crm_field_id', $entity->crm_field_id)
->where('object_type', $entity->field->object_type)
->where('object_id', $objectId)
->first();
// If the field was actually changed, we need to reflect this in the CRM too.
if ($existingValue === null || $existingValue->value !== $value) {
$updatedData[] = $data->id;
}
}
}
}
}
}
return $updatedData;
}
/**
* Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.
*
* @param ServiceInterface $crmService
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array
{
$fieldData = [];
foreach ($entities as $entityId => $value) {
// Only bother with fields that have a value.
if ($value) {
// Extract the entity from the UUID. Check the field is valid and part of the follow-up section.
$entity = $layout->entities()
->uuid($entityId, false)
->whereHas('parent', function ($query) {
$query->where('label', 'follow-up');
})
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->first();
if ($entity) {
// Convert raw data into values that the CRM can consume.
$value = $crmService->normalizeValue($entity->field->type, $value);
// Add the field and value to the payload.
$fieldData += [
$entity->field->crm_provider_id => $value,
];
}
}
}
return $fieldData;
}
/**
* @param Activity $activity
*/
private function validateSummary(Activity $activity): void
{
$team = $activity->user->team;
$crmProvider = $team->crm->provider;
$attributes = [];
$rules = [
'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,
'title' => 'string|max:250',
'prospects' => 'required|array',
'opportunity_id' => new CrmReference($crmProvider),
'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',
'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator
'summary' => 'max:50000',
'nId' => 'exists:notifications,id',
'crm_id' => new CrmReference($crmProvider),
'entities' => 'array',
'is_internal' => 'boolean',
];
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));
// Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.
$entities = $layout->entities()
->where('read_only', 0)
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->whereHas('parent', function ($query) use ($activity) {
if ($activity->isLoggable() === false) {
$query->where('label', '<>', 'follow-up');
}
});
$isInternal = $this->request->input('is_internal', false);
foreach ($entities->get() as $entity) {
$rules += $this->buildFieldValidator($entity, $isInternal);
$attributes += $this->buildFieldMessage($entity);
}
$this->request->validate($rules, [], $attributes);
}
private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array
{
return [
'entities.' . $entity->id_string => $entity->getValidator($isInternal),
];
}
/**
* @param LayoutEntity $entity
*
* @return array
*/
private function buildFieldMessage(LayoutEntity $entity): array
{
$label = $entity->label;
if ($label === null) {
$label = $entity->field->label;
}
return [
'entities.' . $entity->id_string => $label,
];
}
public function search(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->debugLog(
$user,
'User extracted from request',
['user' => $user->getId(), 'tz' => $user->getTimezone()]
);
$searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());
$this->debugLog(
$user,
'ActivitySearch criteria built',
['searchCriteria' => $searchCriteria]
);
$filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);
$this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);
$this->validateSearch($request, $filterSet);
$this->debugLog($user, 'Request validated');
$searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);
/** @var Collection<Activity> $activities */
$activities = $searchResponse['results'];
$this->debugLog($user, 'Activities ES response extracted');
$hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(
$user->getTeamId(),
TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),
);
if ($hideInternalMeetingsSetting?->getValue() === '1') {
$activities = $activities->filter(function (Activity $activity) {
if ($activity->is_internal && empty($activity->actual_start_time)) {
return false;
}
return true;
});
}
$this->debugLog($user, 'Internal meetings (?!) filtered');
$this->response->getManager()
->parseIncludes([
'category',
'organizer.group',
'prospect',
'stage',
'opportunity',
'stats',
'scorecards',
'masterTrack',
'activeParticipants',
'notification',
])
->setSerializer(new JsonSerializer());
$transformerExcludes = $this->request->input('exclude');
if ($transformerExcludes) {
$this->response->getManager()->parseExcludes($transformerExcludes);
}
$this->debugLog($user, 'Response Manager (?!) applied');
$transformer = new ActivityTransformer();
$transformer->setConsumer($user);
$this->debugLog($user, 'Activity Transformer added');
$resource = new \League\Fractal\Resource\Collection($activities, $transformer);
$page = $searchCriteria->getPageNumber();
$this->debugLog($user, 'Search criteria page number called', ['page' => $page]);
$histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');
$this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);
return $this->response->withArray([
'pagination' => [
'total' => $searchResponse['totalHits'],
'current' => $page,
'prev' => max($page - 1, 1),
'next' => $page + 1,
],
'results' => $this->response->getManager()->createData($resource)->toArray(),
'histogram' => $histogram,
]);
}
private function debugLog(User $user, string $logMessage, ?array $context = []): void
{
// Debug for Learning People Only
if ($user->getTeamId() !== 260) {
return;
}
Log::notice(
sprintf('[activity-search-controller] %s', $logMessage),
$context
);
}
/** @throws ValidationException */
private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void
{
$rules = [
'exclude' => 'array',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
];
if ($prefix !== null && mb_strpos($prefix, '.') !== false) {
$rules[rtrim($prefix, '.')] = sprintf(
'required|array|max:%d',
$filterSet->count()
);
}
$validationRules = $filterSet->getValidationRules($prefix)
->merge($rules)
->all();
$request->validate($validationRules);
}
public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$search = $this->updateOrCreateActivitySearch($request);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function updateActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('update', $search);
$this->updateOrCreateActivitySearch($request, $search);
return $this->response->withOk();
}
private function storeNamedSearchFilters(
Collection $request,
Search $search,
FilterDefinitionCollection $filterSet,
?string $prefix = null,
): self {
$arrayTypeProperties = $filterSet
->getPropertyTypes([
FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,
])
->all();
$supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);
foreach ($supportedRequestProperties as $requestPropertyName) {
if (! array_has($request, $requestPropertyName)) {
continue;
}
/** @var string|string[] $propertyValue */
$propertyValue = array_get($request, $requestPropertyName);
$propertyName = $prefix === null
? $requestPropertyName
: mb_substr($requestPropertyName, mb_strlen($prefix));
$isArrayType = array_has($arrayTypeProperties, $propertyName);
if (! $isArrayType) {
/** @var string $requestPropertyValue */
$search->filters()->updateOrCreate(
[
'filter' => $propertyName,
],
[
'value' => $propertyValue,
]
);
continue;
}
/** @var string[] $requestPropertyValue */
/** @var SearchFilter[]|Collection $existingFilterValues */
$existingFilterValuesKeyed = $search->filters()
->where('filter', $propertyName)
->get()
->keyBy('id');
// Iterate over values provided as request parameters
foreach ($propertyValue as $value) {
/** @var SearchFilter|null $valueFilter */
$valueFilter = $search->filters()
->where(
[
'filter' => $propertyName,
'value' => $value,
]
)
->first();
if ($valueFilter !== null) {
// Remove filter value pair from list to be deleted
$existingFilterValuesKeyed->forget($valueFilter->id);
} else {
// Add new filter/value pair
$search->filters()->updateOrCreate([
'filter' => $propertyName,
'value' => $value,
]);
}
}
// Delete filter value pairs for this filter that no longer exist in request parameters
foreach ($existingFilterValuesKeyed as $existingFilter) {
$existingFilter->delete();
}
}
/** @var Collection<int, SearchFilter> $filtersKeyed */
$filtersKeyed = $search->filters()->get()->keyBy('filter');
// wipe removed filters from this search
foreach ($filtersKeyed as $filterName => $filter) {
if (array_has($request, $prefix . $filterName)) {
continue;
}
// Remove all filter values for this filter
$search->filters()->where('filter', $filterName)->delete();
}
return $this;
}
/**
* @throws AuthorizationException
*/
public function fetchActivitySearch(
Search $search,
Request $request,
SearchTransformer $searchTransformer,
): JsonResponse {
$this->authorize('view', $search);
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withCollection(
$user->searches()->get(),
$searchTransformer
->withConsumer($user)
);
}
/**
* Deletes a saved search
*
* @param Request $request
* @param Search $search
*
* @throws Exception
*
* @return JsonResponse
*/
public function deleteActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('delete', $search);
// Orphan any AutomatedReports that use this search
$search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);
// Delete filters and the search itself
$search->filters()->delete();
$search->delete();
return $this->response->withOk();
}
public function live(Request $request, ElasticActivityRepository $repository): JsonResponse
{
$user = $this->getUserFromRequest($request);
$this->request->validate([
'sort_direction' => 'in:asc,desc',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
]);
$activities = $repository->getLiveCoachingEligibleActivities(
user: $user,
lookBackMinutes: self::LOOK_BACK,
limit: (int) $this->request->input('limit', 25),
page: (int) $this->request->input('page', 1),
sortBy: ['actual_start_time', 'scheduled_start_time'],
sortDirection: (string) $this->request->input('sort_direction', 'asc'),
);
$this->response
->getManager()
->parseIncludes(['organizer.group', 'prospect'])
->setSerializer(new JsonSerializer());
return $this->response->withCollection($activities, new ActivityTransformer());
}
/**
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function show(Activity $activity, ActivityService $activityService): JsonResponse
{
$this->authorize('show', $activity);
$user = $activity->getUser();
$team = $user->getTeam();
// Sync the opportunity with the latest data if possible.
if ($activity->opportunity_id) {
try {
$crmService = $this->providerRegistry->get($team->crm->provider);
if (! $user->isCrmRequired()) {
$crmService->setUser($team->getOwner());
} else {
$crmService->setUser($user);
}
$crmService->syncOpportunity($activity->opportunity->crm_provider_id);
} catch (Exception $exception) {
// Move on.
}
}
$activityData = $activityService->getActivityData($this->request->user(), $activity);
return response()->json($activityData);
}
public function createRecording(Activity $activity)
{
$this->authorize('record', $activity);
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Tell Twilio to start recording this activity.
if ($activity->recording_state === Activity::RECORDING_OFF) {
$job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withCreated();
}
return $this->response->errorGone('Activity is already recording.');
}
public function updateRecording(Request $request, Activity $activity)
{
$this->authorize('record', $activity);
$request->validate([
'preference' => 'boolean',
'state' => [
'string',
Rule::in([
Activity::RECORDING_IN_PROGRESS,
Activity::RECORDING_PAUSED,
]),
],
]);
if ($request->has('state')) {
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Toggle the recording state between paused and resumed.
if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {
$job = (new ToggleRecording($activity, $request->input('state')))
->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Recording is not toggleable.');
}
if ($request->has('preference')) {
$activity->update([
'recording_preference' => $request->input('preference') ? 1 : 0,
]);
return $this->response->withOk();
}
return $this->response->errorWrongArgs('Something went wrong');
}
public function stopRecording(Activity $activity)
{
$this->authorize('stopRecord', $activity);
// Tell Twilio to stop recording this activity.
if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {
$job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Activity is not recording.');
}
/**
* Add activity to this user's favorites playlist
*
* @throws AuthorizationException
*/
public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse
{
$this->authorize('favorite', $activity);
$user = $this->getUserFromRequest($this->request);
$favorite = $activity->wasFavoritedBy($user);
$name = $activity->activity_title ?? '';
// It needs to check at least one record.
if (! $favorite) {
$favoritePlaylist = $user->favoritePlaylist();
$playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(
$activity,
$user,
$favoritePlaylist
);
if ($playlistActivity !== null) {
$playlistActivity->update(
// Just update, don't sort.
['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],
);
} else {
$playlistActivity = $activity->playlistActivities()->create([
'playlist_id' => $favoritePlaylist->getId(),
'user_id' => $user->getId(),
'start_time' => 0,
'name' => mb_strimwidth($name, 0, 100),
]);
// Sort it on top.
$playlistActivity->update(
[
'sort' => $playlistActivityRepository->calculateNewSortOrder(
null,
$playlistActivity,
),
],
);
}
$playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);
return new JsonResponse([], JsonResponse::HTTP_CREATED);
}
return new JsonResponse(
[
'error' => [
'code' => AbstractResponse::CODE_CONFLICT,
'http_code' => JsonResponse::HTTP_CONFLICT,
'message' => 'Resource Already Exists',
],
],
JsonResponse::HTTP_CONFLICT,
);
}
/**
* Remove activity from this user's favorites playlist
*
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function unfavorite(Activity $activity)
{
$user = $t...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
32857
|
1254
|
27
|
2026-05-13T09:40:08.958486+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665208958_m1.jpg...
|
PhpStorm
|
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Undo
Redo
Cut
Copy
Paste
Paste and Match Style
Sel Undo
Redo
Cut
Copy
Paste
Paste and Match Style
Select All
Open DevTools...
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"Undo","depth":5,"bounds":{"left":0.0,"top":0.0,"width":0.065972224,"height":0.024444444},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Redo","depth":5,"bounds":{"left":0.0,"top":0.0,"width":0.065972224,"height":0.024444444},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Cut","depth":5,"bounds":{"left":0.0,"top":0.0,"width":0.065972224,"height":0.024444444},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Copy","depth":5,"bounds":{"left":0.0,"top":0.0,"width":0.065972224,"height":0.024444444},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Paste","depth":5,"bounds":{"left":0.0,"top":0.0,"width":0.065972224,"height":0.024444444},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Paste and Match Style","depth":5,"bounds":{"left":0.0,"top":0.0,"width":0.065972224,"height":0.024444444},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Select All","depth":5,"bounds":{"left":0.0,"top":0.0,"width":0.065972224,"height":0.024444444},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Open DevTools","depth":5,"bounds":{"left":0.0,"top":0.0,"width":0.065972224,"height":0.024444444},"on_screen":false,"role_description":"text"}]...
|
4445374797877545977
|
7802338930891525294
|
click
|
hybrid
|
NULL
|
Undo
Redo
Cut
Copy
Paste
Paste and Match Style
Sel Undo
Redo
Cut
Copy
Paste
Paste and Match Style
Select All
Open DevTools
SlackFileEdit ViewGoHistoryWindowHelpAPPDOCKERDEV (docker)₴82APP (-zshtests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleterTest.phptests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesProviderTest.phptests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesUploaderTest.phptests/Unit/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeeches?tests/Unit/Component/Transcription/Diarization/Source/MeetingBotSourceTest.phptests/Unit/Contracts/Services/Calendar/CalendarTraitTest.phptests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.phptests/Unit/Jobs/Activity/Import/ImportTwilioVideoSpeechesJobTest.phptests/Unit/Jobs/Activity/Import/IsActivityReadyForProcessingJobTest.phptests/Unit/Jobs/Calendar/SetupCalendarSyncTest.phptests/Unit/Services/Activity/ParticipantsServiceTest.phptests/Unit/Services/Calendar/Command/ImportParticipantsTest.phptests/Unit/Services/Calendar/GoogleCalendarServiceTest.phptests/Unit/Services/Crm/Close/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTest.phptests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTraitMatchActivitiesTest.phytests/Unit/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTraitOpportunitiesTe:tests/Unit/Services/Crm/Pipedrive/ImportOpportunityMatchActivitiesTest.phptests/Unit/Services/Crm/Salesforce/ServiceTest.phptests/Unit/Services/Mail/0ffice/EmailApiClientTest.phptests/Unit/Services/RecallAI/RecallAIServiceTest.php113 files changed, 4143 insertions(+), 1740 deletions(-)create mode 120000 CLAUDE.mdcreate mode 100644 app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.phpdelete mode 100644 app/Component/ES/ElasticSearchWorkerManager.phpdelete mode 100644 app/Component/ES/Worker/ActivityWorker.phpdelete mode 100644 app/Component/ES/Worker/EntityWorker.phpdelete mode100644 app/Component/ES/Worker/WorkerAmount.phpdelete mode100644 app/Component/ES/Worker/WorkerInterface.phpcreate mode100644 app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.phtcreate mode100644 app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/Assembl:create mode100644 app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNot(create mode 100644 app/Console/Commands/Crm/Backfill0pportunityUserFromAccountCommand.phpdelete mode 100644 app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.phpcreate mode100644 front-end/src/components/shared/modals/EntityPickerModal/__tests__/us‹create mode 100644 tests/Feature/Component/Nudge/Process0rganisationImmediateNudgesJobTe:create mode 100644 tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheck‹delete mode 100644 tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/ActivityWorkerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/EntityWorkerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/WorkerAmountTest.phpcreate mode 100644 tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCr‹create mode 100644 tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.phpLukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ I|HomeDMsActivityFilesLaterMore>•.(alo]• Support Daily - in 2h 20 m100% <78•Wed 13 May 12:40:08→Describe what you are looking forJiminny ...Nikolay Ivanov6 0curoaroylau# engineering# general# jiminny-bg# platform-tickets# product_launches#random# releases# sofia-office# support# thank-yous# the_people_of jimi...MessagesAdd canvas@ Files+Lukas Kovalik 11.Today ~мен все ме праща наhttps://app.vanta.com/c/jiminny.com/employee/onboardingNikolay Ivanov 11:01 AMХм, Джейс дали не може да ти помогне?Lukas Kovalik 11:01 AMще питам James, предполагам че нямам правада мерсиNikolay Ivanov 11:01 AMмда° Direct messages& Nikolay Ivanovdo James Graham. Stoyan Tanev. Galya Dimitrova. Steliyan Georgievo Petko Kashinski®. Aneliya Angelovaã. Stefka Stoyanova•. Vasil Vasilev •!Lukas Kovalik y...МОЛЯLukas Kovalik 12:13 PMНики сори, още един въпрос имамкогато ги правеше ти FE ли оправяима vulnerabilities no npmNikolay Ivanov 12:28 PMнетях ги оставямLukas Kovalik 12:29 PMаз погледнах твоя тикет и там друго нямашесамо FEкак стигна до Workerl:: AppsJira CloudMessage Nikolay IvanovToast...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
32858
|
1255
|
37
|
2026-05-13T09:40:08.973476+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665208973_m2.jpg...
|
PhpStorm
|
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Undo
Redo
Cut
Copy
Paste
Paste and Match Style
Sel Undo
Redo
Cut
Copy
Paste
Paste and Match Style
Select All
Open DevTools...
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"Undo","depth":5,"bounds":{"left":0.27027926,"top":1.0,"width":0.03158245,"height":0.0},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Redo","depth":5,"bounds":{"left":0.27027926,"top":1.0,"width":0.03158245,"height":0.0},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Cut","depth":5,"bounds":{"left":0.27027926,"top":1.0,"width":0.03158245,"height":0.0},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Copy","depth":5,"bounds":{"left":0.27027926,"top":1.0,"width":0.03158245,"height":0.0},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Paste","depth":5,"bounds":{"left":0.27027926,"top":1.0,"width":0.03158245,"height":0.0},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Paste and Match Style","depth":5,"bounds":{"left":0.27027926,"top":1.0,"width":0.03158245,"height":0.0},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Select All","depth":5,"bounds":{"left":0.27027926,"top":1.0,"width":0.03158245,"height":0.0},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Open DevTools","depth":5,"bounds":{"left":0.27027926,"top":1.0,"width":0.03158245,"height":0.0},"on_screen":false,"role_description":"text"}]...
|
4445374797877545977
|
7802338930891525294
|
click
|
hybrid
|
NULL
|
Undo
Redo
Cut
Copy
Paste
Paste and Match Style
Sel Undo
Redo
Cut
Copy
Paste
Paste and Match Style
Select All
Open DevTools
PhostormProiectVIeWINavigareCodeLaravelKeractorJOOISWindowFV faVsco.js°9 master ~(C ActivityController.pnp|aravel.l0gA SF (jiminny@localhost]4 HS_local [jiminny@localhost]& console (PROD] X A console [EU]D Teaminsights, m Themesv D UserAutomatedRep -007final class ActivityController extends Controller implements CommentContextInterfaceA console [STAGING]v DV2c) ACuviLyvzconuroAskAnythingCorLL0/() AskJiminnyRepc© DealsV2Controll 410%(C) OnDemandV2Cc€ PlavlistControlleC) PlavlistSharecorC PlavlistTrackCor111131114(C) UoloadControlleC) [EMAIL]) AiCrmNotesControl(c) Racecontroller nhn@ ClientTokenControl 1157(e) CrmController.pnp11158© DealLevelPromptsC 1159c) DealRiskcontroller.@ InctantMeetinaCont 11611164C) Languagecontrolle© LayoutManagemen 1163Ca) livoCoodControllor1164 9© MeetingsController 1192© MessageController. 1193 l >C MotadataControllor L2141212 |159c) Mobilesettinasconi© MomentController.r 125gc Nudgecontroller.phNumberAllocatorCc 12/e11271OraanizationMembi 1212C) OraanizationRetentC) OraanizationSvnce@ PartnerController.o1276 1g) PlavbackController1133480 PlavlictController pl 1335g ScimController.nhn9) SidekickController , 13379a) SoftnhoneControlle© SsoController.php() CnbccrintionGontrae ToamAiAutomationt6) ToamAiContovtCar0 ToamControllor nhr 1343 (@9 >public function ListActivitySearch(Request Srequest, SearchTransformer SsearchTransformer): JsonResponses: 569— 571* Deletes a saved search— 573* @param Request $request* apanam Search $search575* achrows except1or* drecurn Jsonkesponse578579— 580pubLic tunccion deleteActivicysearch kequest srequest, search ssearch: Jsonkesponse.582oubunc tunction uivelrequest srequest, clastcactIvirvkedosirory srepostrory: usonkesponse....* dparam Activitu Sactivitu*Gthrows_AuthorizationExcent.zon589* Greturn mixedpublic function show(Activity Sactivity, ActivityService $activityService): JsonResponse{...}public function createRecordingActivity Sactivity)i...h597593594public function updateRecording(Request Srequest, Activity $activity)i...h~ 596public function stopRecording(Activity Sactivity)(...}60€* Add activity to this user's favorites playlist_ 601=602* athrows AuthorizationException604public function favorite(Activitv Sactivitv. PlavlistActivitvRepository SolavlistActivitvRepositorv): J501605606=607* Remove activitu from this user's favorites plaulist60S•Goarom Actvatu sactvitu*athrowsAuthorizationExcent.ion* Greturn mixednublic function unfavorite Activity Sactivitv ?Tx: AutovCONCAT(u.id, CASE WHEN U.id = t.owner_id THEN ' (owner)' ELSE"' END) AS user_id,sa.*t.owner_id FROM social_accounts saNolN usens u on u.id e sa.sociablle i.diJOIN teams t .n<->l: on t.id = u.team_icWHERE u.team_id = 581 and sa.provider = 'salesforce';SELECT * FROM automated_report_results order by id desc;select * from features;select * from team_features where feature_id = 40;select * from teams where id = 556:select * from automated_reports:where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044"pat", "podcast"]SELECT * FROM automated report results WHERE uuid to bin( '822fa41b-afd3-43a9-a248-86b0e36f3131') = vuid:select * from automated_report_results order by za desc;SELECT * FROM automated report resultsWHEKE 10 =144select * from automated report results WHERE report id = 54:select * from opportunities where 1d = 7594549ªSELE * FROM teams WHERE name LIKE "%Les%': # 711, 692. 16067 - Timinnvintearationdlesmils.comselect * from playbooks where team id = 711: # event 226147SELEd * FROM Davbook catedonies WHERE DLavbook 10 = 55151SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_typeSELECT * EROM eom fields WHERE 1d = 226147÷SELECT * EROM eom field values WHERE com field 1d = 226147.SELECT * FROM crm_configurations WHERE id = 692;SEISCTCONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE "' END) AS user_id,nemailiSa.xt.owner id FROM social accounts saJOIN users u on u.id = sa.sociable idJOIN teams t 1..n<->1: on t.id = u.team idWHERE U.team id = 711 and sa.provider = 'salesforce':SELECT * FROM crm profiles co JOIN users u 1..n<->1: on u.id = co.user id WHERE u.team_id = 711:select * from leads:select * from calendars:SELECTcascadeNew Cascade40 h^ & Support Daily - in 2h 20 ml100% L2• Wed 13 May 12:40:08AskJiminnyReportActivityServiceTest v+0 ..So jiminny040 A1 A40 V 64 ^Cascade Code x .Kick off a new project. Make changesacross your entre codedasecEvent Serialization Requirement The user wants to determine it the serializesmodels trait is necessary in the Automat.. 22h© Fixing Automated Report Job Failure Due to Missing PDF URLdonit want to he e recorder. Currentiy when a trial is created we dive the Owner a !he really neeas to be a recorder he role of the owner when settina uo a trialpra chotes thot n o - oe e, e ertere veieo, ayetthis ontion shouldn't annear when editing an craanicatiorwhen the owner signs in, they should have the selected role + Admin permissions.WN WIUndoCutCopypastePaste and Match StyleSelect AllOnen DevToolsran isost cases0 +]Po 4 spaces...
|
32856
|
NULL
|
NULL
|
NULL
|
|
32859
|
1254
|
28
|
2026-05-13T09:40:40.026939+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665240026_m1.jpg...
|
PhpStorm
|
faVsco.js – ActivityController.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use Carbon\Carbon;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\In;
use Illuminate\Validation\ValidationException;
use InvalidArgumentException;
use Jiminny\Component\ActivityAnalytics;
use Jiminny\Component\ActivitySearch;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Queue\Constants;
use Jiminny\Contracts\ES\Events\UpdateSingleEntity;
use Jiminny\Contracts\ES\UpdateTargetEnum;
use Jiminny\Contracts\Nudge\NudgeFactoryInterface;
use Jiminny\Contracts\Playlist\PlaylistTrackFactoryInterface;
use Jiminny\Contracts\Repositories\PlaylistActivityRepository;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Enums\TeamSetting;
use Jiminny\Events\Activities\AiAutomation\ActivityProspectAdded;
use Jiminny\Events\Activities\Coaching\Coached;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Controllers\CommentContextInterface;
use Jiminny\Http\Responses\Api\AbstractResponse;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\ActivityCommentTransformer;
use Jiminny\Http\Transformers\ActivityTopicTriggerTransformer;
use Jiminny\Http\Transformers\ActivityTransformer;
use Jiminny\Http\Transformers\AvailabilityNotificationTransformer;
use Jiminny\Http\Transformers\CoachingFeedbackTransformer;
use Jiminny\Http\Transformers\CoachingSectionsTransformer;
use Jiminny\Http\Transformers\SearchTransformer;
use Jiminny\Http\Transformers\StatsTransformer;
use Jiminny\Jobs\Crm\SaveActivity;
use Jiminny\Jobs\Crm\UpdateStage;
use Jiminny\Jobs\Telephony\StartRecording;
use Jiminny\Jobs\Telephony\StopRecording;
use Jiminny\Jobs\Telephony\ToggleRecording;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\CoachingFeedback;
use Jiminny\Models\CoachingSection;
use Jiminny\Models\CoachingSectionCriterion;
use Jiminny\Models\CoachingSectionFeedback;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\LanguageDialect;
use Jiminny\Models\Lead;
use Jiminny\Models\Nudge;
use Jiminny\Models\PlaybookCategory;
use Jiminny\Models\Playlist;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\Track;
use Jiminny\Models\User;
use Jiminny\Repositories\CoachingFeedbackRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Rules\CrmReference;
use Jiminny\Rules\MultidimensionalArrayMaxCharRule;
use Jiminny\Services\ActivityService;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Services\PlaybackService;
use Jiminny\Services\UserService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
use Ramsey\Uuid\Uuid;
use Sentry;
use Symfony\Component\HttpFoundation;
final class ActivityController extends Controller implements CommentContextInterface
{
// Number of minutes to look back on activities. i.e. a timeout on activity duration.
private const int LOOK_BACK = 180;
public function __construct(
private ProviderRegistry $providerRegistry,
private ActivityService $activityService,
Response $response,
private UserService $userService,
private ActivitySearch\Service\ActivitySearch $activitySearch,
private NudgeFactoryInterface $nudgeFactory,
private ActivityCommentService $activityCommentService,
private LoggerInterface $logger,
private readonly CoachingFeedbackRepository $coachingFeedbackRepository,
private readonly TeamRepository $teamRepository,
) {
parent::__construct($response);
}
public static function getCommentImplementation(): string
{
return Comment::class;
}
public function delete()
{
$this->request->validate([
'*' => 'uuid:activities',
]);
$deletedIds = [];
foreach ($this->request->all() as $activityId) {
$activity = Activity::idOrUuId($activityId);
try {
if ($this->authorize('delete', $activity)) {
$activity->delete();
$deletedIds[] = $activityId;
\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);
}
} catch (AuthorizationException $authorizationException) {
// They didn't have permission.
}
}
return $this->response->withArray($deletedIds);
}
public function update(Request $request, Activity $activity)
{
$this->authorize('updateMetadata', $activity);
$request->validate([
'title' => 'string|max:250',
'category_id' => 'uuid:playbook_categories',
'language' => [
new In(
LanguageDialect::query()
->with('language')
->cursor()
->map(static function (LanguageDialect $languageDialect): string {
return $languageDialect->getLanguageLocale();
})
->all()
),
],
]);
if ($request->has('title')) {
$activity->title = $request->input('title');
}
if ($request->has('category_id')) {
$category = PlaybookCategory::uuid($request->input('category_id'));
if ($category->playbook->team_id !== $request->user()->team_id) {
return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
if ($request->has('language')) {
if (! $activity->isInProgress()) {
return $this->response->withError(
'Activity language can only be set while the meeting is in progress.',
400
);
}
$activity->setLanguageCode($request->input('language'));
}
$activity->save();
return $this->response->withOk();
}
// XXX: This should be merged with the update method.
/**
* @param Activity $activity
*
* @throws AuthorizationException
* @throws SocialAccountTokenInvalidException
*
* @return mixed
*/
public function summarize(Activity $activity): mixed
{
$this->logger->info('[Log Activity] Summarizing activity ', [
'activityId' => $activity->getUuid(),
'payload' => $this->request->all(),
]);
$this->authorize('update', $activity);
$this->logger->info('[Log Activity] Validating summary');
// Validate the payload.
$this->validateSummary($activity);
// All objects must belong to this team.
/** @var User $user */
$user = $this->request->user();
$team = $user->getTeam();
$crmService = $this->providerRegistry->get($team->crm->provider);
try {
$crmUser = $user;
if ($user->isCrmRequired() === false) {
$crmUser = $team->owner;
}
$crmService->setUser($crmUser);
} catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());
}
$rawEntities = $this->request->input('entities');
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid(
$this->request->input('layout_id')
);
// Delay execution of CRM jobs to avoid locking issues.
$jobDelay = 0;
// If we have arrived from a notification, mark it as read.
$notificationId = $this->request->input('nId');
if ($notificationId) {
$notification = $user->unreadNotifications->where('id', $notificationId)->first();
if ($notification) {
$notification->markAsRead();
}
}
$title = $this->request->input('title');
$prospects = $this->request->input('prospects');
$opportunityId = $this->request->input('opportunity_id');
$stageId = $this->request->input('stage_id');
$categoryId = $this->request->input('category_id');
$summary = $this->request->input('summary');
$crmProviderId = $this->request->input('crm_id');
$isInternal = $this->request->input('is_internal') ?? false;
$lead = null;
$category = null;
$account = null;
$contact = null;
$opportunity = null;
$stage = null;
$callStage = null;
foreach ($prospects as $prospectData) {
$objectId = $prospectData['id'];
if ($objectId === null) {
continue;
}
$objectType = $prospectData['type'];
$this->logger->info('debug', ['prospect_data' => $prospectData]);
try {
if ($objectType === null) {
$this->logger->info('no object type');
if ($crmService instanceof SupportsObjectTypeParseInterface) {
$objectType = $crmService->parseObjectType($objectId);
}
}
switch ($objectType) {
case 'lead':
$this->logger->info('Processing lead');
/** @var Lead|null $lead */
$lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();
// Lead does not exist locally, import it.
if ($lead === null) {
$this->logger->info('Lead does not exist locally');
/** @var Lead $lead */
$lead = $crmService->syncLead($objectId);
}
$this->logger->info('Lead found', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
if ($stageId === null) {
$this->logger->info('Stage ID is null');
// If it was not provided, just assume it is the current stage.
$callStage = $lead->stage;
break;
}
$this->logger->info('Looking for stage');
// Determine if they have changed the stage.
/** @var Stage $stage */
$stage = $team->crm->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_LEAD)
->firstOrFail();
$this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);
if ($lead->stage_id && $lead->stage_id !== $stage->id) {
$this->logger->info('Stage has changed');
// Storage current stage on activity.
$callStage = $lead->stage;
// The stage has changed, update in remote CRM.
dispatch(new UpdateStage($activity, $lead, $callStage, $stage));
$this->logger->info(
sprintf(
'[%s] User changing lead stage from %s to %s',
$crmService->getDisplayName(),
$callStage->getName(),
$stage->getName()
),
[
'user' => $user->getUuid(),
'lead' => $lead->getUuid(),
]
);
} else {
$this->logger->info('Stage has not changed');
// Stage remains as current.
$callStage = $stage;
}
break;
case 'account':
$this->logger->info('Processing account');
// If the object is not a lead, it should be an account.
$account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();
// Account does not exist locally, import it.
if ($account === null) {
$this->logger->info('Account does not exist locally');
$account = $crmService->syncAccount($objectId);
}
$this->logger->info('Account found', ['accountId' => $account->id]);
break;
case 'contact':
$this->logger->info('processing contact');
$contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$this->logger->info('contact does not exist locally');
$contact = $crmService->syncContact($objectId);
}
$this->logger->info('resolving account');
$account = $this->resolveAccount($team, $contact, $crmService, $prospects);
break;
}
// If they have specified an opportunity, retrieve this with stage.
if ($opportunityId) {
$this->logger->info('opportunity id is set');
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if ($opportunity === null) {
$this->logger->info('opportunity does not exist locally');
$opportunity = $crmService->syncOpportunity($opportunityId);
}
if ($stageId === null) {
$this->logger->info('stage id is null');
// If it was not provided, just assume it is the current stage.
$callStage = $opportunity->stage ?? null;
} else {
$this->logger->info('looking for stage');
/** @var ?Stage $opportunityStage */
$opportunityStage = $team->crm
->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
// There is a chance we still cannot import this opportunity.
if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {
$this->logger->info('opportunity stage has changed');
// Storage current stage on activity.
$callStage = $opportunity->stage;
dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));
$this->logger->info(
sprintf(
'[%s] User changing opportunity stage from %s to %s',
$crmService->getDisplayName(),
$callStage->name,
$opportunityStage->name
),
[
'userId' => $user->id_string,
'opportunityId' => $opportunity->id_string,
]
);
} else {
$this->logger->info('opportunity stage has not changed');
// Stage remains as current.
$callStage = $opportunityStage;
}
}
}
if ($crmProviderId) {
// Cast $crmProviderId to string otherwise it won't use database index for some records
$linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();
// Check if this activity has already been assigned to a different activity.
if ($linkedActivity && $linkedActivity->id !== $activity->id) {
throw new InvalidArgumentException(
'Sorry, the linked task has already been logged under a different call. '
. 'Please choose another linked task.'
);
}
}
} catch (InvalidArgumentException $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($exception->getMessage());
} catch (Exception $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorInternalError(
'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'
);
}
}
if ($categoryId) {
$category = PlaybookCategory::uuid($categoryId);
if ($category->playbook->team_id !== $team->id) {
throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
$this->logger->info('Prospect data', [
'lead_id' => $lead?->getId(),
'account_id' => $account?->getId(),
'contact_id' => $contact?->getId(),
'opportunity_id' => $opportunity?->getId(),
'stage_id' => $stage?->getId(),
]);
if ($title) {
$activity->title = $title;
}
if ($summary) {
$activity->summary = $summary;
}
if ($crmProviderId) {
$activity->crm_provider_id = $crmProviderId;
}
if ($callStage) {
$this->logger->info('Setting stage id', ['stageId' => $callStage->id]);
$activity->stage_id = $callStage->id;
}
if ($lead) {
$this->logger->info('Setting lead id', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
// If we are changed from an account > lead, unset the account data.
$this->logger->info('Unsetting account id, opportunity id, contact id, value');
$activity->account_id = null;
$activity->opportunity_id = null;
$activity->contact_id = null;
$activity->value = null;
}
if ($account) {
$this->logger->info('Setting account id', ['accountId' => $account->id]);
$activity->account_id = $account->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('unsetting lead id');
$activity->lead_id = null;
// Unset the contact if switching different accounts. Will be set up below if still applicable.
if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {
$this->logger->info('Unsetting contact id');
$activity->contact_id = null;
}
}
if ($opportunity) {
$this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);
$this->logger->info('unsetting lead id');
$activity->opportunity_id = $opportunity->id;
$activity->value = $opportunity->value;
// If we are changed from an lead > account, unset the lead data.
$activity->lead_id = null;
}
if ($contact) {
$this->logger->info('setting contact id', ['contactId' => $contact->id]);
$activity->contact_id = $contact->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('Unsetting lead id');
$activity->lead_id = null;
}
$activity->is_internal = $isInternal;
$activity->save();
$activity->refresh();
$this->logger->notice('Activity saved', [
'activity_id' => $activity->getId(),
'lead_id' => $activity->lead_id,
'account_id' => $activity->account_id,
'contact_id' => $activity->contact_id,
'opportunity_id' => $activity->opportunity_id,
'stage_id' => $activity->stage_id,
'crm_provider_id' => $activity->getCrmProviderId(),
]);
// Store entities as field data on the activity.
$updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);
if ($activity->isLoggable()) {
// Follow-up Task or Event data.
$followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);
$this->logger->info('CRM LOG manual log triggered', [
'activityId' => $activity->getUuid(),
'followupData' => $followupData,
'userId' => $user->getUuid(),
]);
// Store data in the CRM.
// ++add check for crm_required
$job = new SaveActivity($activity, $followupData);
if ($updatedData) {
$job->delay(Carbon::now()->addMinutes($jobDelay));
}
dispatch($job);
// Manually dispatch log for Opportunity or Prospect added
if ($activity->hasOpportunity() || $activity->hasProspect()) {
event(new ActivityProspectAdded(
activity: $activity,
eventSource: 'manually-log-crm-data'
));
}
}
return $this->response->withOk();
}
/**
* Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.
*
* @param ServiceInterface $service
* @param Activity $activity
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array
{
$updatedData = [];
$existingData = $activity->data()->get();
// We need to delete any existing data to overwrite with latest values.
$activity->data()->delete();
$layoutEntities = $layout->entities()
->with('field', 'parent')
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->get();
/** @var LayoutEntity $entity */
foreach ($layoutEntities as $entity) {
// If the user has provided a value for this entity
if (array_key_exists($entity->id_string, $entities)) {
$value = $entities[$entity->id_string];
// Convert raw data into values that the CRM can consume.
if ($value) {
$value = $service->normalizeValue($entity->field->type, $value);
}
// Check the field is part of the activity-summary section.
if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {
// This is the internal database ID, not the external CRM ID.
$objectId = null;
switch ($entity->field->object_type) {
case Field::OBJECT_ACCOUNT:
$objectId = $activity->account_id;
break;
case Field::OBJECT_CONTACT:
$objectId = $activity->contact_id;
break;
case Field::OBJECT_OPPORTUNITY:
$objectId = $activity->opportunity_id;
break;
case Field::OBJECT_LEAD:
$objectId = $activity->lead_id;
break;
case Field::OBJECT_TASK:
case Field::OBJECT_EVENT:
$objectId = $activity->id;
break;
}
if ($objectId) {
/** @var FieldData $data */
$data = $activity->data()->create([
'crm_layout_entity_id' => $entity->id,
'crm_field_id' => $entity->crm_field_id,
'object_type' => $entity->field->object_type,
'object_id' => $objectId,
'value' => $value,
]);
// Never send read-only field data to the CRM.
if ($entity->read_only === false && $entity->is_visible) {
$existingValue = $existingData
->where('crm_layout_entity_id', $entity->id)
->where('crm_field_id', $entity->crm_field_id)
->where('object_type', $entity->field->object_type)
->where('object_id', $objectId)
->first();
// If the field was actually changed, we need to reflect this in the CRM too.
if ($existingValue === null || $existingValue->value !== $value) {
$updatedData[] = $data->id;
}
}
}
}
}
}
return $updatedData;
}
/**
* Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.
*
* @param ServiceInterface $crmService
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array
{
$fieldData = [];
foreach ($entities as $entityId => $value) {
// Only bother with fields that have a value.
if ($value) {
// Extract the entity from the UUID. Check the field is valid and part of the follow-up section.
$entity = $layout->entities()
->uuid($entityId, false)
->whereHas('parent', function ($query) {
$query->where('label', 'follow-up');
})
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->first();
if ($entity) {
// Convert raw data into values that the CRM can consume.
$value = $crmService->normalizeValue($entity->field->type, $value);
// Add the field and value to the payload.
$fieldData += [
$entity->field->crm_provider_id => $value,
];
}
}
}
return $fieldData;
}
/**
* @param Activity $activity
*/
private function validateSummary(Activity $activity): void
{
$team = $activity->user->team;
$crmProvider = $team->crm->provider;
$attributes = [];
$rules = [
'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,
'title' => 'string|max:250',
'prospects' => 'required|array',
'opportunity_id' => new CrmReference($crmProvider),
'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',
'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator
'summary' => 'max:50000',
'nId' => 'exists:notifications,id',
'crm_id' => new CrmReference($crmProvider),
'entities' => 'array',
'is_internal' => 'boolean',
];
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));
// Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.
$entities = $layout->entities()
->where('read_only', 0)
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->whereHas('parent', function ($query) use ($activity) {
if ($activity->isLoggable() === false) {
$query->where('label', '<>', 'follow-up');
}
});
$isInternal = $this->request->input('is_internal', false);
foreach ($entities->get() as $entity) {
$rules += $this->buildFieldValidator($entity, $isInternal);
$attributes += $this->buildFieldMessage($entity);
}
$this->request->validate($rules, [], $attributes);
}
private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array
{
return [
'entities.' . $entity->id_string => $entity->getValidator($isInternal),
];
}
/**
* @param LayoutEntity $entity
*
* @return array
*/
private function buildFieldMessage(LayoutEntity $entity): array
{
$label = $entity->label;
if ($label === null) {
$label = $entity->field->label;
}
return [
'entities.' . $entity->id_string => $label,
];
}
public function search(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->debugLog(
$user,
'User extracted from request',
['user' => $user->getId(), 'tz' => $user->getTimezone()]
);
$searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());
$this->debugLog(
$user,
'ActivitySearch criteria built',
['searchCriteria' => $searchCriteria]
);
$filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);
$this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);
$this->validateSearch($request, $filterSet);
$this->debugLog($user, 'Request validated');
$searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);
/** @var Collection<Activity> $activities */
$activities = $searchResponse['results'];
$this->debugLog($user, 'Activities ES response extracted');
$hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(
$user->getTeamId(),
TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),
);
if ($hideInternalMeetingsSetting?->getValue() === '1') {
$activities = $activities->filter(function (Activity $activity) {
if ($activity->is_internal && empty($activity->actual_start_time)) {
return false;
}
return true;
});
}
$this->debugLog($user, 'Internal meetings (?!) filtered');
$this->response->getManager()
->parseIncludes([
'category',
'organizer.group',
'prospect',
'stage',
'opportunity',
'stats',
'scorecards',
'masterTrack',
'activeParticipants',
'notification',
])
->setSerializer(new JsonSerializer());
$transformerExcludes = $this->request->input('exclude');
if ($transformerExcludes) {
$this->response->getManager()->parseExcludes($transformerExcludes);
}
$this->debugLog($user, 'Response Manager (?!) applied');
$transformer = new ActivityTransformer();
$transformer->setConsumer($user);
$this->debugLog($user, 'Activity Transformer added');
$resource = new \League\Fractal\Resource\Collection($activities, $transformer);
$page = $searchCriteria->getPageNumber();
$this->debugLog($user, 'Search criteria page number called', ['page' => $page]);
$histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');
$this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);
return $this->response->withArray([
'pagination' => [
'total' => $searchResponse['totalHits'],
'current' => $page,
'prev' => max($page - 1, 1),
'next' => $page + 1,
],
'results' => $this->response->getManager()->createData($resource)->toArray(),
'histogram' => $histogram,
]);
}
private function debugLog(User $user, string $logMessage, ?array $context = []): void
{
// Debug for Learning People Only
if ($user->getTeamId() !== 260) {
return;
}
Log::notice(
sprintf('[activity-search-controller] %s', $logMessage),
$context
);
}
/** @throws ValidationException */
private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void
{
$rules = [
'exclude' => 'array',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
];
if ($prefix !== null && mb_strpos($prefix, '.') !== false) {
$rules[rtrim($prefix, '.')] = sprintf(
'required|array|max:%d',
$filterSet->count()
);
}
$validationRules = $filterSet->getValidationRules($prefix)
->merge($rules)
->all();
$request->validate($validationRules);
}
public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$search = $this->updateOrCreateActivitySearch($request);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function updateActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('update', $search);
$this->updateOrCreateActivitySearch($request, $search);
return $this->response->withOk();
}
private function storeNamedSearchFilters(
Collection $request,
Search $search,
FilterDefinitionCollection $filterSet,
?string $prefix = null,
): self {
$arrayTypeProperties = $filterSet
->getPropertyTypes([
FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,
])
->all();
$supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);
foreach ($supportedRequestProperties as $requestPropertyName) {
if (! array_has($request, $requestPropertyName)) {
continue;
}
/** @var string|string[] $propertyValue */
$propertyValue = array_get($request, $requestPropertyName);
$propertyName = $prefix === null
? $requestPropertyName
: mb_substr($requestPropertyName, mb_strlen($prefix));
$isArrayType = array_has($arrayTypeProperties, $propertyName);
if (! $isArrayType) {
/** @var string $requestPropertyValue */
$search->filters()->updateOrCreate(
[
'filter' => $propertyName,
],
[
'value' => $propertyValue,
]
);
continue;
}
/** @var string[] $requestPropertyValue */
/** @var SearchFilter[]|Collection $existingFilterValues */
$existingFilterValuesKeyed = $search->filters()
->where('filter', $propertyName)
->get()
->keyBy('id');
// Iterate over values provided as request parameters
foreach ($propertyValue as $value) {
/** @var SearchFilter|null $valueFilter */
$valueFilter = $search->filters()
->where(
[
'filter' => $propertyName,
'value' => $value,
]
)
->first();
if ($valueFilter !== null) {
// Remove filter value pair from list to be deleted
$existingFilterValuesKeyed->forget($valueFilter->id);
} else {
// Add new filter/value pair
$search->filters()->updateOrCreate([
'filter' => $propertyName,
'value' => $value,
]);
}
}
// Delete filter value pairs for this filter that no longer exist in request parameters
foreach ($existingFilterValuesKeyed as $existingFilter) {
$existingFilter->delete();
}
}
/** @var Collection<int, SearchFilter> $filtersKeyed */
$filtersKeyed = $search->filters()->get()->keyBy('filter');
// wipe removed filters from this search
foreach ($filtersKeyed as $filterName => $filter) {
if (array_has($request, $prefix . $filterName)) {
continue;
}
// Remove all filter values for this filter
$search->filters()->where('filter', $filterName)->delete();
}
return $this;
}
/**
* @throws AuthorizationException
*/
public function fetchActivitySearch(
Search $search,
Request $request,
SearchTransformer $searchTransformer,
): JsonResponse {
$this->authorize('view', $search);
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withCollection(
$user->searches()->get(),
$searchTransformer
->withConsumer($user)
);
}
/**
* Deletes a saved search
*
* @param Request $request
* @param Search $search
*
* @throws Exception
*
* @return JsonResponse
*/
public function deleteActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('delete', $search);
// Orphan any AutomatedReports that use this search
$search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);
// Delete filters and the search itself
$search->filters()->delete();
$search->delete();
return $this->response->withOk();
}
public function live(Request $request, ElasticActivityRepository $repository): JsonResponse
{
$user = $this->getUserFromRequest($request);
$this->request->validate([
'sort_direction' => 'in:asc,desc',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
]);
$activities = $repository->getLiveCoachingEligibleActivities(
user: $user,
lookBackMinutes: self::LOOK_BACK,
limit: (int) $this->request->input('limit', 25),
page: (int) $this->request->input('page', 1),
sortBy: ['actual_start_time', 'scheduled_start_time'],
sortDirection: (string) $this->request->input('sort_direction', 'asc'),
);
$this->response
->getManager()
->parseIncludes(['organizer.group', 'prospect'])
->setSerializer(new JsonSerializer());
return $this->response->withCollection($activities, new ActivityTransformer());
}
/**
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function show(Activity $activity, ActivityService $activityService): JsonResponse
{
$this->authorize('show', $activity);
$user = $activity->getUser();
$team = $user->getTeam();
// Sync the opportunity with the latest data if possible.
if ($activity->opportunity_id) {
try {
$crmService = $this->providerRegistry->get($team->crm->provider);
if (! $user->isCrmRequired()) {
$crmService->setUser($team->getOwner());
} else {
$crmService->setUser($user);
}
$crmService->syncOpportunity($activity->opportunity->crm_provider_id);
} catch (Exception $exception) {
// Move on.
}
}
$activityData = $activityService->getActivityData($this->request->user(), $activity);
return response()->json($activityData);
}
public function createRecording(Activity $activity)
{
$this->authorize('record', $activity);
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Tell Twilio to start recording this activity.
if ($activity->recording_state === Activity::RECORDING_OFF) {
$job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withCreated();
}
return $this->response->errorGone('Activity is already recording.');
}
public function updateRecording(Request $request, Activity $activity)
{
$this->authorize('record', $activity);
$request->validate([
'preference' => 'boolean',
'state' => [
'string',
Rule::in([
Activity::RECORDING_IN_PROGRESS,
Activity::RECORDING_PAUSED,
]),
],
]);
if ($request->has('state')) {
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Toggle the recording state between paused and resumed.
if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {
$job = (new ToggleRecording($activity, $request->input('state')))
->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Recording is not toggleable.');
}
if ($request->has('preference')) {
$activity->update([
'recording_preference' => $request->input('preference') ? 1 : 0,
]);
return $this->response->withOk();
}
return $this->response->errorWrongArgs('Something went wrong');
}
public function stopRecording(Activity $activity)
{
$this->authorize('stopRecord', $activity);
// Tell Twilio to stop recording this activity.
if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {
$job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Activity is not recording.');
}
/**
* Add activity to this user's favorites playlist
*
* @throws AuthorizationException
*/
public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse
{
$this->authorize('favorite', $activity);
$user = $this->getUserFromRequest($this->request);
$favorite = $activity->wasFavoritedBy($user);
$name = $activity->activity_title ?? '';
// It needs to check at least one record.
if (! $favorite) {
$favoritePlaylist = $user->favoritePlaylist();
$playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(
$activity,
$user,
$favoritePlaylist
);
if ($playlistActivity !== null) {
$playlistActivity->update(
// Just update, don't sort.
['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],
);
} else {
$playlistActivity = $activity->playlistActivities()->create([
'playlist_id' => $favoritePlaylist->getId(),
'user_id' => $user->getId(),
'start_time' => 0,
'name' => mb_strimwidth($name, 0, 100),
]);
// Sort it on top.
$playlistActivity->update(
[
'sort' => $playlistActivityRepository->calculateNewSortOrder(
null,
$playlistActivity,
),
],
);
}
$playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);
return new JsonResponse([], JsonResponse::HTTP_CREATED);
}
return new JsonResponse(
[
'error' => [
'code' => AbstractResponse::CODE_CONFLICT,
'http_code' => JsonResponse::HTTP_CONFLICT,
'message' => 'Resource Already Exists',
],
],
JsonResponse::HTTP_CONFLICT,
);
}
/**
* Remove activity from this user's favorites playlist
*
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function unfavorite(Activity $activity)
{
$user = $t...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"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":"Analyzing…","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 Carbon\\Carbon;\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Exception;\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Validation\\Rule;\nuse Illuminate\\Validation\\Rules\\In;\nuse Illuminate\\Validation\\ValidationException;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ActivityAnalytics;\nuse Jiminny\\Component\\ActivitySearch;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Contracts\\ES\\Events\\UpdateSingleEntity;\nuse Jiminny\\Contracts\\ES\\UpdateTargetEnum;\nuse Jiminny\\Contracts\\Nudge\\NudgeFactoryInterface;\nuse Jiminny\\Contracts\\Playlist\\PlaylistTrackFactoryInterface;\nuse Jiminny\\Contracts\\Repositories\\PlaylistActivityRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Enums\\TeamSetting;\nuse Jiminny\\Events\\Activities\\AiAutomation\\ActivityProspectAdded;\nuse Jiminny\\Events\\Activities\\Coaching\\Coached;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Controllers\\CommentContextInterface;\nuse Jiminny\\Http\\Responses\\Api\\AbstractResponse;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\ActivityCommentTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTopicTriggerTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTransformer;\nuse Jiminny\\Http\\Transformers\\AvailabilityNotificationTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingFeedbackTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingSectionsTransformer;\nuse Jiminny\\Http\\Transformers\\SearchTransformer;\nuse Jiminny\\Http\\Transformers\\StatsTransformer;\nuse Jiminny\\Jobs\\Crm\\SaveActivity;\nuse Jiminny\\Jobs\\Crm\\UpdateStage;\nuse Jiminny\\Jobs\\Telephony\\StartRecording;\nuse Jiminny\\Jobs\\Telephony\\StopRecording;\nuse Jiminny\\Jobs\\Telephony\\ToggleRecording;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\CoachingFeedback;\nuse Jiminny\\Models\\CoachingSection;\nuse Jiminny\\Models\\CoachingSectionCriterion;\nuse Jiminny\\Models\\CoachingSectionFeedback;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\LanguageDialect;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Nudge;\nuse Jiminny\\Models\\PlaybookCategory;\nuse Jiminny\\Models\\Playlist;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\Track;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\CoachingFeedbackRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Rules\\MultidimensionalArrayMaxCharRule;\nuse Jiminny\\Services\\ActivityService;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Services\\PlaybackService;\nuse Jiminny\\Services\\UserService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\nuse Ramsey\\Uuid\\Uuid;\nuse Sentry;\nuse Symfony\\Component\\HttpFoundation;\n\nfinal class ActivityController extends Controller implements CommentContextInterface\n{\n // Number of minutes to look back on activities. i.e. a timeout on activity duration.\n private const int LOOK_BACK = 180;\n\n public function __construct(\n private ProviderRegistry $providerRegistry,\n private ActivityService $activityService,\n Response $response,\n private UserService $userService,\n private ActivitySearch\\Service\\ActivitySearch $activitySearch,\n private NudgeFactoryInterface $nudgeFactory,\n private ActivityCommentService $activityCommentService,\n private LoggerInterface $logger,\n private readonly CoachingFeedbackRepository $coachingFeedbackRepository,\n private readonly TeamRepository $teamRepository,\n ) {\n parent::__construct($response);\n }\n\n public static function getCommentImplementation(): string\n {\n return Comment::class;\n }\n\n public function delete()\n {\n $this->request->validate([\n '*' => 'uuid:activities',\n ]);\n\n $deletedIds = [];\n foreach ($this->request->all() as $activityId) {\n $activity = Activity::idOrUuId($activityId);\n\n try {\n if ($this->authorize('delete', $activity)) {\n $activity->delete();\n $deletedIds[] = $activityId;\n\n \\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n }\n } catch (AuthorizationException $authorizationException) {\n // They didn't have permission.\n }\n }\n\n return $this->response->withArray($deletedIds);\n }\n\n public function update(Request $request, Activity $activity)\n {\n $this->authorize('updateMetadata', $activity);\n\n $request->validate([\n 'title' => 'string|max:250',\n 'category_id' => 'uuid:playbook_categories',\n 'language' => [\n new In(\n LanguageDialect::query()\n ->with('language')\n ->cursor()\n ->map(static function (LanguageDialect $languageDialect): string {\n return $languageDialect->getLanguageLocale();\n })\n ->all()\n ),\n ],\n ]);\n\n if ($request->has('title')) {\n $activity->title = $request->input('title');\n }\n\n if ($request->has('category_id')) {\n $category = PlaybookCategory::uuid($request->input('category_id'));\n\n if ($category->playbook->team_id !== $request->user()->team_id) {\n return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n if ($request->has('language')) {\n if (! $activity->isInProgress()) {\n return $this->response->withError(\n 'Activity language can only be set while the meeting is in progress.',\n 400\n );\n }\n\n $activity->setLanguageCode($request->input('language'));\n }\n\n $activity->save();\n\n return $this->response->withOk();\n }\n\n // XXX: This should be merged with the update method.\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws SocialAccountTokenInvalidException\n *\n * @return mixed\n */\n public function summarize(Activity $activity): mixed\n {\n $this->logger->info('[Log Activity] Summarizing activity ', [\n 'activityId' => $activity->getUuid(),\n 'payload' => $this->request->all(),\n ]);\n $this->authorize('update', $activity);\n\n $this->logger->info('[Log Activity] Validating summary');\n // Validate the payload.\n $this->validateSummary($activity);\n\n // All objects must belong to this team.\n /** @var User $user */\n $user = $this->request->user();\n $team = $user->getTeam();\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n try {\n $crmUser = $user;\n if ($user->isCrmRequired() === false) {\n $crmUser = $team->owner;\n }\n $crmService->setUser($crmUser);\n } catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());\n }\n\n $rawEntities = $this->request->input('entities');\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid(\n $this->request->input('layout_id')\n );\n\n // Delay execution of CRM jobs to avoid locking issues.\n $jobDelay = 0;\n\n // If we have arrived from a notification, mark it as read.\n $notificationId = $this->request->input('nId');\n if ($notificationId) {\n $notification = $user->unreadNotifications->where('id', $notificationId)->first();\n\n if ($notification) {\n $notification->markAsRead();\n }\n }\n\n $title = $this->request->input('title');\n $prospects = $this->request->input('prospects');\n $opportunityId = $this->request->input('opportunity_id');\n $stageId = $this->request->input('stage_id');\n $categoryId = $this->request->input('category_id');\n $summary = $this->request->input('summary');\n $crmProviderId = $this->request->input('crm_id');\n $isInternal = $this->request->input('is_internal') ?? false;\n\n $lead = null;\n $category = null;\n $account = null;\n $contact = null;\n $opportunity = null;\n $stage = null;\n $callStage = null;\n\n foreach ($prospects as $prospectData) {\n $objectId = $prospectData['id'];\n\n if ($objectId === null) {\n continue;\n }\n\n $objectType = $prospectData['type'];\n $this->logger->info('debug', ['prospect_data' => $prospectData]);\n\n try {\n if ($objectType === null) {\n $this->logger->info('no object type');\n if ($crmService instanceof SupportsObjectTypeParseInterface) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n }\n\n switch ($objectType) {\n case 'lead':\n $this->logger->info('Processing lead');\n /** @var Lead|null $lead */\n $lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();\n\n // Lead does not exist locally, import it.\n if ($lead === null) {\n $this->logger->info('Lead does not exist locally');\n /** @var Lead $lead */\n $lead = $crmService->syncLead($objectId);\n }\n\n $this->logger->info('Lead found', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n if ($stageId === null) {\n $this->logger->info('Stage ID is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $lead->stage;\n\n break;\n }\n\n $this->logger->info('Looking for stage');\n // Determine if they have changed the stage.\n /** @var Stage $stage */\n $stage = $team->crm->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_LEAD)\n ->firstOrFail();\n\n $this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);\n if ($lead->stage_id && $lead->stage_id !== $stage->id) {\n $this->logger->info('Stage has changed');\n // Storage current stage on activity.\n $callStage = $lead->stage;\n\n // The stage has changed, update in remote CRM.\n dispatch(new UpdateStage($activity, $lead, $callStage, $stage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing lead stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->getName(),\n $stage->getName()\n ),\n [\n 'user' => $user->getUuid(),\n 'lead' => $lead->getUuid(),\n ]\n );\n } else {\n $this->logger->info('Stage has not changed');\n // Stage remains as current.\n $callStage = $stage;\n }\n\n break;\n\n case 'account':\n $this->logger->info('Processing account');\n // If the object is not a lead, it should be an account.\n $account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();\n\n // Account does not exist locally, import it.\n if ($account === null) {\n $this->logger->info('Account does not exist locally');\n $account = $crmService->syncAccount($objectId);\n }\n\n $this->logger->info('Account found', ['accountId' => $account->id]);\n\n break;\n case 'contact':\n $this->logger->info('processing contact');\n $contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $this->logger->info('contact does not exist locally');\n $contact = $crmService->syncContact($objectId);\n }\n\n $this->logger->info('resolving account');\n $account = $this->resolveAccount($team, $contact, $crmService, $prospects);\n\n break;\n }\n\n // If they have specified an opportunity, retrieve this with stage.\n if ($opportunityId) {\n $this->logger->info('opportunity id is set');\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if ($opportunity === null) {\n $this->logger->info('opportunity does not exist locally');\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n if ($stageId === null) {\n $this->logger->info('stage id is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $opportunity->stage ?? null;\n } else {\n $this->logger->info('looking for stage');\n /** @var ?Stage $opportunityStage */\n $opportunityStage = $team->crm\n ->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n // There is a chance we still cannot import this opportunity.\n if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {\n $this->logger->info('opportunity stage has changed');\n // Storage current stage on activity.\n $callStage = $opportunity->stage;\n\n dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing opportunity stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->name,\n $opportunityStage->name\n ),\n [\n 'userId' => $user->id_string,\n 'opportunityId' => $opportunity->id_string,\n ]\n );\n } else {\n $this->logger->info('opportunity stage has not changed');\n // Stage remains as current.\n $callStage = $opportunityStage;\n }\n }\n }\n\n if ($crmProviderId) {\n // Cast $crmProviderId to string otherwise it won't use database index for some records\n $linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();\n\n // Check if this activity has already been assigned to a different activity.\n if ($linkedActivity && $linkedActivity->id !== $activity->id) {\n throw new InvalidArgumentException(\n 'Sorry, the linked task has already been logged under a different call. '\n . 'Please choose another linked task.'\n );\n }\n }\n } catch (InvalidArgumentException $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($exception->getMessage());\n } catch (Exception $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorInternalError(\n 'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'\n );\n }\n }\n\n if ($categoryId) {\n $category = PlaybookCategory::uuid($categoryId);\n\n if ($category->playbook->team_id !== $team->id) {\n throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n $this->logger->info('Prospect data', [\n 'lead_id' => $lead?->getId(),\n 'account_id' => $account?->getId(),\n 'contact_id' => $contact?->getId(),\n 'opportunity_id' => $opportunity?->getId(),\n 'stage_id' => $stage?->getId(),\n ]);\n\n if ($title) {\n $activity->title = $title;\n }\n\n if ($summary) {\n $activity->summary = $summary;\n }\n\n if ($crmProviderId) {\n $activity->crm_provider_id = $crmProviderId;\n }\n\n if ($callStage) {\n $this->logger->info('Setting stage id', ['stageId' => $callStage->id]);\n $activity->stage_id = $callStage->id;\n }\n\n if ($lead) {\n $this->logger->info('Setting lead id', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n // If we are changed from an account > lead, unset the account data.\n $this->logger->info('Unsetting account id, opportunity id, contact id, value');\n $activity->account_id = null;\n $activity->opportunity_id = null;\n $activity->contact_id = null;\n $activity->value = null;\n }\n\n if ($account) {\n $this->logger->info('Setting account id', ['accountId' => $account->id]);\n $activity->account_id = $account->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('unsetting lead id');\n $activity->lead_id = null;\n\n // Unset the contact if switching different accounts. Will be set up below if still applicable.\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {\n $this->logger->info('Unsetting contact id');\n $activity->contact_id = null;\n }\n }\n\n if ($opportunity) {\n $this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);\n $this->logger->info('unsetting lead id');\n $activity->opportunity_id = $opportunity->id;\n $activity->value = $opportunity->value;\n\n // If we are changed from an lead > account, unset the lead data.\n $activity->lead_id = null;\n }\n\n if ($contact) {\n $this->logger->info('setting contact id', ['contactId' => $contact->id]);\n $activity->contact_id = $contact->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('Unsetting lead id');\n $activity->lead_id = null;\n }\n\n $activity->is_internal = $isInternal;\n $activity->save();\n $activity->refresh();\n\n $this->logger->notice('Activity saved', [\n 'activity_id' => $activity->getId(),\n 'lead_id' => $activity->lead_id,\n 'account_id' => $activity->account_id,\n 'contact_id' => $activity->contact_id,\n 'opportunity_id' => $activity->opportunity_id,\n 'stage_id' => $activity->stage_id,\n 'crm_provider_id' => $activity->getCrmProviderId(),\n ]);\n\n // Store entities as field data on the activity.\n $updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);\n\n if ($activity->isLoggable()) {\n // Follow-up Task or Event data.\n $followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);\n\n $this->logger->info('CRM LOG manual log triggered', [\n 'activityId' => $activity->getUuid(),\n 'followupData' => $followupData,\n 'userId' => $user->getUuid(),\n ]);\n\n // Store data in the CRM.\n // ++add check for crm_required\n $job = new SaveActivity($activity, $followupData);\n\n if ($updatedData) {\n $job->delay(Carbon::now()->addMinutes($jobDelay));\n }\n\n dispatch($job);\n\n // Manually dispatch log for Opportunity or Prospect added\n if ($activity->hasOpportunity() || $activity->hasProspect()) {\n event(new ActivityProspectAdded(\n activity: $activity,\n eventSource: 'manually-log-crm-data'\n ));\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.\n *\n * @param ServiceInterface $service\n * @param Activity $activity\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array\n {\n $updatedData = [];\n $existingData = $activity->data()->get();\n\n // We need to delete any existing data to overwrite with latest values.\n $activity->data()->delete();\n\n $layoutEntities = $layout->entities()\n ->with('field', 'parent')\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->get();\n\n /** @var LayoutEntity $entity */\n foreach ($layoutEntities as $entity) {\n // If the user has provided a value for this entity\n if (array_key_exists($entity->id_string, $entities)) {\n $value = $entities[$entity->id_string];\n\n // Convert raw data into values that the CRM can consume.\n if ($value) {\n $value = $service->normalizeValue($entity->field->type, $value);\n }\n\n // Check the field is part of the activity-summary section.\n if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {\n // This is the internal database ID, not the external CRM ID.\n $objectId = null;\n\n switch ($entity->field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $objectId = $activity->account_id;\n\n break;\n\n case Field::OBJECT_CONTACT:\n $objectId = $activity->contact_id;\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n $objectId = $activity->opportunity_id;\n\n break;\n\n case Field::OBJECT_LEAD:\n $objectId = $activity->lead_id;\n\n break;\n\n case Field::OBJECT_TASK:\n case Field::OBJECT_EVENT:\n $objectId = $activity->id;\n\n break;\n }\n\n if ($objectId) {\n /** @var FieldData $data */\n $data = $activity->data()->create([\n 'crm_layout_entity_id' => $entity->id,\n 'crm_field_id' => $entity->crm_field_id,\n 'object_type' => $entity->field->object_type,\n 'object_id' => $objectId,\n 'value' => $value,\n ]);\n\n // Never send read-only field data to the CRM.\n if ($entity->read_only === false && $entity->is_visible) {\n $existingValue = $existingData\n ->where('crm_layout_entity_id', $entity->id)\n ->where('crm_field_id', $entity->crm_field_id)\n ->where('object_type', $entity->field->object_type)\n ->where('object_id', $objectId)\n ->first();\n\n // If the field was actually changed, we need to reflect this in the CRM too.\n if ($existingValue === null || $existingValue->value !== $value) {\n $updatedData[] = $data->id;\n }\n }\n }\n }\n }\n }\n\n return $updatedData;\n }\n\n /**\n * Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.\n *\n * @param ServiceInterface $crmService\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array\n {\n $fieldData = [];\n foreach ($entities as $entityId => $value) {\n // Only bother with fields that have a value.\n if ($value) {\n // Extract the entity from the UUID. Check the field is valid and part of the follow-up section.\n $entity = $layout->entities()\n ->uuid($entityId, false)\n ->whereHas('parent', function ($query) {\n $query->where('label', 'follow-up');\n })\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->first();\n\n if ($entity) {\n // Convert raw data into values that the CRM can consume.\n $value = $crmService->normalizeValue($entity->field->type, $value);\n\n // Add the field and value to the payload.\n $fieldData += [\n $entity->field->crm_provider_id => $value,\n ];\n }\n }\n }\n\n return $fieldData;\n }\n\n /**\n * @param Activity $activity\n */\n private function validateSummary(Activity $activity): void\n {\n $team = $activity->user->team;\n $crmProvider = $team->crm->provider;\n $attributes = [];\n\n $rules = [\n 'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,\n 'title' => 'string|max:250',\n 'prospects' => 'required|array',\n 'opportunity_id' => new CrmReference($crmProvider),\n 'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',\n 'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator\n 'summary' => 'max:50000',\n 'nId' => 'exists:notifications,id',\n 'crm_id' => new CrmReference($crmProvider),\n 'entities' => 'array',\n 'is_internal' => 'boolean',\n ];\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));\n\n // Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.\n $entities = $layout->entities()\n ->where('read_only', 0)\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->whereHas('parent', function ($query) use ($activity) {\n if ($activity->isLoggable() === false) {\n $query->where('label', '<>', 'follow-up');\n }\n });\n\n $isInternal = $this->request->input('is_internal', false);\n\n foreach ($entities->get() as $entity) {\n $rules += $this->buildFieldValidator($entity, $isInternal);\n $attributes += $this->buildFieldMessage($entity);\n }\n\n $this->request->validate($rules, [], $attributes);\n }\n\n private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array\n {\n return [\n 'entities.' . $entity->id_string => $entity->getValidator($isInternal),\n ];\n }\n\n /**\n * @param LayoutEntity $entity\n *\n * @return array\n */\n private function buildFieldMessage(LayoutEntity $entity): array\n {\n $label = $entity->label;\n if ($label === null) {\n $label = $entity->field->label;\n }\n\n return [\n 'entities.' . $entity->id_string => $label,\n ];\n }\n\n public function search(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->debugLog(\n $user,\n 'User extracted from request',\n ['user' => $user->getId(), 'tz' => $user->getTimezone()]\n );\n\n $searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());\n\n $this->debugLog(\n $user,\n 'ActivitySearch criteria built',\n ['searchCriteria' => $searchCriteria]\n );\n\n $filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);\n\n $this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);\n\n $this->validateSearch($request, $filterSet);\n\n $this->debugLog($user, 'Request validated');\n\n $searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);\n\n /** @var Collection<Activity> $activities */\n $activities = $searchResponse['results'];\n\n $this->debugLog($user, 'Activities ES response extracted');\n\n $hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(\n $user->getTeamId(),\n TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),\n );\n\n if ($hideInternalMeetingsSetting?->getValue() === '1') {\n $activities = $activities->filter(function (Activity $activity) {\n if ($activity->is_internal && empty($activity->actual_start_time)) {\n return false;\n }\n\n return true;\n });\n }\n\n $this->debugLog($user, 'Internal meetings (?!) filtered');\n\n $this->response->getManager()\n ->parseIncludes([\n 'category',\n 'organizer.group',\n 'prospect',\n 'stage',\n 'opportunity',\n 'stats',\n 'scorecards',\n 'masterTrack',\n 'activeParticipants',\n 'notification',\n ])\n ->setSerializer(new JsonSerializer());\n\n $transformerExcludes = $this->request->input('exclude');\n if ($transformerExcludes) {\n $this->response->getManager()->parseExcludes($transformerExcludes);\n }\n\n $this->debugLog($user, 'Response Manager (?!) applied');\n\n $transformer = new ActivityTransformer();\n $transformer->setConsumer($user);\n\n $this->debugLog($user, 'Activity Transformer added');\n\n $resource = new \\League\\Fractal\\Resource\\Collection($activities, $transformer);\n $page = $searchCriteria->getPageNumber();\n\n $this->debugLog($user, 'Search criteria page number called', ['page' => $page]);\n\n $histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');\n\n $this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);\n\n return $this->response->withArray([\n 'pagination' => [\n 'total' => $searchResponse['totalHits'],\n 'current' => $page,\n 'prev' => max($page - 1, 1),\n 'next' => $page + 1,\n ],\n 'results' => $this->response->getManager()->createData($resource)->toArray(),\n 'histogram' => $histogram,\n ]);\n }\n\n private function debugLog(User $user, string $logMessage, ?array $context = []): void\n {\n // Debug for Learning People Only\n if ($user->getTeamId() !== 260) {\n return;\n }\n\n Log::notice(\n sprintf('[activity-search-controller] %s', $logMessage),\n $context\n );\n }\n\n /** @throws ValidationException */\n private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void\n {\n $rules = [\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ];\n\n if ($prefix !== null && mb_strpos($prefix, '.') !== false) {\n $rules[rtrim($prefix, '.')] = sprintf(\n 'required|array|max:%d',\n $filterSet->count()\n );\n }\n\n $validationRules = $filterSet->getValidationRules($prefix)\n ->merge($rules)\n ->all();\n\n $request->validate($validationRules);\n }\n\n public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $search = $this->updateOrCreateActivitySearch($request);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function updateActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('update', $search);\n\n $this->updateOrCreateActivitySearch($request, $search);\n\n return $this->response->withOk();\n }\n\n private function storeNamedSearchFilters(\n Collection $request,\n Search $search,\n FilterDefinitionCollection $filterSet,\n ?string $prefix = null,\n ): self {\n $arrayTypeProperties = $filterSet\n ->getPropertyTypes([\n FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,\n ])\n ->all();\n\n $supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);\n\n foreach ($supportedRequestProperties as $requestPropertyName) {\n if (! array_has($request, $requestPropertyName)) {\n continue;\n }\n\n /** @var string|string[] $propertyValue */\n $propertyValue = array_get($request, $requestPropertyName);\n $propertyName = $prefix === null\n ? $requestPropertyName\n : mb_substr($requestPropertyName, mb_strlen($prefix));\n\n $isArrayType = array_has($arrayTypeProperties, $propertyName);\n\n if (! $isArrayType) {\n /** @var string $requestPropertyValue */\n\n $search->filters()->updateOrCreate(\n [\n 'filter' => $propertyName,\n ],\n [\n 'value' => $propertyValue,\n ]\n );\n\n continue;\n }\n\n /** @var string[] $requestPropertyValue */\n\n /** @var SearchFilter[]|Collection $existingFilterValues */\n $existingFilterValuesKeyed = $search->filters()\n ->where('filter', $propertyName)\n ->get()\n ->keyBy('id');\n\n // Iterate over values provided as request parameters\n foreach ($propertyValue as $value) {\n /** @var SearchFilter|null $valueFilter */\n $valueFilter = $search->filters()\n ->where(\n [\n 'filter' => $propertyName,\n 'value' => $value,\n ]\n )\n ->first();\n\n if ($valueFilter !== null) {\n // Remove filter value pair from list to be deleted\n $existingFilterValuesKeyed->forget($valueFilter->id);\n } else {\n // Add new filter/value pair\n $search->filters()->updateOrCreate([\n 'filter' => $propertyName,\n 'value' => $value,\n ]);\n }\n }\n\n // Delete filter value pairs for this filter that no longer exist in request parameters\n foreach ($existingFilterValuesKeyed as $existingFilter) {\n $existingFilter->delete();\n }\n }\n\n /** @var Collection<int, SearchFilter> $filtersKeyed */\n $filtersKeyed = $search->filters()->get()->keyBy('filter');\n\n // wipe removed filters from this search\n foreach ($filtersKeyed as $filterName => $filter) {\n if (array_has($request, $prefix . $filterName)) {\n continue;\n }\n\n // Remove all filter values for this filter\n $search->filters()->where('filter', $filterName)->delete();\n }\n\n return $this;\n }\n\n /**\n * @throws AuthorizationException\n */\n public function fetchActivitySearch(\n Search $search,\n Request $request,\n SearchTransformer $searchTransformer,\n ): JsonResponse {\n $this->authorize('view', $search);\n\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection(\n $user->searches()->get(),\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n /**\n * Deletes a saved search\n *\n * @param Request $request\n * @param Search $search\n *\n * @throws Exception\n *\n * @return JsonResponse\n */\n public function deleteActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('delete', $search);\n\n // Orphan any AutomatedReports that use this search\n $search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);\n\n // Delete filters and the search itself\n $search->filters()->delete();\n $search->delete();\n\n return $this->response->withOk();\n }\n\n public function live(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n $user = $this->getUserFromRequest($request);\n\n $this->request->validate([\n 'sort_direction' => 'in:asc,desc',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ]);\n\n $activities = $repository->getLiveCoachingEligibleActivities(\n user: $user,\n lookBackMinutes: self::LOOK_BACK,\n limit: (int) $this->request->input('limit', 25),\n page: (int) $this->request->input('page', 1),\n sortBy: ['actual_start_time', 'scheduled_start_time'],\n sortDirection: (string) $this->request->input('sort_direction', 'asc'),\n );\n\n $this->response\n ->getManager()\n ->parseIncludes(['organizer.group', 'prospect'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($activities, new ActivityTransformer());\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function show(Activity $activity, ActivityService $activityService): JsonResponse\n {\n $this->authorize('show', $activity);\n\n $user = $activity->getUser();\n $team = $user->getTeam();\n\n // Sync the opportunity with the latest data if possible.\n if ($activity->opportunity_id) {\n try {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n if (! $user->isCrmRequired()) {\n $crmService->setUser($team->getOwner());\n } else {\n $crmService->setUser($user);\n }\n\n $crmService->syncOpportunity($activity->opportunity->crm_provider_id);\n } catch (Exception $exception) {\n // Move on.\n }\n }\n\n $activityData = $activityService->getActivityData($this->request->user(), $activity);\n\n return response()->json($activityData);\n }\n\n public function createRecording(Activity $activity)\n {\n $this->authorize('record', $activity);\n\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Tell Twilio to start recording this activity.\n if ($activity->recording_state === Activity::RECORDING_OFF) {\n $job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withCreated();\n }\n\n return $this->response->errorGone('Activity is already recording.');\n }\n\n public function updateRecording(Request $request, Activity $activity)\n {\n $this->authorize('record', $activity);\n\n $request->validate([\n 'preference' => 'boolean',\n 'state' => [\n 'string',\n Rule::in([\n Activity::RECORDING_IN_PROGRESS,\n Activity::RECORDING_PAUSED,\n ]),\n ],\n ]);\n\n if ($request->has('state')) {\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Toggle the recording state between paused and resumed.\n if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {\n $job = (new ToggleRecording($activity, $request->input('state')))\n ->onQueue(Constants::QUEUE_CONFERENCES);\n\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Recording is not toggleable.');\n }\n\n if ($request->has('preference')) {\n $activity->update([\n 'recording_preference' => $request->input('preference') ? 1 : 0,\n ]);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorWrongArgs('Something went wrong');\n }\n\n public function stopRecording(Activity $activity)\n {\n $this->authorize('stopRecord', $activity);\n\n // Tell Twilio to stop recording this activity.\n if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {\n $job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Activity is not recording.');\n }\n\n /**\n * Add activity to this user's favorites playlist\n *\n * @throws AuthorizationException\n */\n public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse\n {\n $this->authorize('favorite', $activity);\n\n $user = $this->getUserFromRequest($this->request);\n $favorite = $activity->wasFavoritedBy($user);\n $name = $activity->activity_title ?? '';\n\n // It needs to check at least one record.\n if (! $favorite) {\n $favoritePlaylist = $user->favoritePlaylist();\n\n $playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(\n $activity,\n $user,\n $favoritePlaylist\n );\n\n if ($playlistActivity !== null) {\n $playlistActivity->update(\n // Just update, don't sort.\n ['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],\n );\n } else {\n $playlistActivity = $activity->playlistActivities()->create([\n 'playlist_id' => $favoritePlaylist->getId(),\n 'user_id' => $user->getId(),\n 'start_time' => 0,\n 'name' => mb_strimwidth($name, 0, 100),\n ]);\n // Sort it on top.\n $playlistActivity->update(\n [\n 'sort' => $playlistActivityRepository->calculateNewSortOrder(\n null,\n $playlistActivity,\n ),\n ],\n );\n }\n\n $playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);\n\n return new JsonResponse([], JsonResponse::HTTP_CREATED);\n }\n\n return new JsonResponse(\n [\n 'error' => [\n 'code' => AbstractResponse::CODE_CONFLICT,\n 'http_code' => JsonResponse::HTTP_CONFLICT,\n 'message' => 'Resource Already Exists',\n ],\n ],\n JsonResponse::HTTP_CONFLICT,\n );\n }\n\n /**\n * Remove activity from this user's favorites playlist\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unfavorite(Activity $activity)\n {\n $user = $this->request->user();\n\n $favorites = $activity->favoritedBy($user);\n\n if ($favorites && $favorites->isEmpty()) {\n return $this->response->errorNotFound('Favorite not found.');\n }\n\n $this->authorize('unfavorite', [$activity, $favorites]);\n\n // When you unfavorite an activity,\n // it should remove all the activities in it, including snippets.\n $isDeleted = $favorites->each(function ($favorite) {\n $favorite->forceDelete();\n });\n\n if ($isDeleted) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not remove favorite.');\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function notify(Activity $activity)\n {\n $this->authorize('notify', $activity);\n\n $user = $this->request->user();\n\n $existingNotification = $activity->availabilityNotifications()\n ->where('user_id', $user->id)\n ->exists();\n\n if ($existingNotification) {\n return $this->response->errorWrongArgs('Notification is already configured.');\n }\n\n $notification = Activity\\AvailabilityNotification::create([\n 'user_id' => $user->id,\n 'activity_id' => $activity->id,\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($notification, new AvailabilityNotificationTransformer());\n }\n\n /**\n * @param Activity $activity\n * @param Activity\\AvailabilityNotification $notification\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unnotify(Activity $activity, Activity\\AvailabilityNotification $notification)\n {\n $this->authorize('unnotify', [$activity, $notification]);\n\n if ($notification->sent_at || $notification->delete()) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not delete notification.');\n }\n\n public function play(Request $request, Activity $activity)\n {\n $this->authorize('stream', $activity);\n\n $request->validate([\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $activity->plays()->create([\n 'user_id' => $user->getId(),\n 'start_time' => $request->input('start_time'),\n ]);\n\n return $this->response->withCreated();\n }\n\n /**\n * @param Activity $activity\n *\n * @return mixed\n */\n public function comment(Activity $activity)\n {\n return $this->newComment($activity);\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @return mixed\n */\n public function replyComment(Activity $activity, Comment $comment)\n {\n return $this->newComment($activity, $comment);\n }\n\n /**\n * @param Activity $activity\n * @param Comment|null $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n protected function newComment(Activity $activity, ?Comment $comment = null)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n 'type' => 'integer|between:0,3',\n 'visibility' => sprintf('nullable|integer|between:1,%d', count(Comment::getVisibilityLevels())),\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n $threadStartId = null;\n if ($comment) {\n $threadStartId = $comment->thread_start_id ?: $comment->id;\n }\n\n try {\n $newComment = Comment::create([\n 'parent_comment_id' => $comment->id ?? null,\n 'thread_start_id' => $threadStartId,\n 'activity_id' => $activity->id,\n 'user_id' => $this->request->user()->id,\n 'comment' => trim($this->request->input('comment')),\n 'start_time' => $this->request->input('start_time', 0),\n 'end_time' => $this->request->input('end_time', 0),\n 'type' => $this->request->input('type', Comment::TYPE_NEUTRAL),\n 'visibility' => $this->request->input('visibility', Comment::VISIBILITY_PUBLIC),\n ]);\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($newComment, new ActivityCommentTransformer());\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not create comment.' . $exception->getMessage());\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function updateComment(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n try {\n $comment->update([\n 'comment' => trim($this->request->input('comment')),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment.');\n }\n }\n\n public function updateCommentVisibility(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'visibility' => sprintf('integer|between:1,%d', count(Comment::getVisibilityLevels())),\n ]);\n\n $visibility = $this->request->input('visibility');\n\n if ($comment->parent !== null) {\n return $this->response->errorWrongArgs('Comment visibility can only be updated on top level comments.');\n }\n\n try {\n $this->activityCommentService->updateCommentVisibility($comment, $visibility);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment\\'s visibility.');\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function deleteComment(Activity $activity, Comment $comment)\n {\n $this->authorize('deleteComment', [$activity, $comment]);\n\n // Delete comment and any children.\n $comment->delete();\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function fetchComments()\n {\n $user = $this->request->user();\n $this->request->validate([\n 'forUserId' => 'uuid:users,team_id,' . $user->team_id,\n 'types' => 'array',\n 'types.*' => 'integer|between:0,3',\n ]);\n $forUser = null;\n\n $types = [Comment::TYPE_NEUTRAL, Comment::TYPE_GAME_CHANGER, Comment::TYPE_POSITIVE];\n $user = $this->request->user();\n if ($this->request->has('forUserId')) {\n $forUser = $user->team->users()->uuid($this->request->input('forUserId'));\n }\n\n $comments = Comment::query()\n ->whereHas('activity', static function (Builder $builder) use ($user, $forUser): void {\n $builder\n // I left feedback on my own activity; or\n ->where('activities.user_id', $user->getId());\n if ($forUser) {\n // I left feedback on any activity for this user.\n $builder->orWhere([\n 'user_id' => $user->getId(),\n 'activities.user_id' => $forUser->getId(),\n ]);\n }\n })\n ->whereIn('type', $this->request->input('types', $types))\n ->orderBy('created_at', 'desc')\n ->get();\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity', 'user'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($comments, new ActivityCommentTransformer());\n }\n\n public function deleteCoachingFeedback(Activity $activity, CoachingFeedback $coachingFeedback)\n {\n $this->authorize('deleteCoachingFeedback', [$activity, $coachingFeedback]);\n $activity = $coachingFeedback->getActivity();\n\n if ($coachingFeedback->delete()) {\n event(new UpdateSingleEntity(\n entityId: $activity->getId(),\n updateTarget: UpdateTargetEnum::ACTIVITY,\n purpose: 'delete-coaching-feedback',\n ));\n\n return $this->response->withOk();\n }\n\n return $this->response->withError('Delete operation failed. Contact support.', 500);\n }\n\n /**\n * Add new or update Coaching feedback\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws \\Illuminate\\Validation\\ValidationException\n *\n * @return mixed\n */\n public function putCoachingFeedback(Request $request, Activity $activity)\n {\n $user = $request->user();\n\n if (! $user instanceof User) {\n abort(403);\n }\n $teamId = $user->getTeamId();\n\n $this->authorize('coach', $activity);\n\n $this->request->validate([\n 'coach_id' => 'required|uuid:users,team_id,' . $teamId,\n 'coachee_id' => 'required|uuid:users,team_id,' . $teamId,\n 'visibility' => ['required', Rule::in(CoachingFeedback::VISIBILITIES)],\n 'coaching_sections.*.uuid' => 'required|uuid:coaching_sections',\n 'coaching_sections.*.score' => ['required', Rule::in(CoachingSectionFeedback::SCORES)],\n 'coaching_sections.*.summary' => 'string|max:10000',\n 'coaching_sections.*.criteria.*.uuid' => 'required|uuid:coaching_section_criteria',\n 'coaching_sections.*.criteria.*.note' => 'required|string|max:10000',\n 'sharedWithUsers' => [\n 'required_if:visibility,' . CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS,\n 'array',\n ],\n 'sharedWithUsers.*' => [\n 'uuid:users,team_id,' . $teamId,\n ],\n ]);\n\n /** @var User $coach */\n $coach = User::uuid($this->request->input('coach_id'));\n /** @var User $coachee */\n $coachee = User::uuid($this->request->input('coachee_id'));\n $coachingSectionFeedbacks = $this->request->input('coaching_sections');\n\n $previousRecord = $this->coachingFeedbackRepository->getOneForActivityByCoacheeAndCoach(\n $coachee->getId(),\n $coach->getId(),\n $activity->getId()\n );\n $recordIsNew = false;\n if ($previousRecord === null) {\n $recordIsNew = true;\n }\n\n if (! $coachee->isSameTeamId($coach)) {\n return $this->response->errorForbidden('User not member of your team.');\n }\n\n if (! is_array($coachingSectionFeedbacks) || count($coachingSectionFeedbacks) < 1) {\n return $this->response->withError('At least one Coaching Framework Section shall be scored.', 422);\n }\n\n if (! $activity->participants()->where('participants.user_id', $coachee->id)->exists()) {\n return $this->response->withError('Coached user did not participate activity.', 422);\n }\n\n $visibility = $this->request->input('visibility');\n\n $shouldSendNotification = $recordIsNew;\n if ($recordIsNew === false && $visibility !== $previousRecord->getVisibility()) {\n $shouldSendNotification = true;\n }\n\n /**\n * Create CoachingFeedback\n *\n * @var CoachingFeedback $coachingFeedback\n */\n $coachingFeedback = $activity->coachingFeedbacks()->updateOrCreate(\n [\n 'coach_id' => $coach->id,\n 'coachee_id' => $coachee->id,\n ],\n [\n 'framework_id' => $activity->category->id,\n 'visibility' => $visibility,\n ]\n );\n\n $sharedUserIds = [];\n if ($visibility === CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS) {\n foreach ($this->request->input('sharedWithUsers') as $sharedWithUserUuid) {\n /** @var User $user */\n $user = User::uuid($sharedWithUserUuid);\n $sharedUserIds[] = $user->getId();\n }\n }\n\n $syncResult = $coachingFeedback->customAccessUsers()->sync($sharedUserIds);\n\n $scores = [];\n\n\n /**\n * Create CoachingSectionsFeedbacks.\n *\n * @var CoachingSectionFeedback $coachingSectionFeedback\n */\n foreach ($coachingSectionFeedbacks as $coachingSectionFeedbackInput) {\n $coachingSection = CoachingSection::uuid($coachingSectionFeedbackInput['uuid']);\n $coachingSectionFeedback = $coachingFeedback->sectionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_id' => $coachingSection->id,\n ],\n [\n 'score' => array_get($coachingSectionFeedbackInput, 'score'),\n 'summary' => array_get($coachingSectionFeedbackInput, 'summary') ?? '',\n ]\n );\n\n $scores[] = array_get($coachingSectionFeedbackInput, 'score');\n\n $criteria = array_get($coachingSectionFeedbackInput, 'criteria');\n if (is_array($criteria) && ! empty($criteria)) {\n foreach ($criteria as $criteriaFeedbackInput) {\n $coachingSectionFeedback->criterionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_criterion_id' => CoachingSectionCriterion::uuid(array_get($criteriaFeedbackInput, 'uuid'))\n ->id,\n ],\n ['note' => array_get($criteriaFeedbackInput, 'note')],\n );\n }\n }\n }\n\n $coachingFeedback->average_score = array_sum($scores) / count($scores);\n\n if ($recordIsNew === false && $coachingFeedback->getAverageScore() !== $previousRecord->getAverageScore()) {\n $shouldSendNotification = true;\n }\n if (! empty($syncResult['attached']) || ! empty($syncResult['detached']) || ! empty($syncResult['updated'])) {\n $shouldSendNotification = true;\n }\n\n $coachingFeedback->save();\n // ensure updated at for coaching feedback on section feedback summary added.\n $coachingFeedback->touch();\n\n if ($shouldSendNotification) {\n event(new Coached($coachingFeedback));\n }\n\n Datadog::increment('jiminny.activity.score.update', 1, ['company' => $activity->user->team->slug]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n $coachingFeedbackTransformer = new CoachingFeedbackTransformer();\n $coachingFeedbackTransformer->setConsumer($this->getUserFromRequest($request));\n\n return $this->response->withItem($coachingFeedback, $coachingFeedbackTransformer);\n }\n\n\n /**\n * Retrieve category criteria for coaching.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachingSections(Activity $activity)\n {\n $this->authorize('coach', $activity);\n\n if ($activity->category === null) {\n return $this->response->errorUnprocessable('Category has not yet been assigned.');\n }\n\n $criteria = $activity\n ->category\n ->coachingSections()\n ->where('is_enabled', 1)\n ->orderBy('sequence', 'asc');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($criteria->get(), new CoachingSectionsTransformer());\n }\n\n /**\n * @throws AuthorizationException\n * @throws ValidationException\n *\n * @return mixed\n */\n public function addToPlaylist(Activity $activity, PlaylistTrackFactoryInterface $playlistTrackFactory)\n {\n $this->request->validate([\n 'playlists' => 'required|array',\n 'playlists.*' => 'uuid:playlists',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'name' => 'required|max:100',\n ]);\n\n $this->authorize('addToPlaylist', [$activity, $this->request->input('playlists')]);\n\n $startTime = $this->request->input('start_time');\n $endTime = $this->request->input('end_time');\n $name = $this->request->input('name');\n /** @var User $user */\n $user = $this->request->user();\n\n // Get playlist by uuid.\n foreach ($this->request->input('playlists') as $playlistId) {\n // Pull out the playlist model.\n $playlist = Playlist::uuid($playlistId);\n\n $playlistTrackFactory->createTrack($playlist, $user, [\n 'name' => $name,\n 'activity' => $activity,\n 'start_time' => $startTime,\n 'end_time' => $endTime,\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function share(Request $request, Activity $activity): JsonResponse\n {\n $this->authorize('share', $activity);\n\n $request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'recipients.*.type' => 'in:user,group',\n 'recipients.*.id' => 'string|max:40',\n 'share' => 'string|max:255',\n ]);\n\n $user = $request->user();\n\n $recipients = $request->get('recipients');\n $users = $this->userService->convertRecipientsToUsers($user, $recipients);\n\n $shareData = [\n 'from_user_id' => $user->id,\n 'note' => $request->input('note'),\n 'start_time' => $request->input('start_time'),\n 'end_time' => $request->input('end_time'),\n ];\n\n // Create a share object against a notification provider channel\n if ($request->input('share')) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'notification_provider_channel' => $request->input('share'),\n ]\n )\n );\n\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n\n // Create a share object against each recipient\n foreach ($users as $recipient) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'to_user_id' => $recipient->id,\n ]\n )\n );\n\n // If parent_share_id has been selected yet\n if (! isset($shareData['parent_share_id'])) {\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachRequest(Activity $activity)\n {\n $this->authorize('coachRequest', $activity);\n\n $this->request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'coachers.*.type' => 'required|in:user',\n 'coachers.*.id' => 'required',\n ]);\n\n $coachers = $this->request->get('coachers');\n $user = $this->request->user();\n $users = $this->userService->convertRecipientsToUsers($user, $coachers);\n\n foreach ($users as $coacher) {\n CoachRequest::create([\n 'user_id' => $coacher->id,\n 'activity_id' => $activity->id,\n 'note' => $this->request->get('note'),\n 'start_time' => $this->request->get('start_time'),\n 'end_time' => $this->request->get('end_time'),\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function createActivityTopicTriggers(Activity $activity, LoggerInterface $logger): HttpFoundation\\JsonResponse\n {\n $this->authorize('analyzeTopicTriggers', $activity);\n\n if (! $activity->hasTranscription()) {\n return new HttpFoundation\\JsonResponse(\n [\n 'error' => 'Transcription not found.',\n ],\n JsonResponse::HTTP_NOT_FOUND\n );\n }\n\n $logger->info(__METHOD__ . ': queued for analysis', [\n 'activity' => $activity->id_string,\n ]);\n\n dispatch(new ActivityAnalytics\\Job\\AnalyzeActivityTopicTriggers($activity));\n\n return new HttpFoundation\\JsonResponse(null, JsonResponse::HTTP_CREATED);\n }\n\n public function fetchActivityTopicTriggers(\n Activity $activity,\n LoggerInterface $logger,\n ActivityTopicTriggerTransformer $transformer\n ): HttpFoundation\\JsonResponse {\n $this->authorize('fetchTopicTriggers', $activity);\n\n $logger->debug(__METHOD__, [\n 'activity' => $activity->id_string,\n ]);\n\n if (! $activity->isProcessed()) {\n return new HttpFoundation\\JsonResponse([]);\n }\n\n $payload = [];\n\n if ($activity->hasTopicTriggers()) {\n $payload = $activity->getTopicTriggersSorted()\n ->map(\n static fn (Activity\\TopicTrigger $activityTopicTrigger): array\n => $transformer->transform($activityTopicTrigger)\n )\n ->values()\n ->all();\n }\n\n return new HttpFoundation\\JsonResponse($payload);\n }\n\n /**\n * @param Activity $activity\n * @param StatsTransformer $statsTransformer\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function stats(Activity $activity, StatsTransformer $statsTransformer)\n {\n $this->authorize('stream', $activity);\n\n if (! $activity->hasTranscription()) {\n return $this->response->errorNotFound('Waveform data is not yet generated.');\n }\n\n $this->response\n ->getManager()\n ->parseIncludes(['wavedata'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($activity, $statsTransformer);\n }\n\n public function destroy(Activity $activity)\n {\n $this->authorize('delete', $activity);\n\n $activity->delete();\n\n \\Log::info('Soft delete activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n\n return $this->response->withNoContent();\n }\n\n public function note(Activity $activity)\n {\n $this->authorize('note', $activity);\n\n $this->request->validate([\n 'note' => 'required|min:1|max:2000',\n 'time' => 'required|numeric|min:0|max:86400',\n ]);\n\n $note = $this->request->input('note');\n $time = $this->request->input('time');\n\n $this->activityService->setActivity($activity);\n $this->activityService->takeNote($this->getUser(), $note, $time);\n\n return $this->response->withCreated();\n }\n\n /**\n * Mark an activity as private.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPrivate(Activity $activity)\n {\n $this->authorize('markAsPrivate', $activity);\n\n if ($activity->is_private === false) {\n $activity->is_private = true;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * Mark an activity as public.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPublic(Activity $activity)\n {\n $this->authorize('markAsPublic', $activity);\n\n if ($activity->is_private) {\n $activity->is_private = false;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws LogicException\n */\n public function fetchCloudFrontS3MediaKeys(Activity $activity, PlaybackService $playbackService): JsonResponse\n {\n $masterTrack = $activity->masterTrack()->first();\n\n if (! $masterTrack instanceof Track) {\n throw new LogicException(sprintf('Master track not found for activity \"%s\"', $activity->getUuid()));\n }\n\n return $this->response->withArray(\n $playbackService->generateCookies(\n $masterTrack,\n $this->request->ip(),\n ),\n );\n }\n\n /**\n * @throws ValidationException\n */\n private function updateOrCreateActivitySearch(Request $request, ?Search $search = null): Search\n {\n $request->validate([\n 'name' => 'required|string|min:2|max:100',\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $searchName = $request->input('name');\n\n if ($search !== null) {\n $search->update([\n 'name' => $searchName,\n ]);\n\n return $search;\n }\n\n $request->validate([\n 'filters' => ['required', 'array', new MultidimensionalArrayMaxCharRule(limit: 255)],\n 'nudges' => 'array|max:' . count(Nudge::MAP_CHANNEL),\n 'nudges.*.channel' => 'required|in:' . implode(',', Nudge::MAP_CHANNEL),\n 'nudges.*.frequency' => 'required|in:' . implode(',', Nudge::MAP_FREQUENCY),\n 'nudges.*.expiresAt' => [\n 'required',\n 'date',\n 'after:today',\n 'before_or_equal:' . now()->addYear()->format('Y-m-d'),\n ],\n ]);\n\n $searchCriteria = Criteria::createFromRequest(\n Collection::make($request->input('filters', []))->all(),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($searchCriteria, $user);\n $this->validateSearch($request, $filterSet, 'filters.');\n\n /** @var Search $search */\n $search = Search::create([\n 'name' => $searchName,\n 'uuid' => Uuid::uuid4()->toString(),\n 'user_id' => $user->getId(),\n ]);\n\n Collection::make($request->input('nudges', []))\n ->each(fn (array $attributes): Nudge => $this->nudgeFactory->createNudge($search, $attributes));\n\n $this->storeNamedSearchFilters(Collection::make($request->all()), $search, $filterSet, 'filters.');\n\n return $search;\n }\n\n private function resolveAccount(\n Team $team,\n Contact $contact,\n ServiceInterface $crmService,\n array $prospects,\n ): ?Account {\n $this->logger->info('Resolving account from contact');\n $account = $contact->getAccount();\n\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS)) {\n $this->logger->info('Team does not have feature to link activity to multiple prospects');\n\n return $account;\n }\n\n $this->logger->info('Resolving account from prospect data');\n $accountData = array_filter(\n $prospects,\n static fn (array $prospectData): bool => $prospectData['type'] === 'account'\n );\n\n if (! empty($accountData)) {\n $this->logger->info('Found account data in prospects');\n $accountData = reset($accountData);\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountData['id'])->first();\n\n if (! $account instanceof Account) {\n $this->logger->info('Account not found in database, syncing from CRM');\n $account = $crmService->syncAccount($accountData['id']);\n }\n }\n\n $this->logger->info('Resolved account', ['account' => $account->getId()]);\n\n return $account;\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Http\\Controllers\\API;\n\nuse Carbon\\Carbon;\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Exception;\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Validation\\Rule;\nuse Illuminate\\Validation\\Rules\\In;\nuse Illuminate\\Validation\\ValidationException;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ActivityAnalytics;\nuse Jiminny\\Component\\ActivitySearch;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Contracts\\ES\\Events\\UpdateSingleEntity;\nuse Jiminny\\Contracts\\ES\\UpdateTargetEnum;\nuse Jiminny\\Contracts\\Nudge\\NudgeFactoryInterface;\nuse Jiminny\\Contracts\\Playlist\\PlaylistTrackFactoryInterface;\nuse Jiminny\\Contracts\\Repositories\\PlaylistActivityRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Enums\\TeamSetting;\nuse Jiminny\\Events\\Activities\\AiAutomation\\ActivityProspectAdded;\nuse Jiminny\\Events\\Activities\\Coaching\\Coached;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Controllers\\CommentContextInterface;\nuse Jiminny\\Http\\Responses\\Api\\AbstractResponse;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\ActivityCommentTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTopicTriggerTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTransformer;\nuse Jiminny\\Http\\Transformers\\AvailabilityNotificationTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingFeedbackTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingSectionsTransformer;\nuse Jiminny\\Http\\Transformers\\SearchTransformer;\nuse Jiminny\\Http\\Transformers\\StatsTransformer;\nuse Jiminny\\Jobs\\Crm\\SaveActivity;\nuse Jiminny\\Jobs\\Crm\\UpdateStage;\nuse Jiminny\\Jobs\\Telephony\\StartRecording;\nuse Jiminny\\Jobs\\Telephony\\StopRecording;\nuse Jiminny\\Jobs\\Telephony\\ToggleRecording;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\CoachingFeedback;\nuse Jiminny\\Models\\CoachingSection;\nuse Jiminny\\Models\\CoachingSectionCriterion;\nuse Jiminny\\Models\\CoachingSectionFeedback;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\LanguageDialect;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Nudge;\nuse Jiminny\\Models\\PlaybookCategory;\nuse Jiminny\\Models\\Playlist;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\Track;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\CoachingFeedbackRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Rules\\MultidimensionalArrayMaxCharRule;\nuse Jiminny\\Services\\ActivityService;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Services\\PlaybackService;\nuse Jiminny\\Services\\UserService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\nuse Ramsey\\Uuid\\Uuid;\nuse Sentry;\nuse Symfony\\Component\\HttpFoundation;\n\nfinal class ActivityController extends Controller implements CommentContextInterface\n{\n // Number of minutes to look back on activities. i.e. a timeout on activity duration.\n private const int LOOK_BACK = 180;\n\n public function __construct(\n private ProviderRegistry $providerRegistry,\n private ActivityService $activityService,\n Response $response,\n private UserService $userService,\n private ActivitySearch\\Service\\ActivitySearch $activitySearch,\n private NudgeFactoryInterface $nudgeFactory,\n private ActivityCommentService $activityCommentService,\n private LoggerInterface $logger,\n private readonly CoachingFeedbackRepository $coachingFeedbackRepository,\n private readonly TeamRepository $teamRepository,\n ) {\n parent::__construct($response);\n }\n\n public static function getCommentImplementation(): string\n {\n return Comment::class;\n }\n\n public function delete()\n {\n $this->request->validate([\n '*' => 'uuid:activities',\n ]);\n\n $deletedIds = [];\n foreach ($this->request->all() as $activityId) {\n $activity = Activity::idOrUuId($activityId);\n\n try {\n if ($this->authorize('delete', $activity)) {\n $activity->delete();\n $deletedIds[] = $activityId;\n\n \\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n }\n } catch (AuthorizationException $authorizationException) {\n // They didn't have permission.\n }\n }\n\n return $this->response->withArray($deletedIds);\n }\n\n public function update(Request $request, Activity $activity)\n {\n $this->authorize('updateMetadata', $activity);\n\n $request->validate([\n 'title' => 'string|max:250',\n 'category_id' => 'uuid:playbook_categories',\n 'language' => [\n new In(\n LanguageDialect::query()\n ->with('language')\n ->cursor()\n ->map(static function (LanguageDialect $languageDialect): string {\n return $languageDialect->getLanguageLocale();\n })\n ->all()\n ),\n ],\n ]);\n\n if ($request->has('title')) {\n $activity->title = $request->input('title');\n }\n\n if ($request->has('category_id')) {\n $category = PlaybookCategory::uuid($request->input('category_id'));\n\n if ($category->playbook->team_id !== $request->user()->team_id) {\n return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n if ($request->has('language')) {\n if (! $activity->isInProgress()) {\n return $this->response->withError(\n 'Activity language can only be set while the meeting is in progress.',\n 400\n );\n }\n\n $activity->setLanguageCode($request->input('language'));\n }\n\n $activity->save();\n\n return $this->response->withOk();\n }\n\n // XXX: This should be merged with the update method.\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws SocialAccountTokenInvalidException\n *\n * @return mixed\n */\n public function summarize(Activity $activity): mixed\n {\n $this->logger->info('[Log Activity] Summarizing activity ', [\n 'activityId' => $activity->getUuid(),\n 'payload' => $this->request->all(),\n ]);\n $this->authorize('update', $activity);\n\n $this->logger->info('[Log Activity] Validating summary');\n // Validate the payload.\n $this->validateSummary($activity);\n\n // All objects must belong to this team.\n /** @var User $user */\n $user = $this->request->user();\n $team = $user->getTeam();\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n try {\n $crmUser = $user;\n if ($user->isCrmRequired() === false) {\n $crmUser = $team->owner;\n }\n $crmService->setUser($crmUser);\n } catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());\n }\n\n $rawEntities = $this->request->input('entities');\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid(\n $this->request->input('layout_id')\n );\n\n // Delay execution of CRM jobs to avoid locking issues.\n $jobDelay = 0;\n\n // If we have arrived from a notification, mark it as read.\n $notificationId = $this->request->input('nId');\n if ($notificationId) {\n $notification = $user->unreadNotifications->where('id', $notificationId)->first();\n\n if ($notification) {\n $notification->markAsRead();\n }\n }\n\n $title = $this->request->input('title');\n $prospects = $this->request->input('prospects');\n $opportunityId = $this->request->input('opportunity_id');\n $stageId = $this->request->input('stage_id');\n $categoryId = $this->request->input('category_id');\n $summary = $this->request->input('summary');\n $crmProviderId = $this->request->input('crm_id');\n $isInternal = $this->request->input('is_internal') ?? false;\n\n $lead = null;\n $category = null;\n $account = null;\n $contact = null;\n $opportunity = null;\n $stage = null;\n $callStage = null;\n\n foreach ($prospects as $prospectData) {\n $objectId = $prospectData['id'];\n\n if ($objectId === null) {\n continue;\n }\n\n $objectType = $prospectData['type'];\n $this->logger->info('debug', ['prospect_data' => $prospectData]);\n\n try {\n if ($objectType === null) {\n $this->logger->info('no object type');\n if ($crmService instanceof SupportsObjectTypeParseInterface) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n }\n\n switch ($objectType) {\n case 'lead':\n $this->logger->info('Processing lead');\n /** @var Lead|null $lead */\n $lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();\n\n // Lead does not exist locally, import it.\n if ($lead === null) {\n $this->logger->info('Lead does not exist locally');\n /** @var Lead $lead */\n $lead = $crmService->syncLead($objectId);\n }\n\n $this->logger->info('Lead found', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n if ($stageId === null) {\n $this->logger->info('Stage ID is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $lead->stage;\n\n break;\n }\n\n $this->logger->info('Looking for stage');\n // Determine if they have changed the stage.\n /** @var Stage $stage */\n $stage = $team->crm->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_LEAD)\n ->firstOrFail();\n\n $this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);\n if ($lead->stage_id && $lead->stage_id !== $stage->id) {\n $this->logger->info('Stage has changed');\n // Storage current stage on activity.\n $callStage = $lead->stage;\n\n // The stage has changed, update in remote CRM.\n dispatch(new UpdateStage($activity, $lead, $callStage, $stage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing lead stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->getName(),\n $stage->getName()\n ),\n [\n 'user' => $user->getUuid(),\n 'lead' => $lead->getUuid(),\n ]\n );\n } else {\n $this->logger->info('Stage has not changed');\n // Stage remains as current.\n $callStage = $stage;\n }\n\n break;\n\n case 'account':\n $this->logger->info('Processing account');\n // If the object is not a lead, it should be an account.\n $account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();\n\n // Account does not exist locally, import it.\n if ($account === null) {\n $this->logger->info('Account does not exist locally');\n $account = $crmService->syncAccount($objectId);\n }\n\n $this->logger->info('Account found', ['accountId' => $account->id]);\n\n break;\n case 'contact':\n $this->logger->info('processing contact');\n $contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $this->logger->info('contact does not exist locally');\n $contact = $crmService->syncContact($objectId);\n }\n\n $this->logger->info('resolving account');\n $account = $this->resolveAccount($team, $contact, $crmService, $prospects);\n\n break;\n }\n\n // If they have specified an opportunity, retrieve this with stage.\n if ($opportunityId) {\n $this->logger->info('opportunity id is set');\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if ($opportunity === null) {\n $this->logger->info('opportunity does not exist locally');\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n if ($stageId === null) {\n $this->logger->info('stage id is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $opportunity->stage ?? null;\n } else {\n $this->logger->info('looking for stage');\n /** @var ?Stage $opportunityStage */\n $opportunityStage = $team->crm\n ->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n // There is a chance we still cannot import this opportunity.\n if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {\n $this->logger->info('opportunity stage has changed');\n // Storage current stage on activity.\n $callStage = $opportunity->stage;\n\n dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing opportunity stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->name,\n $opportunityStage->name\n ),\n [\n 'userId' => $user->id_string,\n 'opportunityId' => $opportunity->id_string,\n ]\n );\n } else {\n $this->logger->info('opportunity stage has not changed');\n // Stage remains as current.\n $callStage = $opportunityStage;\n }\n }\n }\n\n if ($crmProviderId) {\n // Cast $crmProviderId to string otherwise it won't use database index for some records\n $linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();\n\n // Check if this activity has already been assigned to a different activity.\n if ($linkedActivity && $linkedActivity->id !== $activity->id) {\n throw new InvalidArgumentException(\n 'Sorry, the linked task has already been logged under a different call. '\n . 'Please choose another linked task.'\n );\n }\n }\n } catch (InvalidArgumentException $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($exception->getMessage());\n } catch (Exception $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorInternalError(\n 'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'\n );\n }\n }\n\n if ($categoryId) {\n $category = PlaybookCategory::uuid($categoryId);\n\n if ($category->playbook->team_id !== $team->id) {\n throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n $this->logger->info('Prospect data', [\n 'lead_id' => $lead?->getId(),\n 'account_id' => $account?->getId(),\n 'contact_id' => $contact?->getId(),\n 'opportunity_id' => $opportunity?->getId(),\n 'stage_id' => $stage?->getId(),\n ]);\n\n if ($title) {\n $activity->title = $title;\n }\n\n if ($summary) {\n $activity->summary = $summary;\n }\n\n if ($crmProviderId) {\n $activity->crm_provider_id = $crmProviderId;\n }\n\n if ($callStage) {\n $this->logger->info('Setting stage id', ['stageId' => $callStage->id]);\n $activity->stage_id = $callStage->id;\n }\n\n if ($lead) {\n $this->logger->info('Setting lead id', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n // If we are changed from an account > lead, unset the account data.\n $this->logger->info('Unsetting account id, opportunity id, contact id, value');\n $activity->account_id = null;\n $activity->opportunity_id = null;\n $activity->contact_id = null;\n $activity->value = null;\n }\n\n if ($account) {\n $this->logger->info('Setting account id', ['accountId' => $account->id]);\n $activity->account_id = $account->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('unsetting lead id');\n $activity->lead_id = null;\n\n // Unset the contact if switching different accounts. Will be set up below if still applicable.\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {\n $this->logger->info('Unsetting contact id');\n $activity->contact_id = null;\n }\n }\n\n if ($opportunity) {\n $this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);\n $this->logger->info('unsetting lead id');\n $activity->opportunity_id = $opportunity->id;\n $activity->value = $opportunity->value;\n\n // If we are changed from an lead > account, unset the lead data.\n $activity->lead_id = null;\n }\n\n if ($contact) {\n $this->logger->info('setting contact id', ['contactId' => $contact->id]);\n $activity->contact_id = $contact->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('Unsetting lead id');\n $activity->lead_id = null;\n }\n\n $activity->is_internal = $isInternal;\n $activity->save();\n $activity->refresh();\n\n $this->logger->notice('Activity saved', [\n 'activity_id' => $activity->getId(),\n 'lead_id' => $activity->lead_id,\n 'account_id' => $activity->account_id,\n 'contact_id' => $activity->contact_id,\n 'opportunity_id' => $activity->opportunity_id,\n 'stage_id' => $activity->stage_id,\n 'crm_provider_id' => $activity->getCrmProviderId(),\n ]);\n\n // Store entities as field data on the activity.\n $updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);\n\n if ($activity->isLoggable()) {\n // Follow-up Task or Event data.\n $followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);\n\n $this->logger->info('CRM LOG manual log triggered', [\n 'activityId' => $activity->getUuid(),\n 'followupData' => $followupData,\n 'userId' => $user->getUuid(),\n ]);\n\n // Store data in the CRM.\n // ++add check for crm_required\n $job = new SaveActivity($activity, $followupData);\n\n if ($updatedData) {\n $job->delay(Carbon::now()->addMinutes($jobDelay));\n }\n\n dispatch($job);\n\n // Manually dispatch log for Opportunity or Prospect added\n if ($activity->hasOpportunity() || $activity->hasProspect()) {\n event(new ActivityProspectAdded(\n activity: $activity,\n eventSource: 'manually-log-crm-data'\n ));\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.\n *\n * @param ServiceInterface $service\n * @param Activity $activity\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array\n {\n $updatedData = [];\n $existingData = $activity->data()->get();\n\n // We need to delete any existing data to overwrite with latest values.\n $activity->data()->delete();\n\n $layoutEntities = $layout->entities()\n ->with('field', 'parent')\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->get();\n\n /** @var LayoutEntity $entity */\n foreach ($layoutEntities as $entity) {\n // If the user has provided a value for this entity\n if (array_key_exists($entity->id_string, $entities)) {\n $value = $entities[$entity->id_string];\n\n // Convert raw data into values that the CRM can consume.\n if ($value) {\n $value = $service->normalizeValue($entity->field->type, $value);\n }\n\n // Check the field is part of the activity-summary section.\n if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {\n // This is the internal database ID, not the external CRM ID.\n $objectId = null;\n\n switch ($entity->field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $objectId = $activity->account_id;\n\n break;\n\n case Field::OBJECT_CONTACT:\n $objectId = $activity->contact_id;\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n $objectId = $activity->opportunity_id;\n\n break;\n\n case Field::OBJECT_LEAD:\n $objectId = $activity->lead_id;\n\n break;\n\n case Field::OBJECT_TASK:\n case Field::OBJECT_EVENT:\n $objectId = $activity->id;\n\n break;\n }\n\n if ($objectId) {\n /** @var FieldData $data */\n $data = $activity->data()->create([\n 'crm_layout_entity_id' => $entity->id,\n 'crm_field_id' => $entity->crm_field_id,\n 'object_type' => $entity->field->object_type,\n 'object_id' => $objectId,\n 'value' => $value,\n ]);\n\n // Never send read-only field data to the CRM.\n if ($entity->read_only === false && $entity->is_visible) {\n $existingValue = $existingData\n ->where('crm_layout_entity_id', $entity->id)\n ->where('crm_field_id', $entity->crm_field_id)\n ->where('object_type', $entity->field->object_type)\n ->where('object_id', $objectId)\n ->first();\n\n // If the field was actually changed, we need to reflect this in the CRM too.\n if ($existingValue === null || $existingValue->value !== $value) {\n $updatedData[] = $data->id;\n }\n }\n }\n }\n }\n }\n\n return $updatedData;\n }\n\n /**\n * Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.\n *\n * @param ServiceInterface $crmService\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array\n {\n $fieldData = [];\n foreach ($entities as $entityId => $value) {\n // Only bother with fields that have a value.\n if ($value) {\n // Extract the entity from the UUID. Check the field is valid and part of the follow-up section.\n $entity = $layout->entities()\n ->uuid($entityId, false)\n ->whereHas('parent', function ($query) {\n $query->where('label', 'follow-up');\n })\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->first();\n\n if ($entity) {\n // Convert raw data into values that the CRM can consume.\n $value = $crmService->normalizeValue($entity->field->type, $value);\n\n // Add the field and value to the payload.\n $fieldData += [\n $entity->field->crm_provider_id => $value,\n ];\n }\n }\n }\n\n return $fieldData;\n }\n\n /**\n * @param Activity $activity\n */\n private function validateSummary(Activity $activity): void\n {\n $team = $activity->user->team;\n $crmProvider = $team->crm->provider;\n $attributes = [];\n\n $rules = [\n 'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,\n 'title' => 'string|max:250',\n 'prospects' => 'required|array',\n 'opportunity_id' => new CrmReference($crmProvider),\n 'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',\n 'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator\n 'summary' => 'max:50000',\n 'nId' => 'exists:notifications,id',\n 'crm_id' => new CrmReference($crmProvider),\n 'entities' => 'array',\n 'is_internal' => 'boolean',\n ];\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));\n\n // Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.\n $entities = $layout->entities()\n ->where('read_only', 0)\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->whereHas('parent', function ($query) use ($activity) {\n if ($activity->isLoggable() === false) {\n $query->where('label', '<>', 'follow-up');\n }\n });\n\n $isInternal = $this->request->input('is_internal', false);\n\n foreach ($entities->get() as $entity) {\n $rules += $this->buildFieldValidator($entity, $isInternal);\n $attributes += $this->buildFieldMessage($entity);\n }\n\n $this->request->validate($rules, [], $attributes);\n }\n\n private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array\n {\n return [\n 'entities.' . $entity->id_string => $entity->getValidator($isInternal),\n ];\n }\n\n /**\n * @param LayoutEntity $entity\n *\n * @return array\n */\n private function buildFieldMessage(LayoutEntity $entity): array\n {\n $label = $entity->label;\n if ($label === null) {\n $label = $entity->field->label;\n }\n\n return [\n 'entities.' . $entity->id_string => $label,\n ];\n }\n\n public function search(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->debugLog(\n $user,\n 'User extracted from request',\n ['user' => $user->getId(), 'tz' => $user->getTimezone()]\n );\n\n $searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());\n\n $this->debugLog(\n $user,\n 'ActivitySearch criteria built',\n ['searchCriteria' => $searchCriteria]\n );\n\n $filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);\n\n $this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);\n\n $this->validateSearch($request, $filterSet);\n\n $this->debugLog($user, 'Request validated');\n\n $searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);\n\n /** @var Collection<Activity> $activities */\n $activities = $searchResponse['results'];\n\n $this->debugLog($user, 'Activities ES response extracted');\n\n $hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(\n $user->getTeamId(),\n TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),\n );\n\n if ($hideInternalMeetingsSetting?->getValue() === '1') {\n $activities = $activities->filter(function (Activity $activity) {\n if ($activity->is_internal && empty($activity->actual_start_time)) {\n return false;\n }\n\n return true;\n });\n }\n\n $this->debugLog($user, 'Internal meetings (?!) filtered');\n\n $this->response->getManager()\n ->parseIncludes([\n 'category',\n 'organizer.group',\n 'prospect',\n 'stage',\n 'opportunity',\n 'stats',\n 'scorecards',\n 'masterTrack',\n 'activeParticipants',\n 'notification',\n ])\n ->setSerializer(new JsonSerializer());\n\n $transformerExcludes = $this->request->input('exclude');\n if ($transformerExcludes) {\n $this->response->getManager()->parseExcludes($transformerExcludes);\n }\n\n $this->debugLog($user, 'Response Manager (?!) applied');\n\n $transformer = new ActivityTransformer();\n $transformer->setConsumer($user);\n\n $this->debugLog($user, 'Activity Transformer added');\n\n $resource = new \\League\\Fractal\\Resource\\Collection($activities, $transformer);\n $page = $searchCriteria->getPageNumber();\n\n $this->debugLog($user, 'Search criteria page number called', ['page' => $page]);\n\n $histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');\n\n $this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);\n\n return $this->response->withArray([\n 'pagination' => [\n 'total' => $searchResponse['totalHits'],\n 'current' => $page,\n 'prev' => max($page - 1, 1),\n 'next' => $page + 1,\n ],\n 'results' => $this->response->getManager()->createData($resource)->toArray(),\n 'histogram' => $histogram,\n ]);\n }\n\n private function debugLog(User $user, string $logMessage, ?array $context = []): void\n {\n // Debug for Learning People Only\n if ($user->getTeamId() !== 260) {\n return;\n }\n\n Log::notice(\n sprintf('[activity-search-controller] %s', $logMessage),\n $context\n );\n }\n\n /** @throws ValidationException */\n private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void\n {\n $rules = [\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ];\n\n if ($prefix !== null && mb_strpos($prefix, '.') !== false) {\n $rules[rtrim($prefix, '.')] = sprintf(\n 'required|array|max:%d',\n $filterSet->count()\n );\n }\n\n $validationRules = $filterSet->getValidationRules($prefix)\n ->merge($rules)\n ->all();\n\n $request->validate($validationRules);\n }\n\n public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $search = $this->updateOrCreateActivitySearch($request);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function updateActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('update', $search);\n\n $this->updateOrCreateActivitySearch($request, $search);\n\n return $this->response->withOk();\n }\n\n private function storeNamedSearchFilters(\n Collection $request,\n Search $search,\n FilterDefinitionCollection $filterSet,\n ?string $prefix = null,\n ): self {\n $arrayTypeProperties = $filterSet\n ->getPropertyTypes([\n FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,\n ])\n ->all();\n\n $supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);\n\n foreach ($supportedRequestProperties as $requestPropertyName) {\n if (! array_has($request, $requestPropertyName)) {\n continue;\n }\n\n /** @var string|string[] $propertyValue */\n $propertyValue = array_get($request, $requestPropertyName);\n $propertyName = $prefix === null\n ? $requestPropertyName\n : mb_substr($requestPropertyName, mb_strlen($prefix));\n\n $isArrayType = array_has($arrayTypeProperties, $propertyName);\n\n if (! $isArrayType) {\n /** @var string $requestPropertyValue */\n\n $search->filters()->updateOrCreate(\n [\n 'filter' => $propertyName,\n ],\n [\n 'value' => $propertyValue,\n ]\n );\n\n continue;\n }\n\n /** @var string[] $requestPropertyValue */\n\n /** @var SearchFilter[]|Collection $existingFilterValues */\n $existingFilterValuesKeyed = $search->filters()\n ->where('filter', $propertyName)\n ->get()\n ->keyBy('id');\n\n // Iterate over values provided as request parameters\n foreach ($propertyValue as $value) {\n /** @var SearchFilter|null $valueFilter */\n $valueFilter = $search->filters()\n ->where(\n [\n 'filter' => $propertyName,\n 'value' => $value,\n ]\n )\n ->first();\n\n if ($valueFilter !== null) {\n // Remove filter value pair from list to be deleted\n $existingFilterValuesKeyed->forget($valueFilter->id);\n } else {\n // Add new filter/value pair\n $search->filters()->updateOrCreate([\n 'filter' => $propertyName,\n 'value' => $value,\n ]);\n }\n }\n\n // Delete filter value pairs for this filter that no longer exist in request parameters\n foreach ($existingFilterValuesKeyed as $existingFilter) {\n $existingFilter->delete();\n }\n }\n\n /** @var Collection<int, SearchFilter> $filtersKeyed */\n $filtersKeyed = $search->filters()->get()->keyBy('filter');\n\n // wipe removed filters from this search\n foreach ($filtersKeyed as $filterName => $filter) {\n if (array_has($request, $prefix . $filterName)) {\n continue;\n }\n\n // Remove all filter values for this filter\n $search->filters()->where('filter', $filterName)->delete();\n }\n\n return $this;\n }\n\n /**\n * @throws AuthorizationException\n */\n public function fetchActivitySearch(\n Search $search,\n Request $request,\n SearchTransformer $searchTransformer,\n ): JsonResponse {\n $this->authorize('view', $search);\n\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection(\n $user->searches()->get(),\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n /**\n * Deletes a saved search\n *\n * @param Request $request\n * @param Search $search\n *\n * @throws Exception\n *\n * @return JsonResponse\n */\n public function deleteActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('delete', $search);\n\n // Orphan any AutomatedReports that use this search\n $search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);\n\n // Delete filters and the search itself\n $search->filters()->delete();\n $search->delete();\n\n return $this->response->withOk();\n }\n\n public function live(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n $user = $this->getUserFromRequest($request);\n\n $this->request->validate([\n 'sort_direction' => 'in:asc,desc',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ]);\n\n $activities = $repository->getLiveCoachingEligibleActivities(\n user: $user,\n lookBackMinutes: self::LOOK_BACK,\n limit: (int) $this->request->input('limit', 25),\n page: (int) $this->request->input('page', 1),\n sortBy: ['actual_start_time', 'scheduled_start_time'],\n sortDirection: (string) $this->request->input('sort_direction', 'asc'),\n );\n\n $this->response\n ->getManager()\n ->parseIncludes(['organizer.group', 'prospect'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($activities, new ActivityTransformer());\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function show(Activity $activity, ActivityService $activityService): JsonResponse\n {\n $this->authorize('show', $activity);\n\n $user = $activity->getUser();\n $team = $user->getTeam();\n\n // Sync the opportunity with the latest data if possible.\n if ($activity->opportunity_id) {\n try {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n if (! $user->isCrmRequired()) {\n $crmService->setUser($team->getOwner());\n } else {\n $crmService->setUser($user);\n }\n\n $crmService->syncOpportunity($activity->opportunity->crm_provider_id);\n } catch (Exception $exception) {\n // Move on.\n }\n }\n\n $activityData = $activityService->getActivityData($this->request->user(), $activity);\n\n return response()->json($activityData);\n }\n\n public function createRecording(Activity $activity)\n {\n $this->authorize('record', $activity);\n\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Tell Twilio to start recording this activity.\n if ($activity->recording_state === Activity::RECORDING_OFF) {\n $job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withCreated();\n }\n\n return $this->response->errorGone('Activity is already recording.');\n }\n\n public function updateRecording(Request $request, Activity $activity)\n {\n $this->authorize('record', $activity);\n\n $request->validate([\n 'preference' => 'boolean',\n 'state' => [\n 'string',\n Rule::in([\n Activity::RECORDING_IN_PROGRESS,\n Activity::RECORDING_PAUSED,\n ]),\n ],\n ]);\n\n if ($request->has('state')) {\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Toggle the recording state between paused and resumed.\n if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {\n $job = (new ToggleRecording($activity, $request->input('state')))\n ->onQueue(Constants::QUEUE_CONFERENCES);\n\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Recording is not toggleable.');\n }\n\n if ($request->has('preference')) {\n $activity->update([\n 'recording_preference' => $request->input('preference') ? 1 : 0,\n ]);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorWrongArgs('Something went wrong');\n }\n\n public function stopRecording(Activity $activity)\n {\n $this->authorize('stopRecord', $activity);\n\n // Tell Twilio to stop recording this activity.\n if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {\n $job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Activity is not recording.');\n }\n\n /**\n * Add activity to this user's favorites playlist\n *\n * @throws AuthorizationException\n */\n public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse\n {\n $this->authorize('favorite', $activity);\n\n $user = $this->getUserFromRequest($this->request);\n $favorite = $activity->wasFavoritedBy($user);\n $name = $activity->activity_title ?? '';\n\n // It needs to check at least one record.\n if (! $favorite) {\n $favoritePlaylist = $user->favoritePlaylist();\n\n $playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(\n $activity,\n $user,\n $favoritePlaylist\n );\n\n if ($playlistActivity !== null) {\n $playlistActivity->update(\n // Just update, don't sort.\n ['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],\n );\n } else {\n $playlistActivity = $activity->playlistActivities()->create([\n 'playlist_id' => $favoritePlaylist->getId(),\n 'user_id' => $user->getId(),\n 'start_time' => 0,\n 'name' => mb_strimwidth($name, 0, 100),\n ]);\n // Sort it on top.\n $playlistActivity->update(\n [\n 'sort' => $playlistActivityRepository->calculateNewSortOrder(\n null,\n $playlistActivity,\n ),\n ],\n );\n }\n\n $playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);\n\n return new JsonResponse([], JsonResponse::HTTP_CREATED);\n }\n\n return new JsonResponse(\n [\n 'error' => [\n 'code' => AbstractResponse::CODE_CONFLICT,\n 'http_code' => JsonResponse::HTTP_CONFLICT,\n 'message' => 'Resource Already Exists',\n ],\n ],\n JsonResponse::HTTP_CONFLICT,\n );\n }\n\n /**\n * Remove activity from this user's favorites playlist\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unfavorite(Activity $activity)\n {\n $user = $this->request->user();\n\n $favorites = $activity->favoritedBy($user);\n\n if ($favorites && $favorites->isEmpty()) {\n return $this->response->errorNotFound('Favorite not found.');\n }\n\n $this->authorize('unfavorite', [$activity, $favorites]);\n\n // When you unfavorite an activity,\n // it should remove all the activities in it, including snippets.\n $isDeleted = $favorites->each(function ($favorite) {\n $favorite->forceDelete();\n });\n\n if ($isDeleted) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not remove favorite.');\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function notify(Activity $activity)\n {\n $this->authorize('notify', $activity);\n\n $user = $this->request->user();\n\n $existingNotification = $activity->availabilityNotifications()\n ->where('user_id', $user->id)\n ->exists();\n\n if ($existingNotification) {\n return $this->response->errorWrongArgs('Notification is already configured.');\n }\n\n $notification = Activity\\AvailabilityNotification::create([\n 'user_id' => $user->id,\n 'activity_id' => $activity->id,\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($notification, new AvailabilityNotificationTransformer());\n }\n\n /**\n * @param Activity $activity\n * @param Activity\\AvailabilityNotification $notification\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unnotify(Activity $activity, Activity\\AvailabilityNotification $notification)\n {\n $this->authorize('unnotify', [$activity, $notification]);\n\n if ($notification->sent_at || $notification->delete()) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not delete notification.');\n }\n\n public function play(Request $request, Activity $activity)\n {\n $this->authorize('stream', $activity);\n\n $request->validate([\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $activity->plays()->create([\n 'user_id' => $user->getId(),\n 'start_time' => $request->input('start_time'),\n ]);\n\n return $this->response->withCreated();\n }\n\n /**\n * @param Activity $activity\n *\n * @return mixed\n */\n public function comment(Activity $activity)\n {\n return $this->newComment($activity);\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @return mixed\n */\n public function replyComment(Activity $activity, Comment $comment)\n {\n return $this->newComment($activity, $comment);\n }\n\n /**\n * @param Activity $activity\n * @param Comment|null $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n protected function newComment(Activity $activity, ?Comment $comment = null)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n 'type' => 'integer|between:0,3',\n 'visibility' => sprintf('nullable|integer|between:1,%d', count(Comment::getVisibilityLevels())),\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n $threadStartId = null;\n if ($comment) {\n $threadStartId = $comment->thread_start_id ?: $comment->id;\n }\n\n try {\n $newComment = Comment::create([\n 'parent_comment_id' => $comment->id ?? null,\n 'thread_start_id' => $threadStartId,\n 'activity_id' => $activity->id,\n 'user_id' => $this->request->user()->id,\n 'comment' => trim($this->request->input('comment')),\n 'start_time' => $this->request->input('start_time', 0),\n 'end_time' => $this->request->input('end_time', 0),\n 'type' => $this->request->input('type', Comment::TYPE_NEUTRAL),\n 'visibility' => $this->request->input('visibility', Comment::VISIBILITY_PUBLIC),\n ]);\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($newComment, new ActivityCommentTransformer());\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not create comment.' . $exception->getMessage());\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function updateComment(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n try {\n $comment->update([\n 'comment' => trim($this->request->input('comment')),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment.');\n }\n }\n\n public function updateCommentVisibility(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'visibility' => sprintf('integer|between:1,%d', count(Comment::getVisibilityLevels())),\n ]);\n\n $visibility = $this->request->input('visibility');\n\n if ($comment->parent !== null) {\n return $this->response->errorWrongArgs('Comment visibility can only be updated on top level comments.');\n }\n\n try {\n $this->activityCommentService->updateCommentVisibility($comment, $visibility);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment\\'s visibility.');\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function deleteComment(Activity $activity, Comment $comment)\n {\n $this->authorize('deleteComment', [$activity, $comment]);\n\n // Delete comment and any children.\n $comment->delete();\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function fetchComments()\n {\n $user = $this->request->user();\n $this->request->validate([\n 'forUserId' => 'uuid:users,team_id,' . $user->team_id,\n 'types' => 'array',\n 'types.*' => 'integer|between:0,3',\n ]);\n $forUser = null;\n\n $types = [Comment::TYPE_NEUTRAL, Comment::TYPE_GAME_CHANGER, Comment::TYPE_POSITIVE];\n $user = $this->request->user();\n if ($this->request->has('forUserId')) {\n $forUser = $user->team->users()->uuid($this->request->input('forUserId'));\n }\n\n $comments = Comment::query()\n ->whereHas('activity', static function (Builder $builder) use ($user, $forUser): void {\n $builder\n // I left feedback on my own activity; or\n ->where('activities.user_id', $user->getId());\n if ($forUser) {\n // I left feedback on any activity for this user.\n $builder->orWhere([\n 'user_id' => $user->getId(),\n 'activities.user_id' => $forUser->getId(),\n ]);\n }\n })\n ->whereIn('type', $this->request->input('types', $types))\n ->orderBy('created_at', 'desc')\n ->get();\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity', 'user'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($comments, new ActivityCommentTransformer());\n }\n\n public function deleteCoachingFeedback(Activity $activity, CoachingFeedback $coachingFeedback)\n {\n $this->authorize('deleteCoachingFeedback', [$activity, $coachingFeedback]);\n $activity = $coachingFeedback->getActivity();\n\n if ($coachingFeedback->delete()) {\n event(new UpdateSingleEntity(\n entityId: $activity->getId(),\n updateTarget: UpdateTargetEnum::ACTIVITY,\n purpose: 'delete-coaching-feedback',\n ));\n\n return $this->response->withOk();\n }\n\n return $this->response->withError('Delete operation failed. Contact support.', 500);\n }\n\n /**\n * Add new or update Coaching feedback\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws \\Illuminate\\Validation\\ValidationException\n *\n * @return mixed\n */\n public function putCoachingFeedback(Request $request, Activity $activity)\n {\n $user = $request->user();\n\n if (! $user instanceof User) {\n abort(403);\n }\n $teamId = $user->getTeamId();\n\n $this->authorize('coach', $activity);\n\n $this->request->validate([\n 'coach_id' => 'required|uuid:users,team_id,' . $teamId,\n 'coachee_id' => 'required|uuid:users,team_id,' . $teamId,\n 'visibility' => ['required', Rule::in(CoachingFeedback::VISIBILITIES)],\n 'coaching_sections.*.uuid' => 'required|uuid:coaching_sections',\n 'coaching_sections.*.score' => ['required', Rule::in(CoachingSectionFeedback::SCORES)],\n 'coaching_sections.*.summary' => 'string|max:10000',\n 'coaching_sections.*.criteria.*.uuid' => 'required|uuid:coaching_section_criteria',\n 'coaching_sections.*.criteria.*.note' => 'required|string|max:10000',\n 'sharedWithUsers' => [\n 'required_if:visibility,' . CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS,\n 'array',\n ],\n 'sharedWithUsers.*' => [\n 'uuid:users,team_id,' . $teamId,\n ],\n ]);\n\n /** @var User $coach */\n $coach = User::uuid($this->request->input('coach_id'));\n /** @var User $coachee */\n $coachee = User::uuid($this->request->input('coachee_id'));\n $coachingSectionFeedbacks = $this->request->input('coaching_sections');\n\n $previousRecord = $this->coachingFeedbackRepository->getOneForActivityByCoacheeAndCoach(\n $coachee->getId(),\n $coach->getId(),\n $activity->getId()\n );\n $recordIsNew = false;\n if ($previousRecord === null) {\n $recordIsNew = true;\n }\n\n if (! $coachee->isSameTeamId($coach)) {\n return $this->response->errorForbidden('User not member of your team.');\n }\n\n if (! is_array($coachingSectionFeedbacks) || count($coachingSectionFeedbacks) < 1) {\n return $this->response->withError('At least one Coaching Framework Section shall be scored.', 422);\n }\n\n if (! $activity->participants()->where('participants.user_id', $coachee->id)->exists()) {\n return $this->response->withError('Coached user did not participate activity.', 422);\n }\n\n $visibility = $this->request->input('visibility');\n\n $shouldSendNotification = $recordIsNew;\n if ($recordIsNew === false && $visibility !== $previousRecord->getVisibility()) {\n $shouldSendNotification = true;\n }\n\n /**\n * Create CoachingFeedback\n *\n * @var CoachingFeedback $coachingFeedback\n */\n $coachingFeedback = $activity->coachingFeedbacks()->updateOrCreate(\n [\n 'coach_id' => $coach->id,\n 'coachee_id' => $coachee->id,\n ],\n [\n 'framework_id' => $activity->category->id,\n 'visibility' => $visibility,\n ]\n );\n\n $sharedUserIds = [];\n if ($visibility === CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS) {\n foreach ($this->request->input('sharedWithUsers') as $sharedWithUserUuid) {\n /** @var User $user */\n $user = User::uuid($sharedWithUserUuid);\n $sharedUserIds[] = $user->getId();\n }\n }\n\n $syncResult = $coachingFeedback->customAccessUsers()->sync($sharedUserIds);\n\n $scores = [];\n\n\n /**\n * Create CoachingSectionsFeedbacks.\n *\n * @var CoachingSectionFeedback $coachingSectionFeedback\n */\n foreach ($coachingSectionFeedbacks as $coachingSectionFeedbackInput) {\n $coachingSection = CoachingSection::uuid($coachingSectionFeedbackInput['uuid']);\n $coachingSectionFeedback = $coachingFeedback->sectionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_id' => $coachingSection->id,\n ],\n [\n 'score' => array_get($coachingSectionFeedbackInput, 'score'),\n 'summary' => array_get($coachingSectionFeedbackInput, 'summary') ?? '',\n ]\n );\n\n $scores[] = array_get($coachingSectionFeedbackInput, 'score');\n\n $criteria = array_get($coachingSectionFeedbackInput, 'criteria');\n if (is_array($criteria) && ! empty($criteria)) {\n foreach ($criteria as $criteriaFeedbackInput) {\n $coachingSectionFeedback->criterionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_criterion_id' => CoachingSectionCriterion::uuid(array_get($criteriaFeedbackInput, 'uuid'))\n ->id,\n ],\n ['note' => array_get($criteriaFeedbackInput, 'note')],\n );\n }\n }\n }\n\n $coachingFeedback->average_score = array_sum($scores) / count($scores);\n\n if ($recordIsNew === false && $coachingFeedback->getAverageScore() !== $previousRecord->getAverageScore()) {\n $shouldSendNotification = true;\n }\n if (! empty($syncResult['attached']) || ! empty($syncResult['detached']) || ! empty($syncResult['updated'])) {\n $shouldSendNotification = true;\n }\n\n $coachingFeedback->save();\n // ensure updated at for coaching feedback on section feedback summary added.\n $coachingFeedback->touch();\n\n if ($shouldSendNotification) {\n event(new Coached($coachingFeedback));\n }\n\n Datadog::increment('jiminny.activity.score.update', 1, ['company' => $activity->user->team->slug]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n $coachingFeedbackTransformer = new CoachingFeedbackTransformer();\n $coachingFeedbackTransformer->setConsumer($this->getUserFromRequest($request));\n\n return $this->response->withItem($coachingFeedback, $coachingFeedbackTransformer);\n }\n\n\n /**\n * Retrieve category criteria for coaching.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachingSections(Activity $activity)\n {\n $this->authorize('coach', $activity);\n\n if ($activity->category === null) {\n return $this->response->errorUnprocessable('Category has not yet been assigned.');\n }\n\n $criteria = $activity\n ->category\n ->coachingSections()\n ->where('is_enabled', 1)\n ->orderBy('sequence', 'asc');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($criteria->get(), new CoachingSectionsTransformer());\n }\n\n /**\n * @throws AuthorizationException\n * @throws ValidationException\n *\n * @return mixed\n */\n public function addToPlaylist(Activity $activity, PlaylistTrackFactoryInterface $playlistTrackFactory)\n {\n $this->request->validate([\n 'playlists' => 'required|array',\n 'playlists.*' => 'uuid:playlists',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'name' => 'required|max:100',\n ]);\n\n $this->authorize('addToPlaylist', [$activity, $this->request->input('playlists')]);\n\n $startTime = $this->request->input('start_time');\n $endTime = $this->request->input('end_time');\n $name = $this->request->input('name');\n /** @var User $user */\n $user = $this->request->user();\n\n // Get playlist by uuid.\n foreach ($this->request->input('playlists') as $playlistId) {\n // Pull out the playlist model.\n $playlist = Playlist::uuid($playlistId);\n\n $playlistTrackFactory->createTrack($playlist, $user, [\n 'name' => $name,\n 'activity' => $activity,\n 'start_time' => $startTime,\n 'end_time' => $endTime,\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function share(Request $request, Activity $activity): JsonResponse\n {\n $this->authorize('share', $activity);\n\n $request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'recipients.*.type' => 'in:user,group',\n 'recipients.*.id' => 'string|max:40',\n 'share' => 'string|max:255',\n ]);\n\n $user = $request->user();\n\n $recipients = $request->get('recipients');\n $users = $this->userService->convertRecipientsToUsers($user, $recipients);\n\n $shareData = [\n 'from_user_id' => $user->id,\n 'note' => $request->input('note'),\n 'start_time' => $request->input('start_time'),\n 'end_time' => $request->input('end_time'),\n ];\n\n // Create a share object against a notification provider channel\n if ($request->input('share')) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'notification_provider_channel' => $request->input('share'),\n ]\n )\n );\n\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n\n // Create a share object against each recipient\n foreach ($users as $recipient) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'to_user_id' => $recipient->id,\n ]\n )\n );\n\n // If parent_share_id has been selected yet\n if (! isset($shareData['parent_share_id'])) {\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachRequest(Activity $activity)\n {\n $this->authorize('coachRequest', $activity);\n\n $this->request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'coachers.*.type' => 'required|in:user',\n 'coachers.*.id' => 'required',\n ]);\n\n $coachers = $this->request->get('coachers');\n $user = $this->request->user();\n $users = $this->userService->convertRecipientsToUsers($user, $coachers);\n\n foreach ($users as $coacher) {\n CoachRequest::create([\n 'user_id' => $coacher->id,\n 'activity_id' => $activity->id,\n 'note' => $this->request->get('note'),\n 'start_time' => $this->request->get('start_time'),\n 'end_time' => $this->request->get('end_time'),\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function createActivityTopicTriggers(Activity $activity, LoggerInterface $logger): HttpFoundation\\JsonResponse\n {\n $this->authorize('analyzeTopicTriggers', $activity);\n\n if (! $activity->hasTranscription()) {\n return new HttpFoundation\\JsonResponse(\n [\n 'error' => 'Transcription not found.',\n ],\n JsonResponse::HTTP_NOT_FOUND\n );\n }\n\n $logger->info(__METHOD__ . ': queued for analysis', [\n 'activity' => $activity->id_string,\n ]);\n\n dispatch(new ActivityAnalytics\\Job\\AnalyzeActivityTopicTriggers($activity));\n\n return new HttpFoundation\\JsonResponse(null, JsonResponse::HTTP_CREATED);\n }\n\n public function fetchActivityTopicTriggers(\n Activity $activity,\n LoggerInterface $logger,\n ActivityTopicTriggerTransformer $transformer\n ): HttpFoundation\\JsonResponse {\n $this->authorize('fetchTopicTriggers', $activity);\n\n $logger->debug(__METHOD__, [\n 'activity' => $activity->id_string,\n ]);\n\n if (! $activity->isProcessed()) {\n return new HttpFoundation\\JsonResponse([]);\n }\n\n $payload = [];\n\n if ($activity->hasTopicTriggers()) {\n $payload = $activity->getTopicTriggersSorted()\n ->map(\n static fn (Activity\\TopicTrigger $activityTopicTrigger): array\n => $transformer->transform($activityTopicTrigger)\n )\n ->values()\n ->all();\n }\n\n return new HttpFoundation\\JsonResponse($payload);\n }\n\n /**\n * @param Activity $activity\n * @param StatsTransformer $statsTransformer\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function stats(Activity $activity, StatsTransformer $statsTransformer)\n {\n $this->authorize('stream', $activity);\n\n if (! $activity->hasTranscription()) {\n return $this->response->errorNotFound('Waveform data is not yet generated.');\n }\n\n $this->response\n ->getManager()\n ->parseIncludes(['wavedata'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($activity, $statsTransformer);\n }\n\n public function destroy(Activity $activity)\n {\n $this->authorize('delete', $activity);\n\n $activity->delete();\n\n \\Log::info('Soft delete activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n\n return $this->response->withNoContent();\n }\n\n public function note(Activity $activity)\n {\n $this->authorize('note', $activity);\n\n $this->request->validate([\n 'note' => 'required|min:1|max:2000',\n 'time' => 'required|numeric|min:0|max:86400',\n ]);\n\n $note = $this->request->input('note');\n $time = $this->request->input('time');\n\n $this->activityService->setActivity($activity);\n $this->activityService->takeNote($this->getUser(), $note, $time);\n\n return $this->response->withCreated();\n }\n\n /**\n * Mark an activity as private.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPrivate(Activity $activity)\n {\n $this->authorize('markAsPrivate', $activity);\n\n if ($activity->is_private === false) {\n $activity->is_private = true;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * Mark an activity as public.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPublic(Activity $activity)\n {\n $this->authorize('markAsPublic', $activity);\n\n if ($activity->is_private) {\n $activity->is_private = false;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws LogicException\n */\n public function fetchCloudFrontS3MediaKeys(Activity $activity, PlaybackService $playbackService): JsonResponse\n {\n $masterTrack = $activity->masterTrack()->first();\n\n if (! $masterTrack instanceof Track) {\n throw new LogicException(sprintf('Master track not found for activity \"%s\"', $activity->getUuid()));\n }\n\n return $this->response->withArray(\n $playbackService->generateCookies(\n $masterTrack,\n $this->request->ip(),\n ),\n );\n }\n\n /**\n * @throws ValidationException\n */\n private function updateOrCreateActivitySearch(Request $request, ?Search $search = null): Search\n {\n $request->validate([\n 'name' => 'required|string|min:2|max:100',\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $searchName = $request->input('name');\n\n if ($search !== null) {\n $search->update([\n 'name' => $searchName,\n ]);\n\n return $search;\n }\n\n $request->validate([\n 'filters' => ['required', 'array', new MultidimensionalArrayMaxCharRule(limit: 255)],\n 'nudges' => 'array|max:' . count(Nudge::MAP_CHANNEL),\n 'nudges.*.channel' => 'required|in:' . implode(',', Nudge::MAP_CHANNEL),\n 'nudges.*.frequency' => 'required|in:' . implode(',', Nudge::MAP_FREQUENCY),\n 'nudges.*.expiresAt' => [\n 'required',\n 'date',\n 'after:today',\n 'before_or_equal:' . now()->addYear()->format('Y-m-d'),\n ],\n ]);\n\n $searchCriteria = Criteria::createFromRequest(\n Collection::make($request->input('filters', []))->all(),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($searchCriteria, $user);\n $this->validateSearch($request, $filterSet, 'filters.');\n\n /** @var Search $search */\n $search = Search::create([\n 'name' => $searchName,\n 'uuid' => Uuid::uuid4()->toString(),\n 'user_id' => $user->getId(),\n ]);\n\n Collection::make($request->input('nudges', []))\n ->each(fn (array $attributes): Nudge => $this->nudgeFactory->createNudge($search, $attributes));\n\n $this->storeNamedSearchFilters(Collection::make($request->all()), $search, $filterSet, 'filters.');\n\n return $search;\n }\n\n private function resolveAccount(\n Team $team,\n Contact $contact,\n ServiceInterface $crmService,\n array $prospects,\n ): ?Account {\n $this->logger->info('Resolving account from contact');\n $account = $contact->getAccount();\n\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS)) {\n $this->logger->info('Team does not have feature to link activity to multiple prospects');\n\n return $account;\n }\n\n $this->logger->info('Resolving account from prospect data');\n $accountData = array_filter(\n $prospects,\n static fn (array $prospectData): bool => $prospectData['type'] === 'account'\n );\n\n if (! empty($accountData)) {\n $this->logger->info('Found account data in prospects');\n $accountData = reset($accountData);\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountData['id'])->first();\n\n if (! $account instanceof Account) {\n $this->logger->info('Account not found in database, syncing from CRM');\n $account = $crmService->syncAccount($accountData['id']);\n }\n }\n\n $this->logger->info('Resolved account', ['account' => $account->getId()]);\n\n return $account;\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":"40","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"40","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"64","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","depth":4,"on_screen":true,"value":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","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}]...
|
-7287184300264252456
|
-8385861013499833196
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use Carbon\Carbon;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\In;
use Illuminate\Validation\ValidationException;
use InvalidArgumentException;
use Jiminny\Component\ActivityAnalytics;
use Jiminny\Component\ActivitySearch;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Queue\Constants;
use Jiminny\Contracts\ES\Events\UpdateSingleEntity;
use Jiminny\Contracts\ES\UpdateTargetEnum;
use Jiminny\Contracts\Nudge\NudgeFactoryInterface;
use Jiminny\Contracts\Playlist\PlaylistTrackFactoryInterface;
use Jiminny\Contracts\Repositories\PlaylistActivityRepository;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Enums\TeamSetting;
use Jiminny\Events\Activities\AiAutomation\ActivityProspectAdded;
use Jiminny\Events\Activities\Coaching\Coached;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Controllers\CommentContextInterface;
use Jiminny\Http\Responses\Api\AbstractResponse;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\ActivityCommentTransformer;
use Jiminny\Http\Transformers\ActivityTopicTriggerTransformer;
use Jiminny\Http\Transformers\ActivityTransformer;
use Jiminny\Http\Transformers\AvailabilityNotificationTransformer;
use Jiminny\Http\Transformers\CoachingFeedbackTransformer;
use Jiminny\Http\Transformers\CoachingSectionsTransformer;
use Jiminny\Http\Transformers\SearchTransformer;
use Jiminny\Http\Transformers\StatsTransformer;
use Jiminny\Jobs\Crm\SaveActivity;
use Jiminny\Jobs\Crm\UpdateStage;
use Jiminny\Jobs\Telephony\StartRecording;
use Jiminny\Jobs\Telephony\StopRecording;
use Jiminny\Jobs\Telephony\ToggleRecording;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\CoachingFeedback;
use Jiminny\Models\CoachingSection;
use Jiminny\Models\CoachingSectionCriterion;
use Jiminny\Models\CoachingSectionFeedback;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\LanguageDialect;
use Jiminny\Models\Lead;
use Jiminny\Models\Nudge;
use Jiminny\Models\PlaybookCategory;
use Jiminny\Models\Playlist;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\Track;
use Jiminny\Models\User;
use Jiminny\Repositories\CoachingFeedbackRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Rules\CrmReference;
use Jiminny\Rules\MultidimensionalArrayMaxCharRule;
use Jiminny\Services\ActivityService;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Services\PlaybackService;
use Jiminny\Services\UserService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
use Ramsey\Uuid\Uuid;
use Sentry;
use Symfony\Component\HttpFoundation;
final class ActivityController extends Controller implements CommentContextInterface
{
// Number of minutes to look back on activities. i.e. a timeout on activity duration.
private const int LOOK_BACK = 180;
public function __construct(
private ProviderRegistry $providerRegistry,
private ActivityService $activityService,
Response $response,
private UserService $userService,
private ActivitySearch\Service\ActivitySearch $activitySearch,
private NudgeFactoryInterface $nudgeFactory,
private ActivityCommentService $activityCommentService,
private LoggerInterface $logger,
private readonly CoachingFeedbackRepository $coachingFeedbackRepository,
private readonly TeamRepository $teamRepository,
) {
parent::__construct($response);
}
public static function getCommentImplementation(): string
{
return Comment::class;
}
public function delete()
{
$this->request->validate([
'*' => 'uuid:activities',
]);
$deletedIds = [];
foreach ($this->request->all() as $activityId) {
$activity = Activity::idOrUuId($activityId);
try {
if ($this->authorize('delete', $activity)) {
$activity->delete();
$deletedIds[] = $activityId;
\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);
}
} catch (AuthorizationException $authorizationException) {
// They didn't have permission.
}
}
return $this->response->withArray($deletedIds);
}
public function update(Request $request, Activity $activity)
{
$this->authorize('updateMetadata', $activity);
$request->validate([
'title' => 'string|max:250',
'category_id' => 'uuid:playbook_categories',
'language' => [
new In(
LanguageDialect::query()
->with('language')
->cursor()
->map(static function (LanguageDialect $languageDialect): string {
return $languageDialect->getLanguageLocale();
})
->all()
),
],
]);
if ($request->has('title')) {
$activity->title = $request->input('title');
}
if ($request->has('category_id')) {
$category = PlaybookCategory::uuid($request->input('category_id'));
if ($category->playbook->team_id !== $request->user()->team_id) {
return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
if ($request->has('language')) {
if (! $activity->isInProgress()) {
return $this->response->withError(
'Activity language can only be set while the meeting is in progress.',
400
);
}
$activity->setLanguageCode($request->input('language'));
}
$activity->save();
return $this->response->withOk();
}
// XXX: This should be merged with the update method.
/**
* @param Activity $activity
*
* @throws AuthorizationException
* @throws SocialAccountTokenInvalidException
*
* @return mixed
*/
public function summarize(Activity $activity): mixed
{
$this->logger->info('[Log Activity] Summarizing activity ', [
'activityId' => $activity->getUuid(),
'payload' => $this->request->all(),
]);
$this->authorize('update', $activity);
$this->logger->info('[Log Activity] Validating summary');
// Validate the payload.
$this->validateSummary($activity);
// All objects must belong to this team.
/** @var User $user */
$user = $this->request->user();
$team = $user->getTeam();
$crmService = $this->providerRegistry->get($team->crm->provider);
try {
$crmUser = $user;
if ($user->isCrmRequired() === false) {
$crmUser = $team->owner;
}
$crmService->setUser($crmUser);
} catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());
}
$rawEntities = $this->request->input('entities');
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid(
$this->request->input('layout_id')
);
// Delay execution of CRM jobs to avoid locking issues.
$jobDelay = 0;
// If we have arrived from a notification, mark it as read.
$notificationId = $this->request->input('nId');
if ($notificationId) {
$notification = $user->unreadNotifications->where('id', $notificationId)->first();
if ($notification) {
$notification->markAsRead();
}
}
$title = $this->request->input('title');
$prospects = $this->request->input('prospects');
$opportunityId = $this->request->input('opportunity_id');
$stageId = $this->request->input('stage_id');
$categoryId = $this->request->input('category_id');
$summary = $this->request->input('summary');
$crmProviderId = $this->request->input('crm_id');
$isInternal = $this->request->input('is_internal') ?? false;
$lead = null;
$category = null;
$account = null;
$contact = null;
$opportunity = null;
$stage = null;
$callStage = null;
foreach ($prospects as $prospectData) {
$objectId = $prospectData['id'];
if ($objectId === null) {
continue;
}
$objectType = $prospectData['type'];
$this->logger->info('debug', ['prospect_data' => $prospectData]);
try {
if ($objectType === null) {
$this->logger->info('no object type');
if ($crmService instanceof SupportsObjectTypeParseInterface) {
$objectType = $crmService->parseObjectType($objectId);
}
}
switch ($objectType) {
case 'lead':
$this->logger->info('Processing lead');
/** @var Lead|null $lead */
$lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();
// Lead does not exist locally, import it.
if ($lead === null) {
$this->logger->info('Lead does not exist locally');
/** @var Lead $lead */
$lead = $crmService->syncLead($objectId);
}
$this->logger->info('Lead found', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
if ($stageId === null) {
$this->logger->info('Stage ID is null');
// If it was not provided, just assume it is the current stage.
$callStage = $lead->stage;
break;
}
$this->logger->info('Looking for stage');
// Determine if they have changed the stage.
/** @var Stage $stage */
$stage = $team->crm->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_LEAD)
->firstOrFail();
$this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);
if ($lead->stage_id && $lead->stage_id !== $stage->id) {
$this->logger->info('Stage has changed');
// Storage current stage on activity.
$callStage = $lead->stage;
// The stage has changed, update in remote CRM.
dispatch(new UpdateStage($activity, $lead, $callStage, $stage));
$this->logger->info(
sprintf(
'[%s] User changing lead stage from %s to %s',
$crmService->getDisplayName(),
$callStage->getName(),
$stage->getName()
),
[
'user' => $user->getUuid(),
'lead' => $lead->getUuid(),
]
);
} else {
$this->logger->info('Stage has not changed');
// Stage remains as current.
$callStage = $stage;
}
break;
case 'account':
$this->logger->info('Processing account');
// If the object is not a lead, it should be an account.
$account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();
// Account does not exist locally, import it.
if ($account === null) {
$this->logger->info('Account does not exist locally');
$account = $crmService->syncAccount($objectId);
}
$this->logger->info('Account found', ['accountId' => $account->id]);
break;
case 'contact':
$this->logger->info('processing contact');
$contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$this->logger->info('contact does not exist locally');
$contact = $crmService->syncContact($objectId);
}
$this->logger->info('resolving account');
$account = $this->resolveAccount($team, $contact, $crmService, $prospects);
break;
}
// If they have specified an opportunity, retrieve this with stage.
if ($opportunityId) {
$this->logger->info('opportunity id is set');
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if ($opportunity === null) {
$this->logger->info('opportunity does not exist locally');
$opportunity = $crmService->syncOpportunity($opportunityId);
}
if ($stageId === null) {
$this->logger->info('stage id is null');
// If it was not provided, just assume it is the current stage.
$callStage = $opportunity->stage ?? null;
} else {
$this->logger->info('looking for stage');
/** @var ?Stage $opportunityStage */
$opportunityStage = $team->crm
->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
// There is a chance we still cannot import this opportunity.
if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {
$this->logger->info('opportunity stage has changed');
// Storage current stage on activity.
$callStage = $opportunity->stage;
dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));
$this->logger->info(
sprintf(
'[%s] User changing opportunity stage from %s to %s',
$crmService->getDisplayName(),
$callStage->name,
$opportunityStage->name
),
[
'userId' => $user->id_string,
'opportunityId' => $opportunity->id_string,
]
);
} else {
$this->logger->info('opportunity stage has not changed');
// Stage remains as current.
$callStage = $opportunityStage;
}
}
}
if ($crmProviderId) {
// Cast $crmProviderId to string otherwise it won't use database index for some records
$linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();
// Check if this activity has already been assigned to a different activity.
if ($linkedActivity && $linkedActivity->id !== $activity->id) {
throw new InvalidArgumentException(
'Sorry, the linked task has already been logged under a different call. '
. 'Please choose another linked task.'
);
}
}
} catch (InvalidArgumentException $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($exception->getMessage());
} catch (Exception $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorInternalError(
'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'
);
}
}
if ($categoryId) {
$category = PlaybookCategory::uuid($categoryId);
if ($category->playbook->team_id !== $team->id) {
throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
$this->logger->info('Prospect data', [
'lead_id' => $lead?->getId(),
'account_id' => $account?->getId(),
'contact_id' => $contact?->getId(),
'opportunity_id' => $opportunity?->getId(),
'stage_id' => $stage?->getId(),
]);
if ($title) {
$activity->title = $title;
}
if ($summary) {
$activity->summary = $summary;
}
if ($crmProviderId) {
$activity->crm_provider_id = $crmProviderId;
}
if ($callStage) {
$this->logger->info('Setting stage id', ['stageId' => $callStage->id]);
$activity->stage_id = $callStage->id;
}
if ($lead) {
$this->logger->info('Setting lead id', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
// If we are changed from an account > lead, unset the account data.
$this->logger->info('Unsetting account id, opportunity id, contact id, value');
$activity->account_id = null;
$activity->opportunity_id = null;
$activity->contact_id = null;
$activity->value = null;
}
if ($account) {
$this->logger->info('Setting account id', ['accountId' => $account->id]);
$activity->account_id = $account->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('unsetting lead id');
$activity->lead_id = null;
// Unset the contact if switching different accounts. Will be set up below if still applicable.
if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {
$this->logger->info('Unsetting contact id');
$activity->contact_id = null;
}
}
if ($opportunity) {
$this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);
$this->logger->info('unsetting lead id');
$activity->opportunity_id = $opportunity->id;
$activity->value = $opportunity->value;
// If we are changed from an lead > account, unset the lead data.
$activity->lead_id = null;
}
if ($contact) {
$this->logger->info('setting contact id', ['contactId' => $contact->id]);
$activity->contact_id = $contact->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('Unsetting lead id');
$activity->lead_id = null;
}
$activity->is_internal = $isInternal;
$activity->save();
$activity->refresh();
$this->logger->notice('Activity saved', [
'activity_id' => $activity->getId(),
'lead_id' => $activity->lead_id,
'account_id' => $activity->account_id,
'contact_id' => $activity->contact_id,
'opportunity_id' => $activity->opportunity_id,
'stage_id' => $activity->stage_id,
'crm_provider_id' => $activity->getCrmProviderId(),
]);
// Store entities as field data on the activity.
$updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);
if ($activity->isLoggable()) {
// Follow-up Task or Event data.
$followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);
$this->logger->info('CRM LOG manual log triggered', [
'activityId' => $activity->getUuid(),
'followupData' => $followupData,
'userId' => $user->getUuid(),
]);
// Store data in the CRM.
// ++add check for crm_required
$job = new SaveActivity($activity, $followupData);
if ($updatedData) {
$job->delay(Carbon::now()->addMinutes($jobDelay));
}
dispatch($job);
// Manually dispatch log for Opportunity or Prospect added
if ($activity->hasOpportunity() || $activity->hasProspect()) {
event(new ActivityProspectAdded(
activity: $activity,
eventSource: 'manually-log-crm-data'
));
}
}
return $this->response->withOk();
}
/**
* Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.
*
* @param ServiceInterface $service
* @param Activity $activity
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array
{
$updatedData = [];
$existingData = $activity->data()->get();
// We need to delete any existing data to overwrite with latest values.
$activity->data()->delete();
$layoutEntities = $layout->entities()
->with('field', 'parent')
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->get();
/** @var LayoutEntity $entity */
foreach ($layoutEntities as $entity) {
// If the user has provided a value for this entity
if (array_key_exists($entity->id_string, $entities)) {
$value = $entities[$entity->id_string];
// Convert raw data into values that the CRM can consume.
if ($value) {
$value = $service->normalizeValue($entity->field->type, $value);
}
// Check the field is part of the activity-summary section.
if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {
// This is the internal database ID, not the external CRM ID.
$objectId = null;
switch ($entity->field->object_type) {
case Field::OBJECT_ACCOUNT:
$objectId = $activity->account_id;
break;
case Field::OBJECT_CONTACT:
$objectId = $activity->contact_id;
break;
case Field::OBJECT_OPPORTUNITY:
$objectId = $activity->opportunity_id;
break;
case Field::OBJECT_LEAD:
$objectId = $activity->lead_id;
break;
case Field::OBJECT_TASK:
case Field::OBJECT_EVENT:
$objectId = $activity->id;
break;
}
if ($objectId) {
/** @var FieldData $data */
$data = $activity->data()->create([
'crm_layout_entity_id' => $entity->id,
'crm_field_id' => $entity->crm_field_id,
'object_type' => $entity->field->object_type,
'object_id' => $objectId,
'value' => $value,
]);
// Never send read-only field data to the CRM.
if ($entity->read_only === false && $entity->is_visible) {
$existingValue = $existingData
->where('crm_layout_entity_id', $entity->id)
->where('crm_field_id', $entity->crm_field_id)
->where('object_type', $entity->field->object_type)
->where('object_id', $objectId)
->first();
// If the field was actually changed, we need to reflect this in the CRM too.
if ($existingValue === null || $existingValue->value !== $value) {
$updatedData[] = $data->id;
}
}
}
}
}
}
return $updatedData;
}
/**
* Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.
*
* @param ServiceInterface $crmService
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array
{
$fieldData = [];
foreach ($entities as $entityId => $value) {
// Only bother with fields that have a value.
if ($value) {
// Extract the entity from the UUID. Check the field is valid and part of the follow-up section.
$entity = $layout->entities()
->uuid($entityId, false)
->whereHas('parent', function ($query) {
$query->where('label', 'follow-up');
})
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->first();
if ($entity) {
// Convert raw data into values that the CRM can consume.
$value = $crmService->normalizeValue($entity->field->type, $value);
// Add the field and value to the payload.
$fieldData += [
$entity->field->crm_provider_id => $value,
];
}
}
}
return $fieldData;
}
/**
* @param Activity $activity
*/
private function validateSummary(Activity $activity): void
{
$team = $activity->user->team;
$crmProvider = $team->crm->provider;
$attributes = [];
$rules = [
'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,
'title' => 'string|max:250',
'prospects' => 'required|array',
'opportunity_id' => new CrmReference($crmProvider),
'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',
'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator
'summary' => 'max:50000',
'nId' => 'exists:notifications,id',
'crm_id' => new CrmReference($crmProvider),
'entities' => 'array',
'is_internal' => 'boolean',
];
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));
// Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.
$entities = $layout->entities()
->where('read_only', 0)
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->whereHas('parent', function ($query) use ($activity) {
if ($activity->isLoggable() === false) {
$query->where('label', '<>', 'follow-up');
}
});
$isInternal = $this->request->input('is_internal', false);
foreach ($entities->get() as $entity) {
$rules += $this->buildFieldValidator($entity, $isInternal);
$attributes += $this->buildFieldMessage($entity);
}
$this->request->validate($rules, [], $attributes);
}
private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array
{
return [
'entities.' . $entity->id_string => $entity->getValidator($isInternal),
];
}
/**
* @param LayoutEntity $entity
*
* @return array
*/
private function buildFieldMessage(LayoutEntity $entity): array
{
$label = $entity->label;
if ($label === null) {
$label = $entity->field->label;
}
return [
'entities.' . $entity->id_string => $label,
];
}
public function search(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->debugLog(
$user,
'User extracted from request',
['user' => $user->getId(), 'tz' => $user->getTimezone()]
);
$searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());
$this->debugLog(
$user,
'ActivitySearch criteria built',
['searchCriteria' => $searchCriteria]
);
$filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);
$this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);
$this->validateSearch($request, $filterSet);
$this->debugLog($user, 'Request validated');
$searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);
/** @var Collection<Activity> $activities */
$activities = $searchResponse['results'];
$this->debugLog($user, 'Activities ES response extracted');
$hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(
$user->getTeamId(),
TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),
);
if ($hideInternalMeetingsSetting?->getValue() === '1') {
$activities = $activities->filter(function (Activity $activity) {
if ($activity->is_internal && empty($activity->actual_start_time)) {
return false;
}
return true;
});
}
$this->debugLog($user, 'Internal meetings (?!) filtered');
$this->response->getManager()
->parseIncludes([
'category',
'organizer.group',
'prospect',
'stage',
'opportunity',
'stats',
'scorecards',
'masterTrack',
'activeParticipants',
'notification',
])
->setSerializer(new JsonSerializer());
$transformerExcludes = $this->request->input('exclude');
if ($transformerExcludes) {
$this->response->getManager()->parseExcludes($transformerExcludes);
}
$this->debugLog($user, 'Response Manager (?!) applied');
$transformer = new ActivityTransformer();
$transformer->setConsumer($user);
$this->debugLog($user, 'Activity Transformer added');
$resource = new \League\Fractal\Resource\Collection($activities, $transformer);
$page = $searchCriteria->getPageNumber();
$this->debugLog($user, 'Search criteria page number called', ['page' => $page]);
$histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');
$this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);
return $this->response->withArray([
'pagination' => [
'total' => $searchResponse['totalHits'],
'current' => $page,
'prev' => max($page - 1, 1),
'next' => $page + 1,
],
'results' => $this->response->getManager()->createData($resource)->toArray(),
'histogram' => $histogram,
]);
}
private function debugLog(User $user, string $logMessage, ?array $context = []): void
{
// Debug for Learning People Only
if ($user->getTeamId() !== 260) {
return;
}
Log::notice(
sprintf('[activity-search-controller] %s', $logMessage),
$context
);
}
/** @throws ValidationException */
private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void
{
$rules = [
'exclude' => 'array',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
];
if ($prefix !== null && mb_strpos($prefix, '.') !== false) {
$rules[rtrim($prefix, '.')] = sprintf(
'required|array|max:%d',
$filterSet->count()
);
}
$validationRules = $filterSet->getValidationRules($prefix)
->merge($rules)
->all();
$request->validate($validationRules);
}
public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$search = $this->updateOrCreateActivitySearch($request);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function updateActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('update', $search);
$this->updateOrCreateActivitySearch($request, $search);
return $this->response->withOk();
}
private function storeNamedSearchFilters(
Collection $request,
Search $search,
FilterDefinitionCollection $filterSet,
?string $prefix = null,
): self {
$arrayTypeProperties = $filterSet
->getPropertyTypes([
FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,
])
->all();
$supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);
foreach ($supportedRequestProperties as $requestPropertyName) {
if (! array_has($request, $requestPropertyName)) {
continue;
}
/** @var string|string[] $propertyValue */
$propertyValue = array_get($request, $requestPropertyName);
$propertyName = $prefix === null
? $requestPropertyName
: mb_substr($requestPropertyName, mb_strlen($prefix));
$isArrayType = array_has($arrayTypeProperties, $propertyName);
if (! $isArrayType) {
/** @var string $requestPropertyValue */
$search->filters()->updateOrCreate(
[
'filter' => $propertyName,
],
[
'value' => $propertyValue,
]
);
continue;
}
/** @var string[] $requestPropertyValue */
/** @var SearchFilter[]|Collection $existingFilterValues */
$existingFilterValuesKeyed = $search->filters()
->where('filter', $propertyName)
->get()
->keyBy('id');
// Iterate over values provided as request parameters
foreach ($propertyValue as $value) {
/** @var SearchFilter|null $valueFilter */
$valueFilter = $search->filters()
->where(
[
'filter' => $propertyName,
'value' => $value,
]
)
->first();
if ($valueFilter !== null) {
// Remove filter value pair from list to be deleted
$existingFilterValuesKeyed->forget($valueFilter->id);
} else {
// Add new filter/value pair
$search->filters()->updateOrCreate([
'filter' => $propertyName,
'value' => $value,
]);
}
}
// Delete filter value pairs for this filter that no longer exist in request parameters
foreach ($existingFilterValuesKeyed as $existingFilter) {
$existingFilter->delete();
}
}
/** @var Collection<int, SearchFilter> $filtersKeyed */
$filtersKeyed = $search->filters()->get()->keyBy('filter');
// wipe removed filters from this search
foreach ($filtersKeyed as $filterName => $filter) {
if (array_has($request, $prefix . $filterName)) {
continue;
}
// Remove all filter values for this filter
$search->filters()->where('filter', $filterName)->delete();
}
return $this;
}
/**
* @throws AuthorizationException
*/
public function fetchActivitySearch(
Search $search,
Request $request,
SearchTransformer $searchTransformer,
): JsonResponse {
$this->authorize('view', $search);
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withCollection(
$user->searches()->get(),
$searchTransformer
->withConsumer($user)
);
}
/**
* Deletes a saved search
*
* @param Request $request
* @param Search $search
*
* @throws Exception
*
* @return JsonResponse
*/
public function deleteActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('delete', $search);
// Orphan any AutomatedReports that use this search
$search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);
// Delete filters and the search itself
$search->filters()->delete();
$search->delete();
return $this->response->withOk();
}
public function live(Request $request, ElasticActivityRepository $repository): JsonResponse
{
$user = $this->getUserFromRequest($request);
$this->request->validate([
'sort_direction' => 'in:asc,desc',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
]);
$activities = $repository->getLiveCoachingEligibleActivities(
user: $user,
lookBackMinutes: self::LOOK_BACK,
limit: (int) $this->request->input('limit', 25),
page: (int) $this->request->input('page', 1),
sortBy: ['actual_start_time', 'scheduled_start_time'],
sortDirection: (string) $this->request->input('sort_direction', 'asc'),
);
$this->response
->getManager()
->parseIncludes(['organizer.group', 'prospect'])
->setSerializer(new JsonSerializer());
return $this->response->withCollection($activities, new ActivityTransformer());
}
/**
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function show(Activity $activity, ActivityService $activityService): JsonResponse
{
$this->authorize('show', $activity);
$user = $activity->getUser();
$team = $user->getTeam();
// Sync the opportunity with the latest data if possible.
if ($activity->opportunity_id) {
try {
$crmService = $this->providerRegistry->get($team->crm->provider);
if (! $user->isCrmRequired()) {
$crmService->setUser($team->getOwner());
} else {
$crmService->setUser($user);
}
$crmService->syncOpportunity($activity->opportunity->crm_provider_id);
} catch (Exception $exception) {
// Move on.
}
}
$activityData = $activityService->getActivityData($this->request->user(), $activity);
return response()->json($activityData);
}
public function createRecording(Activity $activity)
{
$this->authorize('record', $activity);
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Tell Twilio to start recording this activity.
if ($activity->recording_state === Activity::RECORDING_OFF) {
$job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withCreated();
}
return $this->response->errorGone('Activity is already recording.');
}
public function updateRecording(Request $request, Activity $activity)
{
$this->authorize('record', $activity);
$request->validate([
'preference' => 'boolean',
'state' => [
'string',
Rule::in([
Activity::RECORDING_IN_PROGRESS,
Activity::RECORDING_PAUSED,
]),
],
]);
if ($request->has('state')) {
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Toggle the recording state between paused and resumed.
if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {
$job = (new ToggleRecording($activity, $request->input('state')))
->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Recording is not toggleable.');
}
if ($request->has('preference')) {
$activity->update([
'recording_preference' => $request->input('preference') ? 1 : 0,
]);
return $this->response->withOk();
}
return $this->response->errorWrongArgs('Something went wrong');
}
public function stopRecording(Activity $activity)
{
$this->authorize('stopRecord', $activity);
// Tell Twilio to stop recording this activity.
if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {
$job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Activity is not recording.');
}
/**
* Add activity to this user's favorites playlist
*
* @throws AuthorizationException
*/
public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse
{
$this->authorize('favorite', $activity);
$user = $this->getUserFromRequest($this->request);
$favorite = $activity->wasFavoritedBy($user);
$name = $activity->activity_title ?? '';
// It needs to check at least one record.
if (! $favorite) {
$favoritePlaylist = $user->favoritePlaylist();
$playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(
$activity,
$user,
$favoritePlaylist
);
if ($playlistActivity !== null) {
$playlistActivity->update(
// Just update, don't sort.
['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],
);
} else {
$playlistActivity = $activity->playlistActivities()->create([
'playlist_id' => $favoritePlaylist->getId(),
'user_id' => $user->getId(),
'start_time' => 0,
'name' => mb_strimwidth($name, 0, 100),
]);
// Sort it on top.
$playlistActivity->update(
[
'sort' => $playlistActivityRepository->calculateNewSortOrder(
null,
$playlistActivity,
),
],
);
}
$playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);
return new JsonResponse([], JsonResponse::HTTP_CREATED);
}
return new JsonResponse(
[
'error' => [
'code' => AbstractResponse::CODE_CONFLICT,
'http_code' => JsonResponse::HTTP_CONFLICT,
'message' => 'Resource Already Exists',
],
],
JsonResponse::HTTP_CONFLICT,
);
}
/**
* Remove activity from this user's favorites playlist
*
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function unfavorite(Activity $activity)
{
$user = $t...
|
32857
|
NULL
|
NULL
|
NULL
|
|
32860
|
1255
|
38
|
2026-05-13T09:40:41.403461+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665241403_m2.jpg...
|
PhpStorm
|
faVsco.js – ActivityController.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use Carbon\Carbon;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\In;
use Illuminate\Validation\ValidationException;
use InvalidArgumentException;
use Jiminny\Component\ActivityAnalytics;
use Jiminny\Component\ActivitySearch;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Queue\Constants;
use Jiminny\Contracts\ES\Events\UpdateSingleEntity;
use Jiminny\Contracts\ES\UpdateTargetEnum;
use Jiminny\Contracts\Nudge\NudgeFactoryInterface;
use Jiminny\Contracts\Playlist\PlaylistTrackFactoryInterface;
use Jiminny\Contracts\Repositories\PlaylistActivityRepository;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Enums\TeamSetting;
use Jiminny\Events\Activities\AiAutomation\ActivityProspectAdded;
use Jiminny\Events\Activities\Coaching\Coached;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Controllers\CommentContextInterface;
use Jiminny\Http\Responses\Api\AbstractResponse;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\ActivityCommentTransformer;
use Jiminny\Http\Transformers\ActivityTopicTriggerTransformer;
use Jiminny\Http\Transformers\ActivityTransformer;
use Jiminny\Http\Transformers\AvailabilityNotificationTransformer;
use Jiminny\Http\Transformers\CoachingFeedbackTransformer;
use Jiminny\Http\Transformers\CoachingSectionsTransformer;
use Jiminny\Http\Transformers\SearchTransformer;
use Jiminny\Http\Transformers\StatsTransformer;
use Jiminny\Jobs\Crm\SaveActivity;
use Jiminny\Jobs\Crm\UpdateStage;
use Jiminny\Jobs\Telephony\StartRecording;
use Jiminny\Jobs\Telephony\StopRecording;
use Jiminny\Jobs\Telephony\ToggleRecording;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\CoachingFeedback;
use Jiminny\Models\CoachingSection;
use Jiminny\Models\CoachingSectionCriterion;
use Jiminny\Models\CoachingSectionFeedback;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\LanguageDialect;
use Jiminny\Models\Lead;
use Jiminny\Models\Nudge;
use Jiminny\Models\PlaybookCategory;
use Jiminny\Models\Playlist;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\Track;
use Jiminny\Models\User;
use Jiminny\Repositories\CoachingFeedbackRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Rules\CrmReference;
use Jiminny\Rules\MultidimensionalArrayMaxCharRule;
use Jiminny\Services\ActivityService;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Services\PlaybackService;
use Jiminny\Services\UserService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
use Ramsey\Uuid\Uuid;
use Sentry;
use Symfony\Component\HttpFoundation;
final class ActivityController extends Controller implements CommentContextInterface
{
// Number of minutes to look back on activities. i.e. a timeout on activity duration.
private const int LOOK_BACK = 180;
public function __construct(
private ProviderRegistry $providerRegistry,
private ActivityService $activityService,
Response $response,
private UserService $userService,
private ActivitySearch\Service\ActivitySearch $activitySearch,
private NudgeFactoryInterface $nudgeFactory,
private ActivityCommentService $activityCommentService,
private LoggerInterface $logger,
private readonly CoachingFeedbackRepository $coachingFeedbackRepository,
private readonly TeamRepository $teamRepository,
) {
parent::__construct($response);
}
public static function getCommentImplementation(): string
{
return Comment::class;
}
public function delete()
{
$this->request->validate([
'*' => 'uuid:activities',
]);
$deletedIds = [];
foreach ($this->request->all() as $activityId) {
$activity = Activity::idOrUuId($activityId);
try {
if ($this->authorize('delete', $activity)) {
$activity->delete();
$deletedIds[] = $activityId;
\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);
}
} catch (AuthorizationException $authorizationException) {
// They didn't have permission.
}
}
return $this->response->withArray($deletedIds);
}
public function update(Request $request, Activity $activity)
{
$this->authorize('updateMetadata', $activity);
$request->validate([
'title' => 'string|max:250',
'category_id' => 'uuid:playbook_categories',
'language' => [
new In(
LanguageDialect::query()
->with('language')
->cursor()
->map(static function (LanguageDialect $languageDialect): string {
return $languageDialect->getLanguageLocale();
})
->all()
),
],
]);
if ($request->has('title')) {
$activity->title = $request->input('title');
}
if ($request->has('category_id')) {
$category = PlaybookCategory::uuid($request->input('category_id'));
if ($category->playbook->team_id !== $request->user()->team_id) {
return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
if ($request->has('language')) {
if (! $activity->isInProgress()) {
return $this->response->withError(
'Activity language can only be set while the meeting is in progress.',
400
);
}
$activity->setLanguageCode($request->input('language'));
}
$activity->save();
return $this->response->withOk();
}
// XXX: This should be merged with the update method.
/**
* @param Activity $activity
*
* @throws AuthorizationException
* @throws SocialAccountTokenInvalidException
*
* @return mixed
*/
public function summarize(Activity $activity): mixed
{
$this->logger->info('[Log Activity] Summarizing activity ', [
'activityId' => $activity->getUuid(),
'payload' => $this->request->all(),
]);
$this->authorize('update', $activity);
$this->logger->info('[Log Activity] Validating summary');
// Validate the payload.
$this->validateSummary($activity);
// All objects must belong to this team.
/** @var User $user */
$user = $this->request->user();
$team = $user->getTeam();
$crmService = $this->providerRegistry->get($team->crm->provider);
try {
$crmUser = $user;
if ($user->isCrmRequired() === false) {
$crmUser = $team->owner;
}
$crmService->setUser($crmUser);
} catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());
}
$rawEntities = $this->request->input('entities');
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid(
$this->request->input('layout_id')
);
// Delay execution of CRM jobs to avoid locking issues.
$jobDelay = 0;
// If we have arrived from a notification, mark it as read.
$notificationId = $this->request->input('nId');
if ($notificationId) {
$notification = $user->unreadNotifications->where('id', $notificationId)->first();
if ($notification) {
$notification->markAsRead();
}
}
$title = $this->request->input('title');
$prospects = $this->request->input('prospects');
$opportunityId = $this->request->input('opportunity_id');
$stageId = $this->request->input('stage_id');
$categoryId = $this->request->input('category_id');
$summary = $this->request->input('summary');
$crmProviderId = $this->request->input('crm_id');
$isInternal = $this->request->input('is_internal') ?? false;
$lead = null;
$category = null;
$account = null;
$contact = null;
$opportunity = null;
$stage = null;
$callStage = null;
foreach ($prospects as $prospectData) {
$objectId = $prospectData['id'];
if ($objectId === null) {
continue;
}
$objectType = $prospectData['type'];
$this->logger->info('debug', ['prospect_data' => $prospectData]);
try {
if ($objectType === null) {
$this->logger->info('no object type');
if ($crmService instanceof SupportsObjectTypeParseInterface) {
$objectType = $crmService->parseObjectType($objectId);
}
}
switch ($objectType) {
case 'lead':
$this->logger->info('Processing lead');
/** @var Lead|null $lead */
$lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();
// Lead does not exist locally, import it.
if ($lead === null) {
$this->logger->info('Lead does not exist locally');
/** @var Lead $lead */
$lead = $crmService->syncLead($objectId);
}
$this->logger->info('Lead found', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
if ($stageId === null) {
$this->logger->info('Stage ID is null');
// If it was not provided, just assume it is the current stage.
$callStage = $lead->stage;
break;
}
$this->logger->info('Looking for stage');
// Determine if they have changed the stage.
/** @var Stage $stage */
$stage = $team->crm->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_LEAD)
->firstOrFail();
$this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);
if ($lead->stage_id && $lead->stage_id !== $stage->id) {
$this->logger->info('Stage has changed');
// Storage current stage on activity.
$callStage = $lead->stage;
// The stage has changed, update in remote CRM.
dispatch(new UpdateStage($activity, $lead, $callStage, $stage));
$this->logger->info(
sprintf(
'[%s] User changing lead stage from %s to %s',
$crmService->getDisplayName(),
$callStage->getName(),
$stage->getName()
),
[
'user' => $user->getUuid(),
'lead' => $lead->getUuid(),
]
);
} else {
$this->logger->info('Stage has not changed');
// Stage remains as current.
$callStage = $stage;
}
break;
case 'account':
$this->logger->info('Processing account');
// If the object is not a lead, it should be an account.
$account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();
// Account does not exist locally, import it.
if ($account === null) {
$this->logger->info('Account does not exist locally');
$account = $crmService->syncAccount($objectId);
}
$this->logger->info('Account found', ['accountId' => $account->id]);
break;
case 'contact':
$this->logger->info('processing contact');
$contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$this->logger->info('contact does not exist locally');
$contact = $crmService->syncContact($objectId);
}
$this->logger->info('resolving account');
$account = $this->resolveAccount($team, $contact, $crmService, $prospects);
break;
}
// If they have specified an opportunity, retrieve this with stage.
if ($opportunityId) {
$this->logger->info('opportunity id is set');
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if ($opportunity === null) {
$this->logger->info('opportunity does not exist locally');
$opportunity = $crmService->syncOpportunity($opportunityId);
}
if ($stageId === null) {
$this->logger->info('stage id is null');
// If it was not provided, just assume it is the current stage.
$callStage = $opportunity->stage ?? null;
} else {
$this->logger->info('looking for stage');
/** @var ?Stage $opportunityStage */
$opportunityStage = $team->crm
->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
// There is a chance we still cannot import this opportunity.
if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {
$this->logger->info('opportunity stage has changed');
// Storage current stage on activity.
$callStage = $opportunity->stage;
dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));
$this->logger->info(
sprintf(
'[%s] User changing opportunity stage from %s to %s',
$crmService->getDisplayName(),
$callStage->name,
$opportunityStage->name
),
[
'userId' => $user->id_string,
'opportunityId' => $opportunity->id_string,
]
);
} else {
$this->logger->info('opportunity stage has not changed');
// Stage remains as current.
$callStage = $opportunityStage;
}
}
}
if ($crmProviderId) {
// Cast $crmProviderId to string otherwise it won't use database index for some records
$linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();
// Check if this activity has already been assigned to a different activity.
if ($linkedActivity && $linkedActivity->id !== $activity->id) {
throw new InvalidArgumentException(
'Sorry, the linked task has already been logged under a different call. '
. 'Please choose another linked task.'
);
}
}
} catch (InvalidArgumentException $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($exception->getMessage());
} catch (Exception $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorInternalError(
'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'
);
}
}
if ($categoryId) {
$category = PlaybookCategory::uuid($categoryId);
if ($category->playbook->team_id !== $team->id) {
throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
$this->logger->info('Prospect data', [
'lead_id' => $lead?->getId(),
'account_id' => $account?->getId(),
'contact_id' => $contact?->getId(),
'opportunity_id' => $opportunity?->getId(),
'stage_id' => $stage?->getId(),
]);
if ($title) {
$activity->title = $title;
}
if ($summary) {
$activity->summary = $summary;
}
if ($crmProviderId) {
$activity->crm_provider_id = $crmProviderId;
}
if ($callStage) {
$this->logger->info('Setting stage id', ['stageId' => $callStage->id]);
$activity->stage_id = $callStage->id;
}
if ($lead) {
$this->logger->info('Setting lead id', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
// If we are changed from an account > lead, unset the account data.
$this->logger->info('Unsetting account id, opportunity id, contact id, value');
$activity->account_id = null;
$activity->opportunity_id = null;
$activity->contact_id = null;
$activity->value = null;
}
if ($account) {
$this->logger->info('Setting account id', ['accountId' => $account->id]);
$activity->account_id = $account->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('unsetting lead id');
$activity->lead_id = null;
// Unset the contact if switching different accounts. Will be set up below if still applicable.
if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {
$this->logger->info('Unsetting contact id');
$activity->contact_id = null;
}
}
if ($opportunity) {
$this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);
$this->logger->info('unsetting lead id');
$activity->opportunity_id = $opportunity->id;
$activity->value = $opportunity->value;
// If we are changed from an lead > account, unset the lead data.
$activity->lead_id = null;
}
if ($contact) {
$this->logger->info('setting contact id', ['contactId' => $contact->id]);
$activity->contact_id = $contact->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('Unsetting lead id');
$activity->lead_id = null;
}
$activity->is_internal = $isInternal;
$activity->save();
$activity->refresh();
$this->logger->notice('Activity saved', [
'activity_id' => $activity->getId(),
'lead_id' => $activity->lead_id,
'account_id' => $activity->account_id,
'contact_id' => $activity->contact_id,
'opportunity_id' => $activity->opportunity_id,
'stage_id' => $activity->stage_id,
'crm_provider_id' => $activity->getCrmProviderId(),
]);
// Store entities as field data on the activity.
$updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);
if ($activity->isLoggable()) {
// Follow-up Task or Event data.
$followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);
$this->logger->info('CRM LOG manual log triggered', [
'activityId' => $activity->getUuid(),
'followupData' => $followupData,
'userId' => $user->getUuid(),
]);
// Store data in the CRM.
// ++add check for crm_required
$job = new SaveActivity($activity, $followupData);
if ($updatedData) {
$job->delay(Carbon::now()->addMinutes($jobDelay));
}
dispatch($job);
// Manually dispatch log for Opportunity or Prospect added
if ($activity->hasOpportunity() || $activity->hasProspect()) {
event(new ActivityProspectAdded(
activity: $activity,
eventSource: 'manually-log-crm-data'
));
}
}
return $this->response->withOk();
}
/**
* Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.
*
* @param ServiceInterface $service
* @param Activity $activity
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array
{
$updatedData = [];
$existingData = $activity->data()->get();
// We need to delete any existing data to overwrite with latest values.
$activity->data()->delete();
$layoutEntities = $layout->entities()
->with('field', 'parent')
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->get();
/** @var LayoutEntity $entity */
foreach ($layoutEntities as $entity) {
// If the user has provided a value for this entity
if (array_key_exists($entity->id_string, $entities)) {
$value = $entities[$entity->id_string];
// Convert raw data into values that the CRM can consume.
if ($value) {
$value = $service->normalizeValue($entity->field->type, $value);
}
// Check the field is part of the activity-summary section.
if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {
// This is the internal database ID, not the external CRM ID.
$objectId = null;
switch ($entity->field->object_type) {
case Field::OBJECT_ACCOUNT:
$objectId = $activity->account_id;
break;
case Field::OBJECT_CONTACT:
$objectId = $activity->contact_id;
break;
case Field::OBJECT_OPPORTUNITY:
$objectId = $activity->opportunity_id;
break;
case Field::OBJECT_LEAD:
$objectId = $activity->lead_id;
break;
case Field::OBJECT_TASK:
case Field::OBJECT_EVENT:
$objectId = $activity->id;
break;
}
if ($objectId) {
/** @var FieldData $data */
$data = $activity->data()->create([
'crm_layout_entity_id' => $entity->id,
'crm_field_id' => $entity->crm_field_id,
'object_type' => $entity->field->object_type,
'object_id' => $objectId,
'value' => $value,
]);
// Never send read-only field data to the CRM.
if ($entity->read_only === false && $entity->is_visible) {
$existingValue = $existingData
->where('crm_layout_entity_id', $entity->id)
->where('crm_field_id', $entity->crm_field_id)
->where('object_type', $entity->field->object_type)
->where('object_id', $objectId)
->first();
// If the field was actually changed, we need to reflect this in the CRM too.
if ($existingValue === null || $existingValue->value !== $value) {
$updatedData[] = $data->id;
}
}
}
}
}
}
return $updatedData;
}
/**
* Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.
*
* @param ServiceInterface $crmService
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array
{
$fieldData = [];
foreach ($entities as $entityId => $value) {
// Only bother with fields that have a value.
if ($value) {
// Extract the entity from the UUID. Check the field is valid and part of the follow-up section.
$entity = $layout->entities()
->uuid($entityId, false)
->whereHas('parent', function ($query) {
$query->where('label', 'follow-up');
})
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->first();
if ($entity) {
// Convert raw data into values that the CRM can consume.
$value = $crmService->normalizeValue($entity->field->type, $value);
// Add the field and value to the payload.
$fieldData += [
$entity->field->crm_provider_id => $value,
];
}
}
}
return $fieldData;
}
/**
* @param Activity $activity
*/
private function validateSummary(Activity $activity): void
{
$team = $activity->user->team;
$crmProvider = $team->crm->provider;
$attributes = [];
$rules = [
'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,
'title' => 'string|max:250',
'prospects' => 'required|array',
'opportunity_id' => new CrmReference($crmProvider),
'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',
'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator
'summary' => 'max:50000',
'nId' => 'exists:notifications,id',
'crm_id' => new CrmReference($crmProvider),
'entities' => 'array',
'is_internal' => 'boolean',
];
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));
// Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.
$entities = $layout->entities()
->where('read_only', 0)
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->whereHas('parent', function ($query) use ($activity) {
if ($activity->isLoggable() === false) {
$query->where('label', '<>', 'follow-up');
}
});
$isInternal = $this->request->input('is_internal', false);
foreach ($entities->get() as $entity) {
$rules += $this->buildFieldValidator($entity, $isInternal);
$attributes += $this->buildFieldMessage($entity);
}
$this->request->validate($rules, [], $attributes);
}
private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array
{
return [
'entities.' . $entity->id_string => $entity->getValidator($isInternal),
];
}
/**
* @param LayoutEntity $entity
*
* @return array
*/
private function buildFieldMessage(LayoutEntity $entity): array
{
$label = $entity->label;
if ($label === null) {
$label = $entity->field->label;
}
return [
'entities.' . $entity->id_string => $label,
];
}
public function search(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->debugLog(
$user,
'User extracted from request',
['user' => $user->getId(), 'tz' => $user->getTimezone()]
);
$searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());
$this->debugLog(
$user,
'ActivitySearch criteria built',
['searchCriteria' => $searchCriteria]
);
$filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);
$this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);
$this->validateSearch($request, $filterSet);
$this->debugLog($user, 'Request validated');
$searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);
/** @var Collection<Activity> $activities */
$activities = $searchResponse['results'];
$this->debugLog($user, 'Activities ES response extracted');
$hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(
$user->getTeamId(),
TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),
);
if ($hideInternalMeetingsSetting?->getValue() === '1') {
$activities = $activities->filter(function (Activity $activity) {
if ($activity->is_internal && empty($activity->actual_start_time)) {
return false;
}
return true;
});
}
$this->debugLog($user, 'Internal meetings (?!) filtered');
$this->response->getManager()
->parseIncludes([
'category',
'organizer.group',
'prospect',
'stage',
'opportunity',
'stats',
'scorecards',
'masterTrack',
'activeParticipants',
'notification',
])
->setSerializer(new JsonSerializer());
$transformerExcludes = $this->request->input('exclude');
if ($transformerExcludes) {
$this->response->getManager()->parseExcludes($transformerExcludes);
}
$this->debugLog($user, 'Response Manager (?!) applied');
$transformer = new ActivityTransformer();
$transformer->setConsumer($user);
$this->debugLog($user, 'Activity Transformer added');
$resource = new \League\Fractal\Resource\Collection($activities, $transformer);
$page = $searchCriteria->getPageNumber();
$this->debugLog($user, 'Search criteria page number called', ['page' => $page]);
$histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');
$this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);
return $this->response->withArray([
'pagination' => [
'total' => $searchResponse['totalHits'],
'current' => $page,
'prev' => max($page - 1, 1),
'next' => $page + 1,
],
'results' => $this->response->getManager()->createData($resource)->toArray(),
'histogram' => $histogram,
]);
}
private function debugLog(User $user, string $logMessage, ?array $context = []): void
{
// Debug for Learning People Only
if ($user->getTeamId() !== 260) {
return;
}
Log::notice(
sprintf('[activity-search-controller] %s', $logMessage),
$context
);
}
/** @throws ValidationException */
private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void
{
$rules = [
'exclude' => 'array',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
];
if ($prefix !== null && mb_strpos($prefix, '.') !== false) {
$rules[rtrim($prefix, '.')] = sprintf(
'required|array|max:%d',
$filterSet->count()
);
}
$validationRules = $filterSet->getValidationRules($prefix)
->merge($rules)
->all();
$request->validate($validationRules);
}
public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$search = $this->updateOrCreateActivitySearch($request);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function updateActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('update', $search);
$this->updateOrCreateActivitySearch($request, $search);
return $this->response->withOk();
}
private function storeNamedSearchFilters(
Collection $request,
Search $search,
FilterDefinitionCollection $filterSet,
?string $prefix = null,
): self {
$arrayTypeProperties = $filterSet
->getPropertyTypes([
FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,
])
->all();
$supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);
foreach ($supportedRequestProperties as $requestPropertyName) {
if (! array_has($request, $requestPropertyName)) {
continue;
}
/** @var string|string[] $propertyValue */
$propertyValue = array_get($request, $requestPropertyName);
$propertyName = $prefix === null
? $requestPropertyName
: mb_substr($requestPropertyName, mb_strlen($prefix));
$isArrayType = array_has($arrayTypeProperties, $propertyName);
if (! $isArrayType) {
/** @var string $requestPropertyValue */
$search->filters()->updateOrCreate(
[
'filter' => $propertyName,
],
[
'value' => $propertyValue,
]
);
continue;
}
/** @var string[] $requestPropertyValue */
/** @var SearchFilter[]|Collection $existingFilterValues */
$existingFilterValuesKeyed = $search->filters()
->where('filter', $propertyName)
->get()
->keyBy('id');
// Iterate over values provided as request parameters
foreach ($propertyValue as $value) {
/** @var SearchFilter|null $valueFilter */
$valueFilter = $search->filters()
->where(
[
'filter' => $propertyName,
'value' => $value,
]
)
->first();
if ($valueFilter !== null) {
// Remove filter value pair from list to be deleted
$existingFilterValuesKeyed->forget($valueFilter->id);
} else {
// Add new filter/value pair
$search->filters()->updateOrCreate([
'filter' => $propertyName,
'value' => $value,
]);
}
}
// Delete filter value pairs for this filter that no longer exist in request parameters
foreach ($existingFilterValuesKeyed as $existingFilter) {
$existingFilter->delete();
}
}
/** @var Collection<int, SearchFilter> $filtersKeyed */
$filtersKeyed = $search->filters()->get()->keyBy('filter');
// wipe removed filters from this search
foreach ($filtersKeyed as $filterName => $filter) {
if (array_has($request, $prefix . $filterName)) {
continue;
}
// Remove all filter values for this filter
$search->filters()->where('filter', $filterName)->delete();
}
return $this;
}
/**
* @throws AuthorizationException
*/
public function fetchActivitySearch(
Search $search,
Request $request,
SearchTransformer $searchTransformer,
): JsonResponse {
$this->authorize('view', $search);
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withCollection(
$user->searches()->get(),
$searchTransformer
->withConsumer($user)
);
}
/**
* Deletes a saved search
*
* @param Request $request
* @param Search $search
*
* @throws Exception
*
* @return JsonResponse
*/
public function deleteActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('delete', $search);
// Orphan any AutomatedReports that use this search
$search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);
// Delete filters and the search itself
$search->filters()->delete();
$search->delete();
return $this->response->withOk();
}
public function live(Request $request, ElasticActivityRepository $repository): JsonResponse
{
$user = $this->getUserFromRequest($request);
$this->request->validate([
'sort_direction' => 'in:asc,desc',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
]);
$activities = $repository->getLiveCoachingEligibleActivities(
user: $user,
lookBackMinutes: self::LOOK_BACK,
limit: (int) $this->request->input('limit', 25),
page: (int) $this->request->input('page', 1),
sortBy: ['actual_start_time', 'scheduled_start_time'],
sortDirection: (string) $this->request->input('sort_direction', 'asc'),
);
$this->response
->getManager()
->parseIncludes(['organizer.group', 'prospect'])
->setSerializer(new JsonSerializer());
return $this->response->withCollection($activities, new ActivityTransformer());
}
/**
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function show(Activity $activity, ActivityService $activityService): JsonResponse
{
$this->authorize('show', $activity);
$user = $activity->getUser();
$team = $user->getTeam();
// Sync the opportunity with the latest data if possible.
if ($activity->opportunity_id) {
try {
$crmService = $this->providerRegistry->get($team->crm->provider);
if (! $user->isCrmRequired()) {
$crmService->setUser($team->getOwner());
} else {
$crmService->setUser($user);
}
$crmService->syncOpportunity($activity->opportunity->crm_provider_id);
} catch (Exception $exception) {
// Move on.
}
}
$activityData = $activityService->getActivityData($this->request->user(), $activity);
return response()->json($activityData);
}
public function createRecording(Activity $activity)
{
$this->authorize('record', $activity);
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Tell Twilio to start recording this activity.
if ($activity->recording_state === Activity::RECORDING_OFF) {
$job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withCreated();
}
return $this->response->errorGone('Activity is already recording.');
}
public function updateRecording(Request $request, Activity $activity)
{
$this->authorize('record', $activity);
$request->validate([
'preference' => 'boolean',
'state' => [
'string',
Rule::in([
Activity::RECORDING_IN_PROGRESS,
Activity::RECORDING_PAUSED,
]),
],
]);
if ($request->has('state')) {
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Toggle the recording state between paused and resumed.
if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {
$job = (new ToggleRecording($activity, $request->input('state')))
->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Recording is not toggleable.');
}
if ($request->has('preference')) {
$activity->update([
'recording_preference' => $request->input('preference') ? 1 : 0,
]);
return $this->response->withOk();
}
return $this->response->errorWrongArgs('Something went wrong');
}
public function stopRecording(Activity $activity)
{
$this->authorize('stopRecord', $activity);
// Tell Twilio to stop recording this activity.
if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {
$job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Activity is not recording.');
}
/**
* Add activity to this user's favorites playlist
*
* @throws AuthorizationException
*/
public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse
{
$this->authorize('favorite', $activity);
$user = $this->getUserFromRequest($this->request);
$favorite = $activity->wasFavoritedBy($user);
$name = $activity->activity_title ?? '';
// It needs to check at least one record.
if (! $favorite) {
$favoritePlaylist = $user->favoritePlaylist();
$playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(
$activity,
$user,
$favoritePlaylist
);
if ($playlistActivity !== null) {
$playlistActivity->update(
// Just update, don't sort.
['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],
);
} else {
$playlistActivity = $activity->playlistActivities()->create([
'playlist_id' => $favoritePlaylist->getId(),
'user_id' => $user->getId(),
'start_time' => 0,
'name' => mb_strimwidth($name, 0, 100),
]);
// Sort it on top.
$playlistActivity->update(
[
'sort' => $playlistActivityRepository->calculateNewSortOrder(
null,
$playlistActivity,
),
],
);
}
$playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);
return new JsonResponse([], JsonResponse::HTTP_CREATED);
}
return new JsonResponse(
[
'error' => [
'code' => AbstractResponse::CODE_CONFLICT,
'http_code' => JsonResponse::HTTP_CONFLICT,
'message' => 'Resource Already Exists',
],
],
JsonResponse::HTTP_CONFLICT,
);
}
/**
* Remove activity from this user's favorites playlist
*
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function unfavorite(Activity $activity)
{
$user = $t...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.034242023,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Analyzing…","depth":4,"bounds":{"left":0.37200797,"top":0.07581804,"width":0.019946808,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.39361703,"top":0.074221864,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.40093085,"top":0.074221864,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Http\\Controllers\\API;\n\nuse Carbon\\Carbon;\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Exception;\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Validation\\Rule;\nuse Illuminate\\Validation\\Rules\\In;\nuse Illuminate\\Validation\\ValidationException;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ActivityAnalytics;\nuse Jiminny\\Component\\ActivitySearch;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Contracts\\ES\\Events\\UpdateSingleEntity;\nuse Jiminny\\Contracts\\ES\\UpdateTargetEnum;\nuse Jiminny\\Contracts\\Nudge\\NudgeFactoryInterface;\nuse Jiminny\\Contracts\\Playlist\\PlaylistTrackFactoryInterface;\nuse Jiminny\\Contracts\\Repositories\\PlaylistActivityRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Enums\\TeamSetting;\nuse Jiminny\\Events\\Activities\\AiAutomation\\ActivityProspectAdded;\nuse Jiminny\\Events\\Activities\\Coaching\\Coached;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Controllers\\CommentContextInterface;\nuse Jiminny\\Http\\Responses\\Api\\AbstractResponse;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\ActivityCommentTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTopicTriggerTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTransformer;\nuse Jiminny\\Http\\Transformers\\AvailabilityNotificationTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingFeedbackTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingSectionsTransformer;\nuse Jiminny\\Http\\Transformers\\SearchTransformer;\nuse Jiminny\\Http\\Transformers\\StatsTransformer;\nuse Jiminny\\Jobs\\Crm\\SaveActivity;\nuse Jiminny\\Jobs\\Crm\\UpdateStage;\nuse Jiminny\\Jobs\\Telephony\\StartRecording;\nuse Jiminny\\Jobs\\Telephony\\StopRecording;\nuse Jiminny\\Jobs\\Telephony\\ToggleRecording;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\CoachingFeedback;\nuse Jiminny\\Models\\CoachingSection;\nuse Jiminny\\Models\\CoachingSectionCriterion;\nuse Jiminny\\Models\\CoachingSectionFeedback;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\LanguageDialect;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Nudge;\nuse Jiminny\\Models\\PlaybookCategory;\nuse Jiminny\\Models\\Playlist;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\Track;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\CoachingFeedbackRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Rules\\MultidimensionalArrayMaxCharRule;\nuse Jiminny\\Services\\ActivityService;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Services\\PlaybackService;\nuse Jiminny\\Services\\UserService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\nuse Ramsey\\Uuid\\Uuid;\nuse Sentry;\nuse Symfony\\Component\\HttpFoundation;\n\nfinal class ActivityController extends Controller implements CommentContextInterface\n{\n // Number of minutes to look back on activities. i.e. a timeout on activity duration.\n private const int LOOK_BACK = 180;\n\n public function __construct(\n private ProviderRegistry $providerRegistry,\n private ActivityService $activityService,\n Response $response,\n private UserService $userService,\n private ActivitySearch\\Service\\ActivitySearch $activitySearch,\n private NudgeFactoryInterface $nudgeFactory,\n private ActivityCommentService $activityCommentService,\n private LoggerInterface $logger,\n private readonly CoachingFeedbackRepository $coachingFeedbackRepository,\n private readonly TeamRepository $teamRepository,\n ) {\n parent::__construct($response);\n }\n\n public static function getCommentImplementation(): string\n {\n return Comment::class;\n }\n\n public function delete()\n {\n $this->request->validate([\n '*' => 'uuid:activities',\n ]);\n\n $deletedIds = [];\n foreach ($this->request->all() as $activityId) {\n $activity = Activity::idOrUuId($activityId);\n\n try {\n if ($this->authorize('delete', $activity)) {\n $activity->delete();\n $deletedIds[] = $activityId;\n\n \\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n }\n } catch (AuthorizationException $authorizationException) {\n // They didn't have permission.\n }\n }\n\n return $this->response->withArray($deletedIds);\n }\n\n public function update(Request $request, Activity $activity)\n {\n $this->authorize('updateMetadata', $activity);\n\n $request->validate([\n 'title' => 'string|max:250',\n 'category_id' => 'uuid:playbook_categories',\n 'language' => [\n new In(\n LanguageDialect::query()\n ->with('language')\n ->cursor()\n ->map(static function (LanguageDialect $languageDialect): string {\n return $languageDialect->getLanguageLocale();\n })\n ->all()\n ),\n ],\n ]);\n\n if ($request->has('title')) {\n $activity->title = $request->input('title');\n }\n\n if ($request->has('category_id')) {\n $category = PlaybookCategory::uuid($request->input('category_id'));\n\n if ($category->playbook->team_id !== $request->user()->team_id) {\n return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n if ($request->has('language')) {\n if (! $activity->isInProgress()) {\n return $this->response->withError(\n 'Activity language can only be set while the meeting is in progress.',\n 400\n );\n }\n\n $activity->setLanguageCode($request->input('language'));\n }\n\n $activity->save();\n\n return $this->response->withOk();\n }\n\n // XXX: This should be merged with the update method.\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws SocialAccountTokenInvalidException\n *\n * @return mixed\n */\n public function summarize(Activity $activity): mixed\n {\n $this->logger->info('[Log Activity] Summarizing activity ', [\n 'activityId' => $activity->getUuid(),\n 'payload' => $this->request->all(),\n ]);\n $this->authorize('update', $activity);\n\n $this->logger->info('[Log Activity] Validating summary');\n // Validate the payload.\n $this->validateSummary($activity);\n\n // All objects must belong to this team.\n /** @var User $user */\n $user = $this->request->user();\n $team = $user->getTeam();\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n try {\n $crmUser = $user;\n if ($user->isCrmRequired() === false) {\n $crmUser = $team->owner;\n }\n $crmService->setUser($crmUser);\n } catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());\n }\n\n $rawEntities = $this->request->input('entities');\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid(\n $this->request->input('layout_id')\n );\n\n // Delay execution of CRM jobs to avoid locking issues.\n $jobDelay = 0;\n\n // If we have arrived from a notification, mark it as read.\n $notificationId = $this->request->input('nId');\n if ($notificationId) {\n $notification = $user->unreadNotifications->where('id', $notificationId)->first();\n\n if ($notification) {\n $notification->markAsRead();\n }\n }\n\n $title = $this->request->input('title');\n $prospects = $this->request->input('prospects');\n $opportunityId = $this->request->input('opportunity_id');\n $stageId = $this->request->input('stage_id');\n $categoryId = $this->request->input('category_id');\n $summary = $this->request->input('summary');\n $crmProviderId = $this->request->input('crm_id');\n $isInternal = $this->request->input('is_internal') ?? false;\n\n $lead = null;\n $category = null;\n $account = null;\n $contact = null;\n $opportunity = null;\n $stage = null;\n $callStage = null;\n\n foreach ($prospects as $prospectData) {\n $objectId = $prospectData['id'];\n\n if ($objectId === null) {\n continue;\n }\n\n $objectType = $prospectData['type'];\n $this->logger->info('debug', ['prospect_data' => $prospectData]);\n\n try {\n if ($objectType === null) {\n $this->logger->info('no object type');\n if ($crmService instanceof SupportsObjectTypeParseInterface) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n }\n\n switch ($objectType) {\n case 'lead':\n $this->logger->info('Processing lead');\n /** @var Lead|null $lead */\n $lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();\n\n // Lead does not exist locally, import it.\n if ($lead === null) {\n $this->logger->info('Lead does not exist locally');\n /** @var Lead $lead */\n $lead = $crmService->syncLead($objectId);\n }\n\n $this->logger->info('Lead found', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n if ($stageId === null) {\n $this->logger->info('Stage ID is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $lead->stage;\n\n break;\n }\n\n $this->logger->info('Looking for stage');\n // Determine if they have changed the stage.\n /** @var Stage $stage */\n $stage = $team->crm->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_LEAD)\n ->firstOrFail();\n\n $this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);\n if ($lead->stage_id && $lead->stage_id !== $stage->id) {\n $this->logger->info('Stage has changed');\n // Storage current stage on activity.\n $callStage = $lead->stage;\n\n // The stage has changed, update in remote CRM.\n dispatch(new UpdateStage($activity, $lead, $callStage, $stage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing lead stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->getName(),\n $stage->getName()\n ),\n [\n 'user' => $user->getUuid(),\n 'lead' => $lead->getUuid(),\n ]\n );\n } else {\n $this->logger->info('Stage has not changed');\n // Stage remains as current.\n $callStage = $stage;\n }\n\n break;\n\n case 'account':\n $this->logger->info('Processing account');\n // If the object is not a lead, it should be an account.\n $account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();\n\n // Account does not exist locally, import it.\n if ($account === null) {\n $this->logger->info('Account does not exist locally');\n $account = $crmService->syncAccount($objectId);\n }\n\n $this->logger->info('Account found', ['accountId' => $account->id]);\n\n break;\n case 'contact':\n $this->logger->info('processing contact');\n $contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $this->logger->info('contact does not exist locally');\n $contact = $crmService->syncContact($objectId);\n }\n\n $this->logger->info('resolving account');\n $account = $this->resolveAccount($team, $contact, $crmService, $prospects);\n\n break;\n }\n\n // If they have specified an opportunity, retrieve this with stage.\n if ($opportunityId) {\n $this->logger->info('opportunity id is set');\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if ($opportunity === null) {\n $this->logger->info('opportunity does not exist locally');\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n if ($stageId === null) {\n $this->logger->info('stage id is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $opportunity->stage ?? null;\n } else {\n $this->logger->info('looking for stage');\n /** @var ?Stage $opportunityStage */\n $opportunityStage = $team->crm\n ->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n // There is a chance we still cannot import this opportunity.\n if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {\n $this->logger->info('opportunity stage has changed');\n // Storage current stage on activity.\n $callStage = $opportunity->stage;\n\n dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing opportunity stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->name,\n $opportunityStage->name\n ),\n [\n 'userId' => $user->id_string,\n 'opportunityId' => $opportunity->id_string,\n ]\n );\n } else {\n $this->logger->info('opportunity stage has not changed');\n // Stage remains as current.\n $callStage = $opportunityStage;\n }\n }\n }\n\n if ($crmProviderId) {\n // Cast $crmProviderId to string otherwise it won't use database index for some records\n $linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();\n\n // Check if this activity has already been assigned to a different activity.\n if ($linkedActivity && $linkedActivity->id !== $activity->id) {\n throw new InvalidArgumentException(\n 'Sorry, the linked task has already been logged under a different call. '\n . 'Please choose another linked task.'\n );\n }\n }\n } catch (InvalidArgumentException $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($exception->getMessage());\n } catch (Exception $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorInternalError(\n 'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'\n );\n }\n }\n\n if ($categoryId) {\n $category = PlaybookCategory::uuid($categoryId);\n\n if ($category->playbook->team_id !== $team->id) {\n throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n $this->logger->info('Prospect data', [\n 'lead_id' => $lead?->getId(),\n 'account_id' => $account?->getId(),\n 'contact_id' => $contact?->getId(),\n 'opportunity_id' => $opportunity?->getId(),\n 'stage_id' => $stage?->getId(),\n ]);\n\n if ($title) {\n $activity->title = $title;\n }\n\n if ($summary) {\n $activity->summary = $summary;\n }\n\n if ($crmProviderId) {\n $activity->crm_provider_id = $crmProviderId;\n }\n\n if ($callStage) {\n $this->logger->info('Setting stage id', ['stageId' => $callStage->id]);\n $activity->stage_id = $callStage->id;\n }\n\n if ($lead) {\n $this->logger->info('Setting lead id', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n // If we are changed from an account > lead, unset the account data.\n $this->logger->info('Unsetting account id, opportunity id, contact id, value');\n $activity->account_id = null;\n $activity->opportunity_id = null;\n $activity->contact_id = null;\n $activity->value = null;\n }\n\n if ($account) {\n $this->logger->info('Setting account id', ['accountId' => $account->id]);\n $activity->account_id = $account->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('unsetting lead id');\n $activity->lead_id = null;\n\n // Unset the contact if switching different accounts. Will be set up below if still applicable.\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {\n $this->logger->info('Unsetting contact id');\n $activity->contact_id = null;\n }\n }\n\n if ($opportunity) {\n $this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);\n $this->logger->info('unsetting lead id');\n $activity->opportunity_id = $opportunity->id;\n $activity->value = $opportunity->value;\n\n // If we are changed from an lead > account, unset the lead data.\n $activity->lead_id = null;\n }\n\n if ($contact) {\n $this->logger->info('setting contact id', ['contactId' => $contact->id]);\n $activity->contact_id = $contact->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('Unsetting lead id');\n $activity->lead_id = null;\n }\n\n $activity->is_internal = $isInternal;\n $activity->save();\n $activity->refresh();\n\n $this->logger->notice('Activity saved', [\n 'activity_id' => $activity->getId(),\n 'lead_id' => $activity->lead_id,\n 'account_id' => $activity->account_id,\n 'contact_id' => $activity->contact_id,\n 'opportunity_id' => $activity->opportunity_id,\n 'stage_id' => $activity->stage_id,\n 'crm_provider_id' => $activity->getCrmProviderId(),\n ]);\n\n // Store entities as field data on the activity.\n $updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);\n\n if ($activity->isLoggable()) {\n // Follow-up Task or Event data.\n $followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);\n\n $this->logger->info('CRM LOG manual log triggered', [\n 'activityId' => $activity->getUuid(),\n 'followupData' => $followupData,\n 'userId' => $user->getUuid(),\n ]);\n\n // Store data in the CRM.\n // ++add check for crm_required\n $job = new SaveActivity($activity, $followupData);\n\n if ($updatedData) {\n $job->delay(Carbon::now()->addMinutes($jobDelay));\n }\n\n dispatch($job);\n\n // Manually dispatch log for Opportunity or Prospect added\n if ($activity->hasOpportunity() || $activity->hasProspect()) {\n event(new ActivityProspectAdded(\n activity: $activity,\n eventSource: 'manually-log-crm-data'\n ));\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.\n *\n * @param ServiceInterface $service\n * @param Activity $activity\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array\n {\n $updatedData = [];\n $existingData = $activity->data()->get();\n\n // We need to delete any existing data to overwrite with latest values.\n $activity->data()->delete();\n\n $layoutEntities = $layout->entities()\n ->with('field', 'parent')\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->get();\n\n /** @var LayoutEntity $entity */\n foreach ($layoutEntities as $entity) {\n // If the user has provided a value for this entity\n if (array_key_exists($entity->id_string, $entities)) {\n $value = $entities[$entity->id_string];\n\n // Convert raw data into values that the CRM can consume.\n if ($value) {\n $value = $service->normalizeValue($entity->field->type, $value);\n }\n\n // Check the field is part of the activity-summary section.\n if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {\n // This is the internal database ID, not the external CRM ID.\n $objectId = null;\n\n switch ($entity->field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $objectId = $activity->account_id;\n\n break;\n\n case Field::OBJECT_CONTACT:\n $objectId = $activity->contact_id;\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n $objectId = $activity->opportunity_id;\n\n break;\n\n case Field::OBJECT_LEAD:\n $objectId = $activity->lead_id;\n\n break;\n\n case Field::OBJECT_TASK:\n case Field::OBJECT_EVENT:\n $objectId = $activity->id;\n\n break;\n }\n\n if ($objectId) {\n /** @var FieldData $data */\n $data = $activity->data()->create([\n 'crm_layout_entity_id' => $entity->id,\n 'crm_field_id' => $entity->crm_field_id,\n 'object_type' => $entity->field->object_type,\n 'object_id' => $objectId,\n 'value' => $value,\n ]);\n\n // Never send read-only field data to the CRM.\n if ($entity->read_only === false && $entity->is_visible) {\n $existingValue = $existingData\n ->where('crm_layout_entity_id', $entity->id)\n ->where('crm_field_id', $entity->crm_field_id)\n ->where('object_type', $entity->field->object_type)\n ->where('object_id', $objectId)\n ->first();\n\n // If the field was actually changed, we need to reflect this in the CRM too.\n if ($existingValue === null || $existingValue->value !== $value) {\n $updatedData[] = $data->id;\n }\n }\n }\n }\n }\n }\n\n return $updatedData;\n }\n\n /**\n * Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.\n *\n * @param ServiceInterface $crmService\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array\n {\n $fieldData = [];\n foreach ($entities as $entityId => $value) {\n // Only bother with fields that have a value.\n if ($value) {\n // Extract the entity from the UUID. Check the field is valid and part of the follow-up section.\n $entity = $layout->entities()\n ->uuid($entityId, false)\n ->whereHas('parent', function ($query) {\n $query->where('label', 'follow-up');\n })\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->first();\n\n if ($entity) {\n // Convert raw data into values that the CRM can consume.\n $value = $crmService->normalizeValue($entity->field->type, $value);\n\n // Add the field and value to the payload.\n $fieldData += [\n $entity->field->crm_provider_id => $value,\n ];\n }\n }\n }\n\n return $fieldData;\n }\n\n /**\n * @param Activity $activity\n */\n private function validateSummary(Activity $activity): void\n {\n $team = $activity->user->team;\n $crmProvider = $team->crm->provider;\n $attributes = [];\n\n $rules = [\n 'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,\n 'title' => 'string|max:250',\n 'prospects' => 'required|array',\n 'opportunity_id' => new CrmReference($crmProvider),\n 'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',\n 'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator\n 'summary' => 'max:50000',\n 'nId' => 'exists:notifications,id',\n 'crm_id' => new CrmReference($crmProvider),\n 'entities' => 'array',\n 'is_internal' => 'boolean',\n ];\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));\n\n // Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.\n $entities = $layout->entities()\n ->where('read_only', 0)\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->whereHas('parent', function ($query) use ($activity) {\n if ($activity->isLoggable() === false) {\n $query->where('label', '<>', 'follow-up');\n }\n });\n\n $isInternal = $this->request->input('is_internal', false);\n\n foreach ($entities->get() as $entity) {\n $rules += $this->buildFieldValidator($entity, $isInternal);\n $attributes += $this->buildFieldMessage($entity);\n }\n\n $this->request->validate($rules, [], $attributes);\n }\n\n private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array\n {\n return [\n 'entities.' . $entity->id_string => $entity->getValidator($isInternal),\n ];\n }\n\n /**\n * @param LayoutEntity $entity\n *\n * @return array\n */\n private function buildFieldMessage(LayoutEntity $entity): array\n {\n $label = $entity->label;\n if ($label === null) {\n $label = $entity->field->label;\n }\n\n return [\n 'entities.' . $entity->id_string => $label,\n ];\n }\n\n public function search(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->debugLog(\n $user,\n 'User extracted from request',\n ['user' => $user->getId(), 'tz' => $user->getTimezone()]\n );\n\n $searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());\n\n $this->debugLog(\n $user,\n 'ActivitySearch criteria built',\n ['searchCriteria' => $searchCriteria]\n );\n\n $filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);\n\n $this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);\n\n $this->validateSearch($request, $filterSet);\n\n $this->debugLog($user, 'Request validated');\n\n $searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);\n\n /** @var Collection<Activity> $activities */\n $activities = $searchResponse['results'];\n\n $this->debugLog($user, 'Activities ES response extracted');\n\n $hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(\n $user->getTeamId(),\n TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),\n );\n\n if ($hideInternalMeetingsSetting?->getValue() === '1') {\n $activities = $activities->filter(function (Activity $activity) {\n if ($activity->is_internal && empty($activity->actual_start_time)) {\n return false;\n }\n\n return true;\n });\n }\n\n $this->debugLog($user, 'Internal meetings (?!) filtered');\n\n $this->response->getManager()\n ->parseIncludes([\n 'category',\n 'organizer.group',\n 'prospect',\n 'stage',\n 'opportunity',\n 'stats',\n 'scorecards',\n 'masterTrack',\n 'activeParticipants',\n 'notification',\n ])\n ->setSerializer(new JsonSerializer());\n\n $transformerExcludes = $this->request->input('exclude');\n if ($transformerExcludes) {\n $this->response->getManager()->parseExcludes($transformerExcludes);\n }\n\n $this->debugLog($user, 'Response Manager (?!) applied');\n\n $transformer = new ActivityTransformer();\n $transformer->setConsumer($user);\n\n $this->debugLog($user, 'Activity Transformer added');\n\n $resource = new \\League\\Fractal\\Resource\\Collection($activities, $transformer);\n $page = $searchCriteria->getPageNumber();\n\n $this->debugLog($user, 'Search criteria page number called', ['page' => $page]);\n\n $histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');\n\n $this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);\n\n return $this->response->withArray([\n 'pagination' => [\n 'total' => $searchResponse['totalHits'],\n 'current' => $page,\n 'prev' => max($page - 1, 1),\n 'next' => $page + 1,\n ],\n 'results' => $this->response->getManager()->createData($resource)->toArray(),\n 'histogram' => $histogram,\n ]);\n }\n\n private function debugLog(User $user, string $logMessage, ?array $context = []): void\n {\n // Debug for Learning People Only\n if ($user->getTeamId() !== 260) {\n return;\n }\n\n Log::notice(\n sprintf('[activity-search-controller] %s', $logMessage),\n $context\n );\n }\n\n /** @throws ValidationException */\n private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void\n {\n $rules = [\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ];\n\n if ($prefix !== null && mb_strpos($prefix, '.') !== false) {\n $rules[rtrim($prefix, '.')] = sprintf(\n 'required|array|max:%d',\n $filterSet->count()\n );\n }\n\n $validationRules = $filterSet->getValidationRules($prefix)\n ->merge($rules)\n ->all();\n\n $request->validate($validationRules);\n }\n\n public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $search = $this->updateOrCreateActivitySearch($request);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function updateActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('update', $search);\n\n $this->updateOrCreateActivitySearch($request, $search);\n\n return $this->response->withOk();\n }\n\n private function storeNamedSearchFilters(\n Collection $request,\n Search $search,\n FilterDefinitionCollection $filterSet,\n ?string $prefix = null,\n ): self {\n $arrayTypeProperties = $filterSet\n ->getPropertyTypes([\n FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,\n ])\n ->all();\n\n $supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);\n\n foreach ($supportedRequestProperties as $requestPropertyName) {\n if (! array_has($request, $requestPropertyName)) {\n continue;\n }\n\n /** @var string|string[] $propertyValue */\n $propertyValue = array_get($request, $requestPropertyName);\n $propertyName = $prefix === null\n ? $requestPropertyName\n : mb_substr($requestPropertyName, mb_strlen($prefix));\n\n $isArrayType = array_has($arrayTypeProperties, $propertyName);\n\n if (! $isArrayType) {\n /** @var string $requestPropertyValue */\n\n $search->filters()->updateOrCreate(\n [\n 'filter' => $propertyName,\n ],\n [\n 'value' => $propertyValue,\n ]\n );\n\n continue;\n }\n\n /** @var string[] $requestPropertyValue */\n\n /** @var SearchFilter[]|Collection $existingFilterValues */\n $existingFilterValuesKeyed = $search->filters()\n ->where('filter', $propertyName)\n ->get()\n ->keyBy('id');\n\n // Iterate over values provided as request parameters\n foreach ($propertyValue as $value) {\n /** @var SearchFilter|null $valueFilter */\n $valueFilter = $search->filters()\n ->where(\n [\n 'filter' => $propertyName,\n 'value' => $value,\n ]\n )\n ->first();\n\n if ($valueFilter !== null) {\n // Remove filter value pair from list to be deleted\n $existingFilterValuesKeyed->forget($valueFilter->id);\n } else {\n // Add new filter/value pair\n $search->filters()->updateOrCreate([\n 'filter' => $propertyName,\n 'value' => $value,\n ]);\n }\n }\n\n // Delete filter value pairs for this filter that no longer exist in request parameters\n foreach ($existingFilterValuesKeyed as $existingFilter) {\n $existingFilter->delete();\n }\n }\n\n /** @var Collection<int, SearchFilter> $filtersKeyed */\n $filtersKeyed = $search->filters()->get()->keyBy('filter');\n\n // wipe removed filters from this search\n foreach ($filtersKeyed as $filterName => $filter) {\n if (array_has($request, $prefix . $filterName)) {\n continue;\n }\n\n // Remove all filter values for this filter\n $search->filters()->where('filter', $filterName)->delete();\n }\n\n return $this;\n }\n\n /**\n * @throws AuthorizationException\n */\n public function fetchActivitySearch(\n Search $search,\n Request $request,\n SearchTransformer $searchTransformer,\n ): JsonResponse {\n $this->authorize('view', $search);\n\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection(\n $user->searches()->get(),\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n /**\n * Deletes a saved search\n *\n * @param Request $request\n * @param Search $search\n *\n * @throws Exception\n *\n * @return JsonResponse\n */\n public function deleteActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('delete', $search);\n\n // Orphan any AutomatedReports that use this search\n $search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);\n\n // Delete filters and the search itself\n $search->filters()->delete();\n $search->delete();\n\n return $this->response->withOk();\n }\n\n public function live(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n $user = $this->getUserFromRequest($request);\n\n $this->request->validate([\n 'sort_direction' => 'in:asc,desc',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ]);\n\n $activities = $repository->getLiveCoachingEligibleActivities(\n user: $user,\n lookBackMinutes: self::LOOK_BACK,\n limit: (int) $this->request->input('limit', 25),\n page: (int) $this->request->input('page', 1),\n sortBy: ['actual_start_time', 'scheduled_start_time'],\n sortDirection: (string) $this->request->input('sort_direction', 'asc'),\n );\n\n $this->response\n ->getManager()\n ->parseIncludes(['organizer.group', 'prospect'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($activities, new ActivityTransformer());\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function show(Activity $activity, ActivityService $activityService): JsonResponse\n {\n $this->authorize('show', $activity);\n\n $user = $activity->getUser();\n $team = $user->getTeam();\n\n // Sync the opportunity with the latest data if possible.\n if ($activity->opportunity_id) {\n try {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n if (! $user->isCrmRequired()) {\n $crmService->setUser($team->getOwner());\n } else {\n $crmService->setUser($user);\n }\n\n $crmService->syncOpportunity($activity->opportunity->crm_provider_id);\n } catch (Exception $exception) {\n // Move on.\n }\n }\n\n $activityData = $activityService->getActivityData($this->request->user(), $activity);\n\n return response()->json($activityData);\n }\n\n public function createRecording(Activity $activity)\n {\n $this->authorize('record', $activity);\n\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Tell Twilio to start recording this activity.\n if ($activity->recording_state === Activity::RECORDING_OFF) {\n $job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withCreated();\n }\n\n return $this->response->errorGone('Activity is already recording.');\n }\n\n public function updateRecording(Request $request, Activity $activity)\n {\n $this->authorize('record', $activity);\n\n $request->validate([\n 'preference' => 'boolean',\n 'state' => [\n 'string',\n Rule::in([\n Activity::RECORDING_IN_PROGRESS,\n Activity::RECORDING_PAUSED,\n ]),\n ],\n ]);\n\n if ($request->has('state')) {\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Toggle the recording state between paused and resumed.\n if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {\n $job = (new ToggleRecording($activity, $request->input('state')))\n ->onQueue(Constants::QUEUE_CONFERENCES);\n\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Recording is not toggleable.');\n }\n\n if ($request->has('preference')) {\n $activity->update([\n 'recording_preference' => $request->input('preference') ? 1 : 0,\n ]);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorWrongArgs('Something went wrong');\n }\n\n public function stopRecording(Activity $activity)\n {\n $this->authorize('stopRecord', $activity);\n\n // Tell Twilio to stop recording this activity.\n if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {\n $job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Activity is not recording.');\n }\n\n /**\n * Add activity to this user's favorites playlist\n *\n * @throws AuthorizationException\n */\n public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse\n {\n $this->authorize('favorite', $activity);\n\n $user = $this->getUserFromRequest($this->request);\n $favorite = $activity->wasFavoritedBy($user);\n $name = $activity->activity_title ?? '';\n\n // It needs to check at least one record.\n if (! $favorite) {\n $favoritePlaylist = $user->favoritePlaylist();\n\n $playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(\n $activity,\n $user,\n $favoritePlaylist\n );\n\n if ($playlistActivity !== null) {\n $playlistActivity->update(\n // Just update, don't sort.\n ['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],\n );\n } else {\n $playlistActivity = $activity->playlistActivities()->create([\n 'playlist_id' => $favoritePlaylist->getId(),\n 'user_id' => $user->getId(),\n 'start_time' => 0,\n 'name' => mb_strimwidth($name, 0, 100),\n ]);\n // Sort it on top.\n $playlistActivity->update(\n [\n 'sort' => $playlistActivityRepository->calculateNewSortOrder(\n null,\n $playlistActivity,\n ),\n ],\n );\n }\n\n $playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);\n\n return new JsonResponse([], JsonResponse::HTTP_CREATED);\n }\n\n return new JsonResponse(\n [\n 'error' => [\n 'code' => AbstractResponse::CODE_CONFLICT,\n 'http_code' => JsonResponse::HTTP_CONFLICT,\n 'message' => 'Resource Already Exists',\n ],\n ],\n JsonResponse::HTTP_CONFLICT,\n );\n }\n\n /**\n * Remove activity from this user's favorites playlist\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unfavorite(Activity $activity)\n {\n $user = $this->request->user();\n\n $favorites = $activity->favoritedBy($user);\n\n if ($favorites && $favorites->isEmpty()) {\n return $this->response->errorNotFound('Favorite not found.');\n }\n\n $this->authorize('unfavorite', [$activity, $favorites]);\n\n // When you unfavorite an activity,\n // it should remove all the activities in it, including snippets.\n $isDeleted = $favorites->each(function ($favorite) {\n $favorite->forceDelete();\n });\n\n if ($isDeleted) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not remove favorite.');\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function notify(Activity $activity)\n {\n $this->authorize('notify', $activity);\n\n $user = $this->request->user();\n\n $existingNotification = $activity->availabilityNotifications()\n ->where('user_id', $user->id)\n ->exists();\n\n if ($existingNotification) {\n return $this->response->errorWrongArgs('Notification is already configured.');\n }\n\n $notification = Activity\\AvailabilityNotification::create([\n 'user_id' => $user->id,\n 'activity_id' => $activity->id,\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($notification, new AvailabilityNotificationTransformer());\n }\n\n /**\n * @param Activity $activity\n * @param Activity\\AvailabilityNotification $notification\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unnotify(Activity $activity, Activity\\AvailabilityNotification $notification)\n {\n $this->authorize('unnotify', [$activity, $notification]);\n\n if ($notification->sent_at || $notification->delete()) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not delete notification.');\n }\n\n public function play(Request $request, Activity $activity)\n {\n $this->authorize('stream', $activity);\n\n $request->validate([\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $activity->plays()->create([\n 'user_id' => $user->getId(),\n 'start_time' => $request->input('start_time'),\n ]);\n\n return $this->response->withCreated();\n }\n\n /**\n * @param Activity $activity\n *\n * @return mixed\n */\n public function comment(Activity $activity)\n {\n return $this->newComment($activity);\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @return mixed\n */\n public function replyComment(Activity $activity, Comment $comment)\n {\n return $this->newComment($activity, $comment);\n }\n\n /**\n * @param Activity $activity\n * @param Comment|null $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n protected function newComment(Activity $activity, ?Comment $comment = null)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n 'type' => 'integer|between:0,3',\n 'visibility' => sprintf('nullable|integer|between:1,%d', count(Comment::getVisibilityLevels())),\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n $threadStartId = null;\n if ($comment) {\n $threadStartId = $comment->thread_start_id ?: $comment->id;\n }\n\n try {\n $newComment = Comment::create([\n 'parent_comment_id' => $comment->id ?? null,\n 'thread_start_id' => $threadStartId,\n 'activity_id' => $activity->id,\n 'user_id' => $this->request->user()->id,\n 'comment' => trim($this->request->input('comment')),\n 'start_time' => $this->request->input('start_time', 0),\n 'end_time' => $this->request->input('end_time', 0),\n 'type' => $this->request->input('type', Comment::TYPE_NEUTRAL),\n 'visibility' => $this->request->input('visibility', Comment::VISIBILITY_PUBLIC),\n ]);\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($newComment, new ActivityCommentTransformer());\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not create comment.' . $exception->getMessage());\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function updateComment(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n try {\n $comment->update([\n 'comment' => trim($this->request->input('comment')),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment.');\n }\n }\n\n public function updateCommentVisibility(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'visibility' => sprintf('integer|between:1,%d', count(Comment::getVisibilityLevels())),\n ]);\n\n $visibility = $this->request->input('visibility');\n\n if ($comment->parent !== null) {\n return $this->response->errorWrongArgs('Comment visibility can only be updated on top level comments.');\n }\n\n try {\n $this->activityCommentService->updateCommentVisibility($comment, $visibility);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment\\'s visibility.');\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function deleteComment(Activity $activity, Comment $comment)\n {\n $this->authorize('deleteComment', [$activity, $comment]);\n\n // Delete comment and any children.\n $comment->delete();\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function fetchComments()\n {\n $user = $this->request->user();\n $this->request->validate([\n 'forUserId' => 'uuid:users,team_id,' . $user->team_id,\n 'types' => 'array',\n 'types.*' => 'integer|between:0,3',\n ]);\n $forUser = null;\n\n $types = [Comment::TYPE_NEUTRAL, Comment::TYPE_GAME_CHANGER, Comment::TYPE_POSITIVE];\n $user = $this->request->user();\n if ($this->request->has('forUserId')) {\n $forUser = $user->team->users()->uuid($this->request->input('forUserId'));\n }\n\n $comments = Comment::query()\n ->whereHas('activity', static function (Builder $builder) use ($user, $forUser): void {\n $builder\n // I left feedback on my own activity; or\n ->where('activities.user_id', $user->getId());\n if ($forUser) {\n // I left feedback on any activity for this user.\n $builder->orWhere([\n 'user_id' => $user->getId(),\n 'activities.user_id' => $forUser->getId(),\n ]);\n }\n })\n ->whereIn('type', $this->request->input('types', $types))\n ->orderBy('created_at', 'desc')\n ->get();\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity', 'user'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($comments, new ActivityCommentTransformer());\n }\n\n public function deleteCoachingFeedback(Activity $activity, CoachingFeedback $coachingFeedback)\n {\n $this->authorize('deleteCoachingFeedback', [$activity, $coachingFeedback]);\n $activity = $coachingFeedback->getActivity();\n\n if ($coachingFeedback->delete()) {\n event(new UpdateSingleEntity(\n entityId: $activity->getId(),\n updateTarget: UpdateTargetEnum::ACTIVITY,\n purpose: 'delete-coaching-feedback',\n ));\n\n return $this->response->withOk();\n }\n\n return $this->response->withError('Delete operation failed. Contact support.', 500);\n }\n\n /**\n * Add new or update Coaching feedback\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws \\Illuminate\\Validation\\ValidationException\n *\n * @return mixed\n */\n public function putCoachingFeedback(Request $request, Activity $activity)\n {\n $user = $request->user();\n\n if (! $user instanceof User) {\n abort(403);\n }\n $teamId = $user->getTeamId();\n\n $this->authorize('coach', $activity);\n\n $this->request->validate([\n 'coach_id' => 'required|uuid:users,team_id,' . $teamId,\n 'coachee_id' => 'required|uuid:users,team_id,' . $teamId,\n 'visibility' => ['required', Rule::in(CoachingFeedback::VISIBILITIES)],\n 'coaching_sections.*.uuid' => 'required|uuid:coaching_sections',\n 'coaching_sections.*.score' => ['required', Rule::in(CoachingSectionFeedback::SCORES)],\n 'coaching_sections.*.summary' => 'string|max:10000',\n 'coaching_sections.*.criteria.*.uuid' => 'required|uuid:coaching_section_criteria',\n 'coaching_sections.*.criteria.*.note' => 'required|string|max:10000',\n 'sharedWithUsers' => [\n 'required_if:visibility,' . CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS,\n 'array',\n ],\n 'sharedWithUsers.*' => [\n 'uuid:users,team_id,' . $teamId,\n ],\n ]);\n\n /** @var User $coach */\n $coach = User::uuid($this->request->input('coach_id'));\n /** @var User $coachee */\n $coachee = User::uuid($this->request->input('coachee_id'));\n $coachingSectionFeedbacks = $this->request->input('coaching_sections');\n\n $previousRecord = $this->coachingFeedbackRepository->getOneForActivityByCoacheeAndCoach(\n $coachee->getId(),\n $coach->getId(),\n $activity->getId()\n );\n $recordIsNew = false;\n if ($previousRecord === null) {\n $recordIsNew = true;\n }\n\n if (! $coachee->isSameTeamId($coach)) {\n return $this->response->errorForbidden('User not member of your team.');\n }\n\n if (! is_array($coachingSectionFeedbacks) || count($coachingSectionFeedbacks) < 1) {\n return $this->response->withError('At least one Coaching Framework Section shall be scored.', 422);\n }\n\n if (! $activity->participants()->where('participants.user_id', $coachee->id)->exists()) {\n return $this->response->withError('Coached user did not participate activity.', 422);\n }\n\n $visibility = $this->request->input('visibility');\n\n $shouldSendNotification = $recordIsNew;\n if ($recordIsNew === false && $visibility !== $previousRecord->getVisibility()) {\n $shouldSendNotification = true;\n }\n\n /**\n * Create CoachingFeedback\n *\n * @var CoachingFeedback $coachingFeedback\n */\n $coachingFeedback = $activity->coachingFeedbacks()->updateOrCreate(\n [\n 'coach_id' => $coach->id,\n 'coachee_id' => $coachee->id,\n ],\n [\n 'framework_id' => $activity->category->id,\n 'visibility' => $visibility,\n ]\n );\n\n $sharedUserIds = [];\n if ($visibility === CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS) {\n foreach ($this->request->input('sharedWithUsers') as $sharedWithUserUuid) {\n /** @var User $user */\n $user = User::uuid($sharedWithUserUuid);\n $sharedUserIds[] = $user->getId();\n }\n }\n\n $syncResult = $coachingFeedback->customAccessUsers()->sync($sharedUserIds);\n\n $scores = [];\n\n\n /**\n * Create CoachingSectionsFeedbacks.\n *\n * @var CoachingSectionFeedback $coachingSectionFeedback\n */\n foreach ($coachingSectionFeedbacks as $coachingSectionFeedbackInput) {\n $coachingSection = CoachingSection::uuid($coachingSectionFeedbackInput['uuid']);\n $coachingSectionFeedback = $coachingFeedback->sectionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_id' => $coachingSection->id,\n ],\n [\n 'score' => array_get($coachingSectionFeedbackInput, 'score'),\n 'summary' => array_get($coachingSectionFeedbackInput, 'summary') ?? '',\n ]\n );\n\n $scores[] = array_get($coachingSectionFeedbackInput, 'score');\n\n $criteria = array_get($coachingSectionFeedbackInput, 'criteria');\n if (is_array($criteria) && ! empty($criteria)) {\n foreach ($criteria as $criteriaFeedbackInput) {\n $coachingSectionFeedback->criterionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_criterion_id' => CoachingSectionCriterion::uuid(array_get($criteriaFeedbackInput, 'uuid'))\n ->id,\n ],\n ['note' => array_get($criteriaFeedbackInput, 'note')],\n );\n }\n }\n }\n\n $coachingFeedback->average_score = array_sum($scores) / count($scores);\n\n if ($recordIsNew === false && $coachingFeedback->getAverageScore() !== $previousRecord->getAverageScore()) {\n $shouldSendNotification = true;\n }\n if (! empty($syncResult['attached']) || ! empty($syncResult['detached']) || ! empty($syncResult['updated'])) {\n $shouldSendNotification = true;\n }\n\n $coachingFeedback->save();\n // ensure updated at for coaching feedback on section feedback summary added.\n $coachingFeedback->touch();\n\n if ($shouldSendNotification) {\n event(new Coached($coachingFeedback));\n }\n\n Datadog::increment('jiminny.activity.score.update', 1, ['company' => $activity->user->team->slug]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n $coachingFeedbackTransformer = new CoachingFeedbackTransformer();\n $coachingFeedbackTransformer->setConsumer($this->getUserFromRequest($request));\n\n return $this->response->withItem($coachingFeedback, $coachingFeedbackTransformer);\n }\n\n\n /**\n * Retrieve category criteria for coaching.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachingSections(Activity $activity)\n {\n $this->authorize('coach', $activity);\n\n if ($activity->category === null) {\n return $this->response->errorUnprocessable('Category has not yet been assigned.');\n }\n\n $criteria = $activity\n ->category\n ->coachingSections()\n ->where('is_enabled', 1)\n ->orderBy('sequence', 'asc');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($criteria->get(), new CoachingSectionsTransformer());\n }\n\n /**\n * @throws AuthorizationException\n * @throws ValidationException\n *\n * @return mixed\n */\n public function addToPlaylist(Activity $activity, PlaylistTrackFactoryInterface $playlistTrackFactory)\n {\n $this->request->validate([\n 'playlists' => 'required|array',\n 'playlists.*' => 'uuid:playlists',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'name' => 'required|max:100',\n ]);\n\n $this->authorize('addToPlaylist', [$activity, $this->request->input('playlists')]);\n\n $startTime = $this->request->input('start_time');\n $endTime = $this->request->input('end_time');\n $name = $this->request->input('name');\n /** @var User $user */\n $user = $this->request->user();\n\n // Get playlist by uuid.\n foreach ($this->request->input('playlists') as $playlistId) {\n // Pull out the playlist model.\n $playlist = Playlist::uuid($playlistId);\n\n $playlistTrackFactory->createTrack($playlist, $user, [\n 'name' => $name,\n 'activity' => $activity,\n 'start_time' => $startTime,\n 'end_time' => $endTime,\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function share(Request $request, Activity $activity): JsonResponse\n {\n $this->authorize('share', $activity);\n\n $request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'recipients.*.type' => 'in:user,group',\n 'recipients.*.id' => 'string|max:40',\n 'share' => 'string|max:255',\n ]);\n\n $user = $request->user();\n\n $recipients = $request->get('recipients');\n $users = $this->userService->convertRecipientsToUsers($user, $recipients);\n\n $shareData = [\n 'from_user_id' => $user->id,\n 'note' => $request->input('note'),\n 'start_time' => $request->input('start_time'),\n 'end_time' => $request->input('end_time'),\n ];\n\n // Create a share object against a notification provider channel\n if ($request->input('share')) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'notification_provider_channel' => $request->input('share'),\n ]\n )\n );\n\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n\n // Create a share object against each recipient\n foreach ($users as $recipient) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'to_user_id' => $recipient->id,\n ]\n )\n );\n\n // If parent_share_id has been selected yet\n if (! isset($shareData['parent_share_id'])) {\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachRequest(Activity $activity)\n {\n $this->authorize('coachRequest', $activity);\n\n $this->request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'coachers.*.type' => 'required|in:user',\n 'coachers.*.id' => 'required',\n ]);\n\n $coachers = $this->request->get('coachers');\n $user = $this->request->user();\n $users = $this->userService->convertRecipientsToUsers($user, $coachers);\n\n foreach ($users as $coacher) {\n CoachRequest::create([\n 'user_id' => $coacher->id,\n 'activity_id' => $activity->id,\n 'note' => $this->request->get('note'),\n 'start_time' => $this->request->get('start_time'),\n 'end_time' => $this->request->get('end_time'),\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function createActivityTopicTriggers(Activity $activity, LoggerInterface $logger): HttpFoundation\\JsonResponse\n {\n $this->authorize('analyzeTopicTriggers', $activity);\n\n if (! $activity->hasTranscription()) {\n return new HttpFoundation\\JsonResponse(\n [\n 'error' => 'Transcription not found.',\n ],\n JsonResponse::HTTP_NOT_FOUND\n );\n }\n\n $logger->info(__METHOD__ . ': queued for analysis', [\n 'activity' => $activity->id_string,\n ]);\n\n dispatch(new ActivityAnalytics\\Job\\AnalyzeActivityTopicTriggers($activity));\n\n return new HttpFoundation\\JsonResponse(null, JsonResponse::HTTP_CREATED);\n }\n\n public function fetchActivityTopicTriggers(\n Activity $activity,\n LoggerInterface $logger,\n ActivityTopicTriggerTransformer $transformer\n ): HttpFoundation\\JsonResponse {\n $this->authorize('fetchTopicTriggers', $activity);\n\n $logger->debug(__METHOD__, [\n 'activity' => $activity->id_string,\n ]);\n\n if (! $activity->isProcessed()) {\n return new HttpFoundation\\JsonResponse([]);\n }\n\n $payload = [];\n\n if ($activity->hasTopicTriggers()) {\n $payload = $activity->getTopicTriggersSorted()\n ->map(\n static fn (Activity\\TopicTrigger $activityTopicTrigger): array\n => $transformer->transform($activityTopicTrigger)\n )\n ->values()\n ->all();\n }\n\n return new HttpFoundation\\JsonResponse($payload);\n }\n\n /**\n * @param Activity $activity\n * @param StatsTransformer $statsTransformer\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function stats(Activity $activity, StatsTransformer $statsTransformer)\n {\n $this->authorize('stream', $activity);\n\n if (! $activity->hasTranscription()) {\n return $this->response->errorNotFound('Waveform data is not yet generated.');\n }\n\n $this->response\n ->getManager()\n ->parseIncludes(['wavedata'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($activity, $statsTransformer);\n }\n\n public function destroy(Activity $activity)\n {\n $this->authorize('delete', $activity);\n\n $activity->delete();\n\n \\Log::info('Soft delete activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n\n return $this->response->withNoContent();\n }\n\n public function note(Activity $activity)\n {\n $this->authorize('note', $activity);\n\n $this->request->validate([\n 'note' => 'required|min:1|max:2000',\n 'time' => 'required|numeric|min:0|max:86400',\n ]);\n\n $note = $this->request->input('note');\n $time = $this->request->input('time');\n\n $this->activityService->setActivity($activity);\n $this->activityService->takeNote($this->getUser(), $note, $time);\n\n return $this->response->withCreated();\n }\n\n /**\n * Mark an activity as private.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPrivate(Activity $activity)\n {\n $this->authorize('markAsPrivate', $activity);\n\n if ($activity->is_private === false) {\n $activity->is_private = true;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * Mark an activity as public.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPublic(Activity $activity)\n {\n $this->authorize('markAsPublic', $activity);\n\n if ($activity->is_private) {\n $activity->is_private = false;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws LogicException\n */\n public function fetchCloudFrontS3MediaKeys(Activity $activity, PlaybackService $playbackService): JsonResponse\n {\n $masterTrack = $activity->masterTrack()->first();\n\n if (! $masterTrack instanceof Track) {\n throw new LogicException(sprintf('Master track not found for activity \"%s\"', $activity->getUuid()));\n }\n\n return $this->response->withArray(\n $playbackService->generateCookies(\n $masterTrack,\n $this->request->ip(),\n ),\n );\n }\n\n /**\n * @throws ValidationException\n */\n private function updateOrCreateActivitySearch(Request $request, ?Search $search = null): Search\n {\n $request->validate([\n 'name' => 'required|string|min:2|max:100',\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $searchName = $request->input('name');\n\n if ($search !== null) {\n $search->update([\n 'name' => $searchName,\n ]);\n\n return $search;\n }\n\n $request->validate([\n 'filters' => ['required', 'array', new MultidimensionalArrayMaxCharRule(limit: 255)],\n 'nudges' => 'array|max:' . count(Nudge::MAP_CHANNEL),\n 'nudges.*.channel' => 'required|in:' . implode(',', Nudge::MAP_CHANNEL),\n 'nudges.*.frequency' => 'required|in:' . implode(',', Nudge::MAP_FREQUENCY),\n 'nudges.*.expiresAt' => [\n 'required',\n 'date',\n 'after:today',\n 'before_or_equal:' . now()->addYear()->format('Y-m-d'),\n ],\n ]);\n\n $searchCriteria = Criteria::createFromRequest(\n Collection::make($request->input('filters', []))->all(),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($searchCriteria, $user);\n $this->validateSearch($request, $filterSet, 'filters.');\n\n /** @var Search $search */\n $search = Search::create([\n 'name' => $searchName,\n 'uuid' => Uuid::uuid4()->toString(),\n 'user_id' => $user->getId(),\n ]);\n\n Collection::make($request->input('nudges', []))\n ->each(fn (array $attributes): Nudge => $this->nudgeFactory->createNudge($search, $attributes));\n\n $this->storeNamedSearchFilters(Collection::make($request->all()), $search, $filterSet, 'filters.');\n\n return $search;\n }\n\n private function resolveAccount(\n Team $team,\n Contact $contact,\n ServiceInterface $crmService,\n array $prospects,\n ): ?Account {\n $this->logger->info('Resolving account from contact');\n $account = $contact->getAccount();\n\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS)) {\n $this->logger->info('Team does not have feature to link activity to multiple prospects');\n\n return $account;\n }\n\n $this->logger->info('Resolving account from prospect data');\n $accountData = array_filter(\n $prospects,\n static fn (array $prospectData): bool => $prospectData['type'] === 'account'\n );\n\n if (! empty($accountData)) {\n $this->logger->info('Found account data in prospects');\n $accountData = reset($accountData);\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountData['id'])->first();\n\n if (! $account instanceof Account) {\n $this->logger->info('Account not found in database, syncing from CRM');\n $account = $crmService->syncAccount($accountData['id']);\n }\n }\n\n $this->logger->info('Resolved account', ['account' => $account->getId()]);\n\n return $account;\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Http\\Controllers\\API;\n\nuse Carbon\\Carbon;\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Exception;\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Validation\\Rule;\nuse Illuminate\\Validation\\Rules\\In;\nuse Illuminate\\Validation\\ValidationException;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ActivityAnalytics;\nuse Jiminny\\Component\\ActivitySearch;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Contracts\\ES\\Events\\UpdateSingleEntity;\nuse Jiminny\\Contracts\\ES\\UpdateTargetEnum;\nuse Jiminny\\Contracts\\Nudge\\NudgeFactoryInterface;\nuse Jiminny\\Contracts\\Playlist\\PlaylistTrackFactoryInterface;\nuse Jiminny\\Contracts\\Repositories\\PlaylistActivityRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Enums\\TeamSetting;\nuse Jiminny\\Events\\Activities\\AiAutomation\\ActivityProspectAdded;\nuse Jiminny\\Events\\Activities\\Coaching\\Coached;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Controllers\\CommentContextInterface;\nuse Jiminny\\Http\\Responses\\Api\\AbstractResponse;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\ActivityCommentTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTopicTriggerTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTransformer;\nuse Jiminny\\Http\\Transformers\\AvailabilityNotificationTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingFeedbackTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingSectionsTransformer;\nuse Jiminny\\Http\\Transformers\\SearchTransformer;\nuse Jiminny\\Http\\Transformers\\StatsTransformer;\nuse Jiminny\\Jobs\\Crm\\SaveActivity;\nuse Jiminny\\Jobs\\Crm\\UpdateStage;\nuse Jiminny\\Jobs\\Telephony\\StartRecording;\nuse Jiminny\\Jobs\\Telephony\\StopRecording;\nuse Jiminny\\Jobs\\Telephony\\ToggleRecording;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\CoachingFeedback;\nuse Jiminny\\Models\\CoachingSection;\nuse Jiminny\\Models\\CoachingSectionCriterion;\nuse Jiminny\\Models\\CoachingSectionFeedback;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\LanguageDialect;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Nudge;\nuse Jiminny\\Models\\PlaybookCategory;\nuse Jiminny\\Models\\Playlist;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\Track;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\CoachingFeedbackRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Rules\\MultidimensionalArrayMaxCharRule;\nuse Jiminny\\Services\\ActivityService;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Services\\PlaybackService;\nuse Jiminny\\Services\\UserService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\nuse Ramsey\\Uuid\\Uuid;\nuse Sentry;\nuse Symfony\\Component\\HttpFoundation;\n\nfinal class ActivityController extends Controller implements CommentContextInterface\n{\n // Number of minutes to look back on activities. i.e. a timeout on activity duration.\n private const int LOOK_BACK = 180;\n\n public function __construct(\n private ProviderRegistry $providerRegistry,\n private ActivityService $activityService,\n Response $response,\n private UserService $userService,\n private ActivitySearch\\Service\\ActivitySearch $activitySearch,\n private NudgeFactoryInterface $nudgeFactory,\n private ActivityCommentService $activityCommentService,\n private LoggerInterface $logger,\n private readonly CoachingFeedbackRepository $coachingFeedbackRepository,\n private readonly TeamRepository $teamRepository,\n ) {\n parent::__construct($response);\n }\n\n public static function getCommentImplementation(): string\n {\n return Comment::class;\n }\n\n public function delete()\n {\n $this->request->validate([\n '*' => 'uuid:activities',\n ]);\n\n $deletedIds = [];\n foreach ($this->request->all() as $activityId) {\n $activity = Activity::idOrUuId($activityId);\n\n try {\n if ($this->authorize('delete', $activity)) {\n $activity->delete();\n $deletedIds[] = $activityId;\n\n \\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n }\n } catch (AuthorizationException $authorizationException) {\n // They didn't have permission.\n }\n }\n\n return $this->response->withArray($deletedIds);\n }\n\n public function update(Request $request, Activity $activity)\n {\n $this->authorize('updateMetadata', $activity);\n\n $request->validate([\n 'title' => 'string|max:250',\n 'category_id' => 'uuid:playbook_categories',\n 'language' => [\n new In(\n LanguageDialect::query()\n ->with('language')\n ->cursor()\n ->map(static function (LanguageDialect $languageDialect): string {\n return $languageDialect->getLanguageLocale();\n })\n ->all()\n ),\n ],\n ]);\n\n if ($request->has('title')) {\n $activity->title = $request->input('title');\n }\n\n if ($request->has('category_id')) {\n $category = PlaybookCategory::uuid($request->input('category_id'));\n\n if ($category->playbook->team_id !== $request->user()->team_id) {\n return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n if ($request->has('language')) {\n if (! $activity->isInProgress()) {\n return $this->response->withError(\n 'Activity language can only be set while the meeting is in progress.',\n 400\n );\n }\n\n $activity->setLanguageCode($request->input('language'));\n }\n\n $activity->save();\n\n return $this->response->withOk();\n }\n\n // XXX: This should be merged with the update method.\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws SocialAccountTokenInvalidException\n *\n * @return mixed\n */\n public function summarize(Activity $activity): mixed\n {\n $this->logger->info('[Log Activity] Summarizing activity ', [\n 'activityId' => $activity->getUuid(),\n 'payload' => $this->request->all(),\n ]);\n $this->authorize('update', $activity);\n\n $this->logger->info('[Log Activity] Validating summary');\n // Validate the payload.\n $this->validateSummary($activity);\n\n // All objects must belong to this team.\n /** @var User $user */\n $user = $this->request->user();\n $team = $user->getTeam();\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n try {\n $crmUser = $user;\n if ($user->isCrmRequired() === false) {\n $crmUser = $team->owner;\n }\n $crmService->setUser($crmUser);\n } catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());\n }\n\n $rawEntities = $this->request->input('entities');\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid(\n $this->request->input('layout_id')\n );\n\n // Delay execution of CRM jobs to avoid locking issues.\n $jobDelay = 0;\n\n // If we have arrived from a notification, mark it as read.\n $notificationId = $this->request->input('nId');\n if ($notificationId) {\n $notification = $user->unreadNotifications->where('id', $notificationId)->first();\n\n if ($notification) {\n $notification->markAsRead();\n }\n }\n\n $title = $this->request->input('title');\n $prospects = $this->request->input('prospects');\n $opportunityId = $this->request->input('opportunity_id');\n $stageId = $this->request->input('stage_id');\n $categoryId = $this->request->input('category_id');\n $summary = $this->request->input('summary');\n $crmProviderId = $this->request->input('crm_id');\n $isInternal = $this->request->input('is_internal') ?? false;\n\n $lead = null;\n $category = null;\n $account = null;\n $contact = null;\n $opportunity = null;\n $stage = null;\n $callStage = null;\n\n foreach ($prospects as $prospectData) {\n $objectId = $prospectData['id'];\n\n if ($objectId === null) {\n continue;\n }\n\n $objectType = $prospectData['type'];\n $this->logger->info('debug', ['prospect_data' => $prospectData]);\n\n try {\n if ($objectType === null) {\n $this->logger->info('no object type');\n if ($crmService instanceof SupportsObjectTypeParseInterface) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n }\n\n switch ($objectType) {\n case 'lead':\n $this->logger->info('Processing lead');\n /** @var Lead|null $lead */\n $lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();\n\n // Lead does not exist locally, import it.\n if ($lead === null) {\n $this->logger->info('Lead does not exist locally');\n /** @var Lead $lead */\n $lead = $crmService->syncLead($objectId);\n }\n\n $this->logger->info('Lead found', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n if ($stageId === null) {\n $this->logger->info('Stage ID is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $lead->stage;\n\n break;\n }\n\n $this->logger->info('Looking for stage');\n // Determine if they have changed the stage.\n /** @var Stage $stage */\n $stage = $team->crm->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_LEAD)\n ->firstOrFail();\n\n $this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);\n if ($lead->stage_id && $lead->stage_id !== $stage->id) {\n $this->logger->info('Stage has changed');\n // Storage current stage on activity.\n $callStage = $lead->stage;\n\n // The stage has changed, update in remote CRM.\n dispatch(new UpdateStage($activity, $lead, $callStage, $stage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing lead stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->getName(),\n $stage->getName()\n ),\n [\n 'user' => $user->getUuid(),\n 'lead' => $lead->getUuid(),\n ]\n );\n } else {\n $this->logger->info('Stage has not changed');\n // Stage remains as current.\n $callStage = $stage;\n }\n\n break;\n\n case 'account':\n $this->logger->info('Processing account');\n // If the object is not a lead, it should be an account.\n $account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();\n\n // Account does not exist locally, import it.\n if ($account === null) {\n $this->logger->info('Account does not exist locally');\n $account = $crmService->syncAccount($objectId);\n }\n\n $this->logger->info('Account found', ['accountId' => $account->id]);\n\n break;\n case 'contact':\n $this->logger->info('processing contact');\n $contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $this->logger->info('contact does not exist locally');\n $contact = $crmService->syncContact($objectId);\n }\n\n $this->logger->info('resolving account');\n $account = $this->resolveAccount($team, $contact, $crmService, $prospects);\n\n break;\n }\n\n // If they have specified an opportunity, retrieve this with stage.\n if ($opportunityId) {\n $this->logger->info('opportunity id is set');\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if ($opportunity === null) {\n $this->logger->info('opportunity does not exist locally');\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n if ($stageId === null) {\n $this->logger->info('stage id is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $opportunity->stage ?? null;\n } else {\n $this->logger->info('looking for stage');\n /** @var ?Stage $opportunityStage */\n $opportunityStage = $team->crm\n ->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n // There is a chance we still cannot import this opportunity.\n if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {\n $this->logger->info('opportunity stage has changed');\n // Storage current stage on activity.\n $callStage = $opportunity->stage;\n\n dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing opportunity stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->name,\n $opportunityStage->name\n ),\n [\n 'userId' => $user->id_string,\n 'opportunityId' => $opportunity->id_string,\n ]\n );\n } else {\n $this->logger->info('opportunity stage has not changed');\n // Stage remains as current.\n $callStage = $opportunityStage;\n }\n }\n }\n\n if ($crmProviderId) {\n // Cast $crmProviderId to string otherwise it won't use database index for some records\n $linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();\n\n // Check if this activity has already been assigned to a different activity.\n if ($linkedActivity && $linkedActivity->id !== $activity->id) {\n throw new InvalidArgumentException(\n 'Sorry, the linked task has already been logged under a different call. '\n . 'Please choose another linked task.'\n );\n }\n }\n } catch (InvalidArgumentException $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($exception->getMessage());\n } catch (Exception $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorInternalError(\n 'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'\n );\n }\n }\n\n if ($categoryId) {\n $category = PlaybookCategory::uuid($categoryId);\n\n if ($category->playbook->team_id !== $team->id) {\n throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n $this->logger->info('Prospect data', [\n 'lead_id' => $lead?->getId(),\n 'account_id' => $account?->getId(),\n 'contact_id' => $contact?->getId(),\n 'opportunity_id' => $opportunity?->getId(),\n 'stage_id' => $stage?->getId(),\n ]);\n\n if ($title) {\n $activity->title = $title;\n }\n\n if ($summary) {\n $activity->summary = $summary;\n }\n\n if ($crmProviderId) {\n $activity->crm_provider_id = $crmProviderId;\n }\n\n if ($callStage) {\n $this->logger->info('Setting stage id', ['stageId' => $callStage->id]);\n $activity->stage_id = $callStage->id;\n }\n\n if ($lead) {\n $this->logger->info('Setting lead id', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n // If we are changed from an account > lead, unset the account data.\n $this->logger->info('Unsetting account id, opportunity id, contact id, value');\n $activity->account_id = null;\n $activity->opportunity_id = null;\n $activity->contact_id = null;\n $activity->value = null;\n }\n\n if ($account) {\n $this->logger->info('Setting account id', ['accountId' => $account->id]);\n $activity->account_id = $account->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('unsetting lead id');\n $activity->lead_id = null;\n\n // Unset the contact if switching different accounts. Will be set up below if still applicable.\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {\n $this->logger->info('Unsetting contact id');\n $activity->contact_id = null;\n }\n }\n\n if ($opportunity) {\n $this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);\n $this->logger->info('unsetting lead id');\n $activity->opportunity_id = $opportunity->id;\n $activity->value = $opportunity->value;\n\n // If we are changed from an lead > account, unset the lead data.\n $activity->lead_id = null;\n }\n\n if ($contact) {\n $this->logger->info('setting contact id', ['contactId' => $contact->id]);\n $activity->contact_id = $contact->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('Unsetting lead id');\n $activity->lead_id = null;\n }\n\n $activity->is_internal = $isInternal;\n $activity->save();\n $activity->refresh();\n\n $this->logger->notice('Activity saved', [\n 'activity_id' => $activity->getId(),\n 'lead_id' => $activity->lead_id,\n 'account_id' => $activity->account_id,\n 'contact_id' => $activity->contact_id,\n 'opportunity_id' => $activity->opportunity_id,\n 'stage_id' => $activity->stage_id,\n 'crm_provider_id' => $activity->getCrmProviderId(),\n ]);\n\n // Store entities as field data on the activity.\n $updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);\n\n if ($activity->isLoggable()) {\n // Follow-up Task or Event data.\n $followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);\n\n $this->logger->info('CRM LOG manual log triggered', [\n 'activityId' => $activity->getUuid(),\n 'followupData' => $followupData,\n 'userId' => $user->getUuid(),\n ]);\n\n // Store data in the CRM.\n // ++add check for crm_required\n $job = new SaveActivity($activity, $followupData);\n\n if ($updatedData) {\n $job->delay(Carbon::now()->addMinutes($jobDelay));\n }\n\n dispatch($job);\n\n // Manually dispatch log for Opportunity or Prospect added\n if ($activity->hasOpportunity() || $activity->hasProspect()) {\n event(new ActivityProspectAdded(\n activity: $activity,\n eventSource: 'manually-log-crm-data'\n ));\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.\n *\n * @param ServiceInterface $service\n * @param Activity $activity\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array\n {\n $updatedData = [];\n $existingData = $activity->data()->get();\n\n // We need to delete any existing data to overwrite with latest values.\n $activity->data()->delete();\n\n $layoutEntities = $layout->entities()\n ->with('field', 'parent')\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->get();\n\n /** @var LayoutEntity $entity */\n foreach ($layoutEntities as $entity) {\n // If the user has provided a value for this entity\n if (array_key_exists($entity->id_string, $entities)) {\n $value = $entities[$entity->id_string];\n\n // Convert raw data into values that the CRM can consume.\n if ($value) {\n $value = $service->normalizeValue($entity->field->type, $value);\n }\n\n // Check the field is part of the activity-summary section.\n if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {\n // This is the internal database ID, not the external CRM ID.\n $objectId = null;\n\n switch ($entity->field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $objectId = $activity->account_id;\n\n break;\n\n case Field::OBJECT_CONTACT:\n $objectId = $activity->contact_id;\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n $objectId = $activity->opportunity_id;\n\n break;\n\n case Field::OBJECT_LEAD:\n $objectId = $activity->lead_id;\n\n break;\n\n case Field::OBJECT_TASK:\n case Field::OBJECT_EVENT:\n $objectId = $activity->id;\n\n break;\n }\n\n if ($objectId) {\n /** @var FieldData $data */\n $data = $activity->data()->create([\n 'crm_layout_entity_id' => $entity->id,\n 'crm_field_id' => $entity->crm_field_id,\n 'object_type' => $entity->field->object_type,\n 'object_id' => $objectId,\n 'value' => $value,\n ]);\n\n // Never send read-only field data to the CRM.\n if ($entity->read_only === false && $entity->is_visible) {\n $existingValue = $existingData\n ->where('crm_layout_entity_id', $entity->id)\n ->where('crm_field_id', $entity->crm_field_id)\n ->where('object_type', $entity->field->object_type)\n ->where('object_id', $objectId)\n ->first();\n\n // If the field was actually changed, we need to reflect this in the CRM too.\n if ($existingValue === null || $existingValue->value !== $value) {\n $updatedData[] = $data->id;\n }\n }\n }\n }\n }\n }\n\n return $updatedData;\n }\n\n /**\n * Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.\n *\n * @param ServiceInterface $crmService\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array\n {\n $fieldData = [];\n foreach ($entities as $entityId => $value) {\n // Only bother with fields that have a value.\n if ($value) {\n // Extract the entity from the UUID. Check the field is valid and part of the follow-up section.\n $entity = $layout->entities()\n ->uuid($entityId, false)\n ->whereHas('parent', function ($query) {\n $query->where('label', 'follow-up');\n })\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->first();\n\n if ($entity) {\n // Convert raw data into values that the CRM can consume.\n $value = $crmService->normalizeValue($entity->field->type, $value);\n\n // Add the field and value to the payload.\n $fieldData += [\n $entity->field->crm_provider_id => $value,\n ];\n }\n }\n }\n\n return $fieldData;\n }\n\n /**\n * @param Activity $activity\n */\n private function validateSummary(Activity $activity): void\n {\n $team = $activity->user->team;\n $crmProvider = $team->crm->provider;\n $attributes = [];\n\n $rules = [\n 'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,\n 'title' => 'string|max:250',\n 'prospects' => 'required|array',\n 'opportunity_id' => new CrmReference($crmProvider),\n 'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',\n 'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator\n 'summary' => 'max:50000',\n 'nId' => 'exists:notifications,id',\n 'crm_id' => new CrmReference($crmProvider),\n 'entities' => 'array',\n 'is_internal' => 'boolean',\n ];\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));\n\n // Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.\n $entities = $layout->entities()\n ->where('read_only', 0)\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->whereHas('parent', function ($query) use ($activity) {\n if ($activity->isLoggable() === false) {\n $query->where('label', '<>', 'follow-up');\n }\n });\n\n $isInternal = $this->request->input('is_internal', false);\n\n foreach ($entities->get() as $entity) {\n $rules += $this->buildFieldValidator($entity, $isInternal);\n $attributes += $this->buildFieldMessage($entity);\n }\n\n $this->request->validate($rules, [], $attributes);\n }\n\n private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array\n {\n return [\n 'entities.' . $entity->id_string => $entity->getValidator($isInternal),\n ];\n }\n\n /**\n * @param LayoutEntity $entity\n *\n * @return array\n */\n private function buildFieldMessage(LayoutEntity $entity): array\n {\n $label = $entity->label;\n if ($label === null) {\n $label = $entity->field->label;\n }\n\n return [\n 'entities.' . $entity->id_string => $label,\n ];\n }\n\n public function search(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->debugLog(\n $user,\n 'User extracted from request',\n ['user' => $user->getId(), 'tz' => $user->getTimezone()]\n );\n\n $searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());\n\n $this->debugLog(\n $user,\n 'ActivitySearch criteria built',\n ['searchCriteria' => $searchCriteria]\n );\n\n $filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);\n\n $this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);\n\n $this->validateSearch($request, $filterSet);\n\n $this->debugLog($user, 'Request validated');\n\n $searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);\n\n /** @var Collection<Activity> $activities */\n $activities = $searchResponse['results'];\n\n $this->debugLog($user, 'Activities ES response extracted');\n\n $hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(\n $user->getTeamId(),\n TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),\n );\n\n if ($hideInternalMeetingsSetting?->getValue() === '1') {\n $activities = $activities->filter(function (Activity $activity) {\n if ($activity->is_internal && empty($activity->actual_start_time)) {\n return false;\n }\n\n return true;\n });\n }\n\n $this->debugLog($user, 'Internal meetings (?!) filtered');\n\n $this->response->getManager()\n ->parseIncludes([\n 'category',\n 'organizer.group',\n 'prospect',\n 'stage',\n 'opportunity',\n 'stats',\n 'scorecards',\n 'masterTrack',\n 'activeParticipants',\n 'notification',\n ])\n ->setSerializer(new JsonSerializer());\n\n $transformerExcludes = $this->request->input('exclude');\n if ($transformerExcludes) {\n $this->response->getManager()->parseExcludes($transformerExcludes);\n }\n\n $this->debugLog($user, 'Response Manager (?!) applied');\n\n $transformer = new ActivityTransformer();\n $transformer->setConsumer($user);\n\n $this->debugLog($user, 'Activity Transformer added');\n\n $resource = new \\League\\Fractal\\Resource\\Collection($activities, $transformer);\n $page = $searchCriteria->getPageNumber();\n\n $this->debugLog($user, 'Search criteria page number called', ['page' => $page]);\n\n $histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');\n\n $this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);\n\n return $this->response->withArray([\n 'pagination' => [\n 'total' => $searchResponse['totalHits'],\n 'current' => $page,\n 'prev' => max($page - 1, 1),\n 'next' => $page + 1,\n ],\n 'results' => $this->response->getManager()->createData($resource)->toArray(),\n 'histogram' => $histogram,\n ]);\n }\n\n private function debugLog(User $user, string $logMessage, ?array $context = []): void\n {\n // Debug for Learning People Only\n if ($user->getTeamId() !== 260) {\n return;\n }\n\n Log::notice(\n sprintf('[activity-search-controller] %s', $logMessage),\n $context\n );\n }\n\n /** @throws ValidationException */\n private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void\n {\n $rules = [\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ];\n\n if ($prefix !== null && mb_strpos($prefix, '.') !== false) {\n $rules[rtrim($prefix, '.')] = sprintf(\n 'required|array|max:%d',\n $filterSet->count()\n );\n }\n\n $validationRules = $filterSet->getValidationRules($prefix)\n ->merge($rules)\n ->all();\n\n $request->validate($validationRules);\n }\n\n public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $search = $this->updateOrCreateActivitySearch($request);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function updateActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('update', $search);\n\n $this->updateOrCreateActivitySearch($request, $search);\n\n return $this->response->withOk();\n }\n\n private function storeNamedSearchFilters(\n Collection $request,\n Search $search,\n FilterDefinitionCollection $filterSet,\n ?string $prefix = null,\n ): self {\n $arrayTypeProperties = $filterSet\n ->getPropertyTypes([\n FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,\n ])\n ->all();\n\n $supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);\n\n foreach ($supportedRequestProperties as $requestPropertyName) {\n if (! array_has($request, $requestPropertyName)) {\n continue;\n }\n\n /** @var string|string[] $propertyValue */\n $propertyValue = array_get($request, $requestPropertyName);\n $propertyName = $prefix === null\n ? $requestPropertyName\n : mb_substr($requestPropertyName, mb_strlen($prefix));\n\n $isArrayType = array_has($arrayTypeProperties, $propertyName);\n\n if (! $isArrayType) {\n /** @var string $requestPropertyValue */\n\n $search->filters()->updateOrCreate(\n [\n 'filter' => $propertyName,\n ],\n [\n 'value' => $propertyValue,\n ]\n );\n\n continue;\n }\n\n /** @var string[] $requestPropertyValue */\n\n /** @var SearchFilter[]|Collection $existingFilterValues */\n $existingFilterValuesKeyed = $search->filters()\n ->where('filter', $propertyName)\n ->get()\n ->keyBy('id');\n\n // Iterate over values provided as request parameters\n foreach ($propertyValue as $value) {\n /** @var SearchFilter|null $valueFilter */\n $valueFilter = $search->filters()\n ->where(\n [\n 'filter' => $propertyName,\n 'value' => $value,\n ]\n )\n ->first();\n\n if ($valueFilter !== null) {\n // Remove filter value pair from list to be deleted\n $existingFilterValuesKeyed->forget($valueFilter->id);\n } else {\n // Add new filter/value pair\n $search->filters()->updateOrCreate([\n 'filter' => $propertyName,\n 'value' => $value,\n ]);\n }\n }\n\n // Delete filter value pairs for this filter that no longer exist in request parameters\n foreach ($existingFilterValuesKeyed as $existingFilter) {\n $existingFilter->delete();\n }\n }\n\n /** @var Collection<int, SearchFilter> $filtersKeyed */\n $filtersKeyed = $search->filters()->get()->keyBy('filter');\n\n // wipe removed filters from this search\n foreach ($filtersKeyed as $filterName => $filter) {\n if (array_has($request, $prefix . $filterName)) {\n continue;\n }\n\n // Remove all filter values for this filter\n $search->filters()->where('filter', $filterName)->delete();\n }\n\n return $this;\n }\n\n /**\n * @throws AuthorizationException\n */\n public function fetchActivitySearch(\n Search $search,\n Request $request,\n SearchTransformer $searchTransformer,\n ): JsonResponse {\n $this->authorize('view', $search);\n\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection(\n $user->searches()->get(),\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n /**\n * Deletes a saved search\n *\n * @param Request $request\n * @param Search $search\n *\n * @throws Exception\n *\n * @return JsonResponse\n */\n public function deleteActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('delete', $search);\n\n // Orphan any AutomatedReports that use this search\n $search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);\n\n // Delete filters and the search itself\n $search->filters()->delete();\n $search->delete();\n\n return $this->response->withOk();\n }\n\n public function live(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n $user = $this->getUserFromRequest($request);\n\n $this->request->validate([\n 'sort_direction' => 'in:asc,desc',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ]);\n\n $activities = $repository->getLiveCoachingEligibleActivities(\n user: $user,\n lookBackMinutes: self::LOOK_BACK,\n limit: (int) $this->request->input('limit', 25),\n page: (int) $this->request->input('page', 1),\n sortBy: ['actual_start_time', 'scheduled_start_time'],\n sortDirection: (string) $this->request->input('sort_direction', 'asc'),\n );\n\n $this->response\n ->getManager()\n ->parseIncludes(['organizer.group', 'prospect'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($activities, new ActivityTransformer());\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function show(Activity $activity, ActivityService $activityService): JsonResponse\n {\n $this->authorize('show', $activity);\n\n $user = $activity->getUser();\n $team = $user->getTeam();\n\n // Sync the opportunity with the latest data if possible.\n if ($activity->opportunity_id) {\n try {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n if (! $user->isCrmRequired()) {\n $crmService->setUser($team->getOwner());\n } else {\n $crmService->setUser($user);\n }\n\n $crmService->syncOpportunity($activity->opportunity->crm_provider_id);\n } catch (Exception $exception) {\n // Move on.\n }\n }\n\n $activityData = $activityService->getActivityData($this->request->user(), $activity);\n\n return response()->json($activityData);\n }\n\n public function createRecording(Activity $activity)\n {\n $this->authorize('record', $activity);\n\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Tell Twilio to start recording this activity.\n if ($activity->recording_state === Activity::RECORDING_OFF) {\n $job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withCreated();\n }\n\n return $this->response->errorGone('Activity is already recording.');\n }\n\n public function updateRecording(Request $request, Activity $activity)\n {\n $this->authorize('record', $activity);\n\n $request->validate([\n 'preference' => 'boolean',\n 'state' => [\n 'string',\n Rule::in([\n Activity::RECORDING_IN_PROGRESS,\n Activity::RECORDING_PAUSED,\n ]),\n ],\n ]);\n\n if ($request->has('state')) {\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Toggle the recording state between paused and resumed.\n if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {\n $job = (new ToggleRecording($activity, $request->input('state')))\n ->onQueue(Constants::QUEUE_CONFERENCES);\n\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Recording is not toggleable.');\n }\n\n if ($request->has('preference')) {\n $activity->update([\n 'recording_preference' => $request->input('preference') ? 1 : 0,\n ]);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorWrongArgs('Something went wrong');\n }\n\n public function stopRecording(Activity $activity)\n {\n $this->authorize('stopRecord', $activity);\n\n // Tell Twilio to stop recording this activity.\n if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {\n $job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Activity is not recording.');\n }\n\n /**\n * Add activity to this user's favorites playlist\n *\n * @throws AuthorizationException\n */\n public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse\n {\n $this->authorize('favorite', $activity);\n\n $user = $this->getUserFromRequest($this->request);\n $favorite = $activity->wasFavoritedBy($user);\n $name = $activity->activity_title ?? '';\n\n // It needs to check at least one record.\n if (! $favorite) {\n $favoritePlaylist = $user->favoritePlaylist();\n\n $playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(\n $activity,\n $user,\n $favoritePlaylist\n );\n\n if ($playlistActivity !== null) {\n $playlistActivity->update(\n // Just update, don't sort.\n ['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],\n );\n } else {\n $playlistActivity = $activity->playlistActivities()->create([\n 'playlist_id' => $favoritePlaylist->getId(),\n 'user_id' => $user->getId(),\n 'start_time' => 0,\n 'name' => mb_strimwidth($name, 0, 100),\n ]);\n // Sort it on top.\n $playlistActivity->update(\n [\n 'sort' => $playlistActivityRepository->calculateNewSortOrder(\n null,\n $playlistActivity,\n ),\n ],\n );\n }\n\n $playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);\n\n return new JsonResponse([], JsonResponse::HTTP_CREATED);\n }\n\n return new JsonResponse(\n [\n 'error' => [\n 'code' => AbstractResponse::CODE_CONFLICT,\n 'http_code' => JsonResponse::HTTP_CONFLICT,\n 'message' => 'Resource Already Exists',\n ],\n ],\n JsonResponse::HTTP_CONFLICT,\n );\n }\n\n /**\n * Remove activity from this user's favorites playlist\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unfavorite(Activity $activity)\n {\n $user = $this->request->user();\n\n $favorites = $activity->favoritedBy($user);\n\n if ($favorites && $favorites->isEmpty()) {\n return $this->response->errorNotFound('Favorite not found.');\n }\n\n $this->authorize('unfavorite', [$activity, $favorites]);\n\n // When you unfavorite an activity,\n // it should remove all the activities in it, including snippets.\n $isDeleted = $favorites->each(function ($favorite) {\n $favorite->forceDelete();\n });\n\n if ($isDeleted) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not remove favorite.');\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function notify(Activity $activity)\n {\n $this->authorize('notify', $activity);\n\n $user = $this->request->user();\n\n $existingNotification = $activity->availabilityNotifications()\n ->where('user_id', $user->id)\n ->exists();\n\n if ($existingNotification) {\n return $this->response->errorWrongArgs('Notification is already configured.');\n }\n\n $notification = Activity\\AvailabilityNotification::create([\n 'user_id' => $user->id,\n 'activity_id' => $activity->id,\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($notification, new AvailabilityNotificationTransformer());\n }\n\n /**\n * @param Activity $activity\n * @param Activity\\AvailabilityNotification $notification\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unnotify(Activity $activity, Activity\\AvailabilityNotification $notification)\n {\n $this->authorize('unnotify', [$activity, $notification]);\n\n if ($notification->sent_at || $notification->delete()) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not delete notification.');\n }\n\n public function play(Request $request, Activity $activity)\n {\n $this->authorize('stream', $activity);\n\n $request->validate([\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $activity->plays()->create([\n 'user_id' => $user->getId(),\n 'start_time' => $request->input('start_time'),\n ]);\n\n return $this->response->withCreated();\n }\n\n /**\n * @param Activity $activity\n *\n * @return mixed\n */\n public function comment(Activity $activity)\n {\n return $this->newComment($activity);\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @return mixed\n */\n public function replyComment(Activity $activity, Comment $comment)\n {\n return $this->newComment($activity, $comment);\n }\n\n /**\n * @param Activity $activity\n * @param Comment|null $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n protected function newComment(Activity $activity, ?Comment $comment = null)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n 'type' => 'integer|between:0,3',\n 'visibility' => sprintf('nullable|integer|between:1,%d', count(Comment::getVisibilityLevels())),\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n $threadStartId = null;\n if ($comment) {\n $threadStartId = $comment->thread_start_id ?: $comment->id;\n }\n\n try {\n $newComment = Comment::create([\n 'parent_comment_id' => $comment->id ?? null,\n 'thread_start_id' => $threadStartId,\n 'activity_id' => $activity->id,\n 'user_id' => $this->request->user()->id,\n 'comment' => trim($this->request->input('comment')),\n 'start_time' => $this->request->input('start_time', 0),\n 'end_time' => $this->request->input('end_time', 0),\n 'type' => $this->request->input('type', Comment::TYPE_NEUTRAL),\n 'visibility' => $this->request->input('visibility', Comment::VISIBILITY_PUBLIC),\n ]);\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($newComment, new ActivityCommentTransformer());\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not create comment.' . $exception->getMessage());\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function updateComment(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n try {\n $comment->update([\n 'comment' => trim($this->request->input('comment')),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment.');\n }\n }\n\n public function updateCommentVisibility(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'visibility' => sprintf('integer|between:1,%d', count(Comment::getVisibilityLevels())),\n ]);\n\n $visibility = $this->request->input('visibility');\n\n if ($comment->parent !== null) {\n return $this->response->errorWrongArgs('Comment visibility can only be updated on top level comments.');\n }\n\n try {\n $this->activityCommentService->updateCommentVisibility($comment, $visibility);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment\\'s visibility.');\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function deleteComment(Activity $activity, Comment $comment)\n {\n $this->authorize('deleteComment', [$activity, $comment]);\n\n // Delete comment and any children.\n $comment->delete();\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function fetchComments()\n {\n $user = $this->request->user();\n $this->request->validate([\n 'forUserId' => 'uuid:users,team_id,' . $user->team_id,\n 'types' => 'array',\n 'types.*' => 'integer|between:0,3',\n ]);\n $forUser = null;\n\n $types = [Comment::TYPE_NEUTRAL, Comment::TYPE_GAME_CHANGER, Comment::TYPE_POSITIVE];\n $user = $this->request->user();\n if ($this->request->has('forUserId')) {\n $forUser = $user->team->users()->uuid($this->request->input('forUserId'));\n }\n\n $comments = Comment::query()\n ->whereHas('activity', static function (Builder $builder) use ($user, $forUser): void {\n $builder\n // I left feedback on my own activity; or\n ->where('activities.user_id', $user->getId());\n if ($forUser) {\n // I left feedback on any activity for this user.\n $builder->orWhere([\n 'user_id' => $user->getId(),\n 'activities.user_id' => $forUser->getId(),\n ]);\n }\n })\n ->whereIn('type', $this->request->input('types', $types))\n ->orderBy('created_at', 'desc')\n ->get();\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity', 'user'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($comments, new ActivityCommentTransformer());\n }\n\n public function deleteCoachingFeedback(Activity $activity, CoachingFeedback $coachingFeedback)\n {\n $this->authorize('deleteCoachingFeedback', [$activity, $coachingFeedback]);\n $activity = $coachingFeedback->getActivity();\n\n if ($coachingFeedback->delete()) {\n event(new UpdateSingleEntity(\n entityId: $activity->getId(),\n updateTarget: UpdateTargetEnum::ACTIVITY,\n purpose: 'delete-coaching-feedback',\n ));\n\n return $this->response->withOk();\n }\n\n return $this->response->withError('Delete operation failed. Contact support.', 500);\n }\n\n /**\n * Add new or update Coaching feedback\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws \\Illuminate\\Validation\\ValidationException\n *\n * @return mixed\n */\n public function putCoachingFeedback(Request $request, Activity $activity)\n {\n $user = $request->user();\n\n if (! $user instanceof User) {\n abort(403);\n }\n $teamId = $user->getTeamId();\n\n $this->authorize('coach', $activity);\n\n $this->request->validate([\n 'coach_id' => 'required|uuid:users,team_id,' . $teamId,\n 'coachee_id' => 'required|uuid:users,team_id,' . $teamId,\n 'visibility' => ['required', Rule::in(CoachingFeedback::VISIBILITIES)],\n 'coaching_sections.*.uuid' => 'required|uuid:coaching_sections',\n 'coaching_sections.*.score' => ['required', Rule::in(CoachingSectionFeedback::SCORES)],\n 'coaching_sections.*.summary' => 'string|max:10000',\n 'coaching_sections.*.criteria.*.uuid' => 'required|uuid:coaching_section_criteria',\n 'coaching_sections.*.criteria.*.note' => 'required|string|max:10000',\n 'sharedWithUsers' => [\n 'required_if:visibility,' . CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS,\n 'array',\n ],\n 'sharedWithUsers.*' => [\n 'uuid:users,team_id,' . $teamId,\n ],\n ]);\n\n /** @var User $coach */\n $coach = User::uuid($this->request->input('coach_id'));\n /** @var User $coachee */\n $coachee = User::uuid($this->request->input('coachee_id'));\n $coachingSectionFeedbacks = $this->request->input('coaching_sections');\n\n $previousRecord = $this->coachingFeedbackRepository->getOneForActivityByCoacheeAndCoach(\n $coachee->getId(),\n $coach->getId(),\n $activity->getId()\n );\n $recordIsNew = false;\n if ($previousRecord === null) {\n $recordIsNew = true;\n }\n\n if (! $coachee->isSameTeamId($coach)) {\n return $this->response->errorForbidden('User not member of your team.');\n }\n\n if (! is_array($coachingSectionFeedbacks) || count($coachingSectionFeedbacks) < 1) {\n return $this->response->withError('At least one Coaching Framework Section shall be scored.', 422);\n }\n\n if (! $activity->participants()->where('participants.user_id', $coachee->id)->exists()) {\n return $this->response->withError('Coached user did not participate activity.', 422);\n }\n\n $visibility = $this->request->input('visibility');\n\n $shouldSendNotification = $recordIsNew;\n if ($recordIsNew === false && $visibility !== $previousRecord->getVisibility()) {\n $shouldSendNotification = true;\n }\n\n /**\n * Create CoachingFeedback\n *\n * @var CoachingFeedback $coachingFeedback\n */\n $coachingFeedback = $activity->coachingFeedbacks()->updateOrCreate(\n [\n 'coach_id' => $coach->id,\n 'coachee_id' => $coachee->id,\n ],\n [\n 'framework_id' => $activity->category->id,\n 'visibility' => $visibility,\n ]\n );\n\n $sharedUserIds = [];\n if ($visibility === CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS) {\n foreach ($this->request->input('sharedWithUsers') as $sharedWithUserUuid) {\n /** @var User $user */\n $user = User::uuid($sharedWithUserUuid);\n $sharedUserIds[] = $user->getId();\n }\n }\n\n $syncResult = $coachingFeedback->customAccessUsers()->sync($sharedUserIds);\n\n $scores = [];\n\n\n /**\n * Create CoachingSectionsFeedbacks.\n *\n * @var CoachingSectionFeedback $coachingSectionFeedback\n */\n foreach ($coachingSectionFeedbacks as $coachingSectionFeedbackInput) {\n $coachingSection = CoachingSection::uuid($coachingSectionFeedbackInput['uuid']);\n $coachingSectionFeedback = $coachingFeedback->sectionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_id' => $coachingSection->id,\n ],\n [\n 'score' => array_get($coachingSectionFeedbackInput, 'score'),\n 'summary' => array_get($coachingSectionFeedbackInput, 'summary') ?? '',\n ]\n );\n\n $scores[] = array_get($coachingSectionFeedbackInput, 'score');\n\n $criteria = array_get($coachingSectionFeedbackInput, 'criteria');\n if (is_array($criteria) && ! empty($criteria)) {\n foreach ($criteria as $criteriaFeedbackInput) {\n $coachingSectionFeedback->criterionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_criterion_id' => CoachingSectionCriterion::uuid(array_get($criteriaFeedbackInput, 'uuid'))\n ->id,\n ],\n ['note' => array_get($criteriaFeedbackInput, 'note')],\n );\n }\n }\n }\n\n $coachingFeedback->average_score = array_sum($scores) / count($scores);\n\n if ($recordIsNew === false && $coachingFeedback->getAverageScore() !== $previousRecord->getAverageScore()) {\n $shouldSendNotification = true;\n }\n if (! empty($syncResult['attached']) || ! empty($syncResult['detached']) || ! empty($syncResult['updated'])) {\n $shouldSendNotification = true;\n }\n\n $coachingFeedback->save();\n // ensure updated at for coaching feedback on section feedback summary added.\n $coachingFeedback->touch();\n\n if ($shouldSendNotification) {\n event(new Coached($coachingFeedback));\n }\n\n Datadog::increment('jiminny.activity.score.update', 1, ['company' => $activity->user->team->slug]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n $coachingFeedbackTransformer = new CoachingFeedbackTransformer();\n $coachingFeedbackTransformer->setConsumer($this->getUserFromRequest($request));\n\n return $this->response->withItem($coachingFeedback, $coachingFeedbackTransformer);\n }\n\n\n /**\n * Retrieve category criteria for coaching.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachingSections(Activity $activity)\n {\n $this->authorize('coach', $activity);\n\n if ($activity->category === null) {\n return $this->response->errorUnprocessable('Category has not yet been assigned.');\n }\n\n $criteria = $activity\n ->category\n ->coachingSections()\n ->where('is_enabled', 1)\n ->orderBy('sequence', 'asc');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($criteria->get(), new CoachingSectionsTransformer());\n }\n\n /**\n * @throws AuthorizationException\n * @throws ValidationException\n *\n * @return mixed\n */\n public function addToPlaylist(Activity $activity, PlaylistTrackFactoryInterface $playlistTrackFactory)\n {\n $this->request->validate([\n 'playlists' => 'required|array',\n 'playlists.*' => 'uuid:playlists',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'name' => 'required|max:100',\n ]);\n\n $this->authorize('addToPlaylist', [$activity, $this->request->input('playlists')]);\n\n $startTime = $this->request->input('start_time');\n $endTime = $this->request->input('end_time');\n $name = $this->request->input('name');\n /** @var User $user */\n $user = $this->request->user();\n\n // Get playlist by uuid.\n foreach ($this->request->input('playlists') as $playlistId) {\n // Pull out the playlist model.\n $playlist = Playlist::uuid($playlistId);\n\n $playlistTrackFactory->createTrack($playlist, $user, [\n 'name' => $name,\n 'activity' => $activity,\n 'start_time' => $startTime,\n 'end_time' => $endTime,\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function share(Request $request, Activity $activity): JsonResponse\n {\n $this->authorize('share', $activity);\n\n $request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'recipients.*.type' => 'in:user,group',\n 'recipients.*.id' => 'string|max:40',\n 'share' => 'string|max:255',\n ]);\n\n $user = $request->user();\n\n $recipients = $request->get('recipients');\n $users = $this->userService->convertRecipientsToUsers($user, $recipients);\n\n $shareData = [\n 'from_user_id' => $user->id,\n 'note' => $request->input('note'),\n 'start_time' => $request->input('start_time'),\n 'end_time' => $request->input('end_time'),\n ];\n\n // Create a share object against a notification provider channel\n if ($request->input('share')) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'notification_provider_channel' => $request->input('share'),\n ]\n )\n );\n\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n\n // Create a share object against each recipient\n foreach ($users as $recipient) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'to_user_id' => $recipient->id,\n ]\n )\n );\n\n // If parent_share_id has been selected yet\n if (! isset($shareData['parent_share_id'])) {\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachRequest(Activity $activity)\n {\n $this->authorize('coachRequest', $activity);\n\n $this->request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'coachers.*.type' => 'required|in:user',\n 'coachers.*.id' => 'required',\n ]);\n\n $coachers = $this->request->get('coachers');\n $user = $this->request->user();\n $users = $this->userService->convertRecipientsToUsers($user, $coachers);\n\n foreach ($users as $coacher) {\n CoachRequest::create([\n 'user_id' => $coacher->id,\n 'activity_id' => $activity->id,\n 'note' => $this->request->get('note'),\n 'start_time' => $this->request->get('start_time'),\n 'end_time' => $this->request->get('end_time'),\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function createActivityTopicTriggers(Activity $activity, LoggerInterface $logger): HttpFoundation\\JsonResponse\n {\n $this->authorize('analyzeTopicTriggers', $activity);\n\n if (! $activity->hasTranscription()) {\n return new HttpFoundation\\JsonResponse(\n [\n 'error' => 'Transcription not found.',\n ],\n JsonResponse::HTTP_NOT_FOUND\n );\n }\n\n $logger->info(__METHOD__ . ': queued for analysis', [\n 'activity' => $activity->id_string,\n ]);\n\n dispatch(new ActivityAnalytics\\Job\\AnalyzeActivityTopicTriggers($activity));\n\n return new HttpFoundation\\JsonResponse(null, JsonResponse::HTTP_CREATED);\n }\n\n public function fetchActivityTopicTriggers(\n Activity $activity,\n LoggerInterface $logger,\n ActivityTopicTriggerTransformer $transformer\n ): HttpFoundation\\JsonResponse {\n $this->authorize('fetchTopicTriggers', $activity);\n\n $logger->debug(__METHOD__, [\n 'activity' => $activity->id_string,\n ]);\n\n if (! $activity->isProcessed()) {\n return new HttpFoundation\\JsonResponse([]);\n }\n\n $payload = [];\n\n if ($activity->hasTopicTriggers()) {\n $payload = $activity->getTopicTriggersSorted()\n ->map(\n static fn (Activity\\TopicTrigger $activityTopicTrigger): array\n => $transformer->transform($activityTopicTrigger)\n )\n ->values()\n ->all();\n }\n\n return new HttpFoundation\\JsonResponse($payload);\n }\n\n /**\n * @param Activity $activity\n * @param StatsTransformer $statsTransformer\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function stats(Activity $activity, StatsTransformer $statsTransformer)\n {\n $this->authorize('stream', $activity);\n\n if (! $activity->hasTranscription()) {\n return $this->response->errorNotFound('Waveform data is not yet generated.');\n }\n\n $this->response\n ->getManager()\n ->parseIncludes(['wavedata'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($activity, $statsTransformer);\n }\n\n public function destroy(Activity $activity)\n {\n $this->authorize('delete', $activity);\n\n $activity->delete();\n\n \\Log::info('Soft delete activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n\n return $this->response->withNoContent();\n }\n\n public function note(Activity $activity)\n {\n $this->authorize('note', $activity);\n\n $this->request->validate([\n 'note' => 'required|min:1|max:2000',\n 'time' => 'required|numeric|min:0|max:86400',\n ]);\n\n $note = $this->request->input('note');\n $time = $this->request->input('time');\n\n $this->activityService->setActivity($activity);\n $this->activityService->takeNote($this->getUser(), $note, $time);\n\n return $this->response->withCreated();\n }\n\n /**\n * Mark an activity as private.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPrivate(Activity $activity)\n {\n $this->authorize('markAsPrivate', $activity);\n\n if ($activity->is_private === false) {\n $activity->is_private = true;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * Mark an activity as public.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPublic(Activity $activity)\n {\n $this->authorize('markAsPublic', $activity);\n\n if ($activity->is_private) {\n $activity->is_private = false;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws LogicException\n */\n public function fetchCloudFrontS3MediaKeys(Activity $activity, PlaybackService $playbackService): JsonResponse\n {\n $masterTrack = $activity->masterTrack()->first();\n\n if (! $masterTrack instanceof Track) {\n throw new LogicException(sprintf('Master track not found for activity \"%s\"', $activity->getUuid()));\n }\n\n return $this->response->withArray(\n $playbackService->generateCookies(\n $masterTrack,\n $this->request->ip(),\n ),\n );\n }\n\n /**\n * @throws ValidationException\n */\n private function updateOrCreateActivitySearch(Request $request, ?Search $search = null): Search\n {\n $request->validate([\n 'name' => 'required|string|min:2|max:100',\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $searchName = $request->input('name');\n\n if ($search !== null) {\n $search->update([\n 'name' => $searchName,\n ]);\n\n return $search;\n }\n\n $request->validate([\n 'filters' => ['required', 'array', new MultidimensionalArrayMaxCharRule(limit: 255)],\n 'nudges' => 'array|max:' . count(Nudge::MAP_CHANNEL),\n 'nudges.*.channel' => 'required|in:' . implode(',', Nudge::MAP_CHANNEL),\n 'nudges.*.frequency' => 'required|in:' . implode(',', Nudge::MAP_FREQUENCY),\n 'nudges.*.expiresAt' => [\n 'required',\n 'date',\n 'after:today',\n 'before_or_equal:' . now()->addYear()->format('Y-m-d'),\n ],\n ]);\n\n $searchCriteria = Criteria::createFromRequest(\n Collection::make($request->input('filters', []))->all(),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($searchCriteria, $user);\n $this->validateSearch($request, $filterSet, 'filters.');\n\n /** @var Search $search */\n $search = Search::create([\n 'name' => $searchName,\n 'uuid' => Uuid::uuid4()->toString(),\n 'user_id' => $user->getId(),\n ]);\n\n Collection::make($request->input('nudges', []))\n ->each(fn (array $attributes): Nudge => $this->nudgeFactory->createNudge($search, $attributes));\n\n $this->storeNamedSearchFilters(Collection::make($request->all()), $search, $filterSet, 'filters.');\n\n return $search;\n }\n\n private function resolveAccount(\n Team $team,\n Contact $contact,\n ServiceInterface $crmService,\n array $prospects,\n ): ?Account {\n $this->logger->info('Resolving account from contact');\n $account = $contact->getAccount();\n\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS)) {\n $this->logger->info('Team does not have feature to link activity to multiple prospects');\n\n return $account;\n }\n\n $this->logger->info('Resolving account from prospect data');\n $accountData = array_filter(\n $prospects,\n static fn (array $prospectData): bool => $prospectData['type'] === 'account'\n );\n\n if (! empty($accountData)) {\n $this->logger->info('Found account data in prospects');\n $accountData = reset($accountData);\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountData['id'])->first();\n\n if (! $account instanceof Account) {\n $this->logger->info('Account not found in database, syncing from CRM');\n $account = $crmService->syncAccount($accountData['id']);\n }\n }\n\n $this->logger->info('Resolved account', ['account' => $account->getId()]);\n\n return $account;\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.40957448,"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.41821808,"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.42918882,"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.43783244,"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.44647607,"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.4574468,"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.46841756,"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.4950133,"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.50598407,"top":0.09896249,"width":0.029587766,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"bounds":{"left":0.7084442,"top":0.09896249,"width":0.02825798,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"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":"40","depth":4,"bounds":{"left":0.67785907,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.69015956,"top":0.123703115,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"40","depth":4,"bounds":{"left":0.6994681,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"64","depth":4,"bounds":{"left":0.7117686,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.7237367,"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.73105055,"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 * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","depth":4,"on_screen":true,"value":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","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}]...
|
-7287184300264252456
|
-8385861013499833196
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use Carbon\Carbon;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\In;
use Illuminate\Validation\ValidationException;
use InvalidArgumentException;
use Jiminny\Component\ActivityAnalytics;
use Jiminny\Component\ActivitySearch;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Queue\Constants;
use Jiminny\Contracts\ES\Events\UpdateSingleEntity;
use Jiminny\Contracts\ES\UpdateTargetEnum;
use Jiminny\Contracts\Nudge\NudgeFactoryInterface;
use Jiminny\Contracts\Playlist\PlaylistTrackFactoryInterface;
use Jiminny\Contracts\Repositories\PlaylistActivityRepository;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Enums\TeamSetting;
use Jiminny\Events\Activities\AiAutomation\ActivityProspectAdded;
use Jiminny\Events\Activities\Coaching\Coached;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Controllers\CommentContextInterface;
use Jiminny\Http\Responses\Api\AbstractResponse;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\ActivityCommentTransformer;
use Jiminny\Http\Transformers\ActivityTopicTriggerTransformer;
use Jiminny\Http\Transformers\ActivityTransformer;
use Jiminny\Http\Transformers\AvailabilityNotificationTransformer;
use Jiminny\Http\Transformers\CoachingFeedbackTransformer;
use Jiminny\Http\Transformers\CoachingSectionsTransformer;
use Jiminny\Http\Transformers\SearchTransformer;
use Jiminny\Http\Transformers\StatsTransformer;
use Jiminny\Jobs\Crm\SaveActivity;
use Jiminny\Jobs\Crm\UpdateStage;
use Jiminny\Jobs\Telephony\StartRecording;
use Jiminny\Jobs\Telephony\StopRecording;
use Jiminny\Jobs\Telephony\ToggleRecording;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\CoachingFeedback;
use Jiminny\Models\CoachingSection;
use Jiminny\Models\CoachingSectionCriterion;
use Jiminny\Models\CoachingSectionFeedback;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\LanguageDialect;
use Jiminny\Models\Lead;
use Jiminny\Models\Nudge;
use Jiminny\Models\PlaybookCategory;
use Jiminny\Models\Playlist;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\Track;
use Jiminny\Models\User;
use Jiminny\Repositories\CoachingFeedbackRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Rules\CrmReference;
use Jiminny\Rules\MultidimensionalArrayMaxCharRule;
use Jiminny\Services\ActivityService;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Services\PlaybackService;
use Jiminny\Services\UserService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
use Ramsey\Uuid\Uuid;
use Sentry;
use Symfony\Component\HttpFoundation;
final class ActivityController extends Controller implements CommentContextInterface
{
// Number of minutes to look back on activities. i.e. a timeout on activity duration.
private const int LOOK_BACK = 180;
public function __construct(
private ProviderRegistry $providerRegistry,
private ActivityService $activityService,
Response $response,
private UserService $userService,
private ActivitySearch\Service\ActivitySearch $activitySearch,
private NudgeFactoryInterface $nudgeFactory,
private ActivityCommentService $activityCommentService,
private LoggerInterface $logger,
private readonly CoachingFeedbackRepository $coachingFeedbackRepository,
private readonly TeamRepository $teamRepository,
) {
parent::__construct($response);
}
public static function getCommentImplementation(): string
{
return Comment::class;
}
public function delete()
{
$this->request->validate([
'*' => 'uuid:activities',
]);
$deletedIds = [];
foreach ($this->request->all() as $activityId) {
$activity = Activity::idOrUuId($activityId);
try {
if ($this->authorize('delete', $activity)) {
$activity->delete();
$deletedIds[] = $activityId;
\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);
}
} catch (AuthorizationException $authorizationException) {
// They didn't have permission.
}
}
return $this->response->withArray($deletedIds);
}
public function update(Request $request, Activity $activity)
{
$this->authorize('updateMetadata', $activity);
$request->validate([
'title' => 'string|max:250',
'category_id' => 'uuid:playbook_categories',
'language' => [
new In(
LanguageDialect::query()
->with('language')
->cursor()
->map(static function (LanguageDialect $languageDialect): string {
return $languageDialect->getLanguageLocale();
})
->all()
),
],
]);
if ($request->has('title')) {
$activity->title = $request->input('title');
}
if ($request->has('category_id')) {
$category = PlaybookCategory::uuid($request->input('category_id'));
if ($category->playbook->team_id !== $request->user()->team_id) {
return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
if ($request->has('language')) {
if (! $activity->isInProgress()) {
return $this->response->withError(
'Activity language can only be set while the meeting is in progress.',
400
);
}
$activity->setLanguageCode($request->input('language'));
}
$activity->save();
return $this->response->withOk();
}
// XXX: This should be merged with the update method.
/**
* @param Activity $activity
*
* @throws AuthorizationException
* @throws SocialAccountTokenInvalidException
*
* @return mixed
*/
public function summarize(Activity $activity): mixed
{
$this->logger->info('[Log Activity] Summarizing activity ', [
'activityId' => $activity->getUuid(),
'payload' => $this->request->all(),
]);
$this->authorize('update', $activity);
$this->logger->info('[Log Activity] Validating summary');
// Validate the payload.
$this->validateSummary($activity);
// All objects must belong to this team.
/** @var User $user */
$user = $this->request->user();
$team = $user->getTeam();
$crmService = $this->providerRegistry->get($team->crm->provider);
try {
$crmUser = $user;
if ($user->isCrmRequired() === false) {
$crmUser = $team->owner;
}
$crmService->setUser($crmUser);
} catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());
}
$rawEntities = $this->request->input('entities');
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid(
$this->request->input('layout_id')
);
// Delay execution of CRM jobs to avoid locking issues.
$jobDelay = 0;
// If we have arrived from a notification, mark it as read.
$notificationId = $this->request->input('nId');
if ($notificationId) {
$notification = $user->unreadNotifications->where('id', $notificationId)->first();
if ($notification) {
$notification->markAsRead();
}
}
$title = $this->request->input('title');
$prospects = $this->request->input('prospects');
$opportunityId = $this->request->input('opportunity_id');
$stageId = $this->request->input('stage_id');
$categoryId = $this->request->input('category_id');
$summary = $this->request->input('summary');
$crmProviderId = $this->request->input('crm_id');
$isInternal = $this->request->input('is_internal') ?? false;
$lead = null;
$category = null;
$account = null;
$contact = null;
$opportunity = null;
$stage = null;
$callStage = null;
foreach ($prospects as $prospectData) {
$objectId = $prospectData['id'];
if ($objectId === null) {
continue;
}
$objectType = $prospectData['type'];
$this->logger->info('debug', ['prospect_data' => $prospectData]);
try {
if ($objectType === null) {
$this->logger->info('no object type');
if ($crmService instanceof SupportsObjectTypeParseInterface) {
$objectType = $crmService->parseObjectType($objectId);
}
}
switch ($objectType) {
case 'lead':
$this->logger->info('Processing lead');
/** @var Lead|null $lead */
$lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();
// Lead does not exist locally, import it.
if ($lead === null) {
$this->logger->info('Lead does not exist locally');
/** @var Lead $lead */
$lead = $crmService->syncLead($objectId);
}
$this->logger->info('Lead found', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
if ($stageId === null) {
$this->logger->info('Stage ID is null');
// If it was not provided, just assume it is the current stage.
$callStage = $lead->stage;
break;
}
$this->logger->info('Looking for stage');
// Determine if they have changed the stage.
/** @var Stage $stage */
$stage = $team->crm->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_LEAD)
->firstOrFail();
$this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);
if ($lead->stage_id && $lead->stage_id !== $stage->id) {
$this->logger->info('Stage has changed');
// Storage current stage on activity.
$callStage = $lead->stage;
// The stage has changed, update in remote CRM.
dispatch(new UpdateStage($activity, $lead, $callStage, $stage));
$this->logger->info(
sprintf(
'[%s] User changing lead stage from %s to %s',
$crmService->getDisplayName(),
$callStage->getName(),
$stage->getName()
),
[
'user' => $user->getUuid(),
'lead' => $lead->getUuid(),
]
);
} else {
$this->logger->info('Stage has not changed');
// Stage remains as current.
$callStage = $stage;
}
break;
case 'account':
$this->logger->info('Processing account');
// If the object is not a lead, it should be an account.
$account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();
// Account does not exist locally, import it.
if ($account === null) {
$this->logger->info('Account does not exist locally');
$account = $crmService->syncAccount($objectId);
}
$this->logger->info('Account found', ['accountId' => $account->id]);
break;
case 'contact':
$this->logger->info('processing contact');
$contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$this->logger->info('contact does not exist locally');
$contact = $crmService->syncContact($objectId);
}
$this->logger->info('resolving account');
$account = $this->resolveAccount($team, $contact, $crmService, $prospects);
break;
}
// If they have specified an opportunity, retrieve this with stage.
if ($opportunityId) {
$this->logger->info('opportunity id is set');
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if ($opportunity === null) {
$this->logger->info('opportunity does not exist locally');
$opportunity = $crmService->syncOpportunity($opportunityId);
}
if ($stageId === null) {
$this->logger->info('stage id is null');
// If it was not provided, just assume it is the current stage.
$callStage = $opportunity->stage ?? null;
} else {
$this->logger->info('looking for stage');
/** @var ?Stage $opportunityStage */
$opportunityStage = $team->crm
->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
// There is a chance we still cannot import this opportunity.
if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {
$this->logger->info('opportunity stage has changed');
// Storage current stage on activity.
$callStage = $opportunity->stage;
dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));
$this->logger->info(
sprintf(
'[%s] User changing opportunity stage from %s to %s',
$crmService->getDisplayName(),
$callStage->name,
$opportunityStage->name
),
[
'userId' => $user->id_string,
'opportunityId' => $opportunity->id_string,
]
);
} else {
$this->logger->info('opportunity stage has not changed');
// Stage remains as current.
$callStage = $opportunityStage;
}
}
}
if ($crmProviderId) {
// Cast $crmProviderId to string otherwise it won't use database index for some records
$linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();
// Check if this activity has already been assigned to a different activity.
if ($linkedActivity && $linkedActivity->id !== $activity->id) {
throw new InvalidArgumentException(
'Sorry, the linked task has already been logged under a different call. '
. 'Please choose another linked task.'
);
}
}
} catch (InvalidArgumentException $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($exception->getMessage());
} catch (Exception $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorInternalError(
'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'
);
}
}
if ($categoryId) {
$category = PlaybookCategory::uuid($categoryId);
if ($category->playbook->team_id !== $team->id) {
throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
$this->logger->info('Prospect data', [
'lead_id' => $lead?->getId(),
'account_id' => $account?->getId(),
'contact_id' => $contact?->getId(),
'opportunity_id' => $opportunity?->getId(),
'stage_id' => $stage?->getId(),
]);
if ($title) {
$activity->title = $title;
}
if ($summary) {
$activity->summary = $summary;
}
if ($crmProviderId) {
$activity->crm_provider_id = $crmProviderId;
}
if ($callStage) {
$this->logger->info('Setting stage id', ['stageId' => $callStage->id]);
$activity->stage_id = $callStage->id;
}
if ($lead) {
$this->logger->info('Setting lead id', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
// If we are changed from an account > lead, unset the account data.
$this->logger->info('Unsetting account id, opportunity id, contact id, value');
$activity->account_id = null;
$activity->opportunity_id = null;
$activity->contact_id = null;
$activity->value = null;
}
if ($account) {
$this->logger->info('Setting account id', ['accountId' => $account->id]);
$activity->account_id = $account->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('unsetting lead id');
$activity->lead_id = null;
// Unset the contact if switching different accounts. Will be set up below if still applicable.
if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {
$this->logger->info('Unsetting contact id');
$activity->contact_id = null;
}
}
if ($opportunity) {
$this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);
$this->logger->info('unsetting lead id');
$activity->opportunity_id = $opportunity->id;
$activity->value = $opportunity->value;
// If we are changed from an lead > account, unset the lead data.
$activity->lead_id = null;
}
if ($contact) {
$this->logger->info('setting contact id', ['contactId' => $contact->id]);
$activity->contact_id = $contact->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('Unsetting lead id');
$activity->lead_id = null;
}
$activity->is_internal = $isInternal;
$activity->save();
$activity->refresh();
$this->logger->notice('Activity saved', [
'activity_id' => $activity->getId(),
'lead_id' => $activity->lead_id,
'account_id' => $activity->account_id,
'contact_id' => $activity->contact_id,
'opportunity_id' => $activity->opportunity_id,
'stage_id' => $activity->stage_id,
'crm_provider_id' => $activity->getCrmProviderId(),
]);
// Store entities as field data on the activity.
$updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);
if ($activity->isLoggable()) {
// Follow-up Task or Event data.
$followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);
$this->logger->info('CRM LOG manual log triggered', [
'activityId' => $activity->getUuid(),
'followupData' => $followupData,
'userId' => $user->getUuid(),
]);
// Store data in the CRM.
// ++add check for crm_required
$job = new SaveActivity($activity, $followupData);
if ($updatedData) {
$job->delay(Carbon::now()->addMinutes($jobDelay));
}
dispatch($job);
// Manually dispatch log for Opportunity or Prospect added
if ($activity->hasOpportunity() || $activity->hasProspect()) {
event(new ActivityProspectAdded(
activity: $activity,
eventSource: 'manually-log-crm-data'
));
}
}
return $this->response->withOk();
}
/**
* Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.
*
* @param ServiceInterface $service
* @param Activity $activity
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array
{
$updatedData = [];
$existingData = $activity->data()->get();
// We need to delete any existing data to overwrite with latest values.
$activity->data()->delete();
$layoutEntities = $layout->entities()
->with('field', 'parent')
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->get();
/** @var LayoutEntity $entity */
foreach ($layoutEntities as $entity) {
// If the user has provided a value for this entity
if (array_key_exists($entity->id_string, $entities)) {
$value = $entities[$entity->id_string];
// Convert raw data into values that the CRM can consume.
if ($value) {
$value = $service->normalizeValue($entity->field->type, $value);
}
// Check the field is part of the activity-summary section.
if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {
// This is the internal database ID, not the external CRM ID.
$objectId = null;
switch ($entity->field->object_type) {
case Field::OBJECT_ACCOUNT:
$objectId = $activity->account_id;
break;
case Field::OBJECT_CONTACT:
$objectId = $activity->contact_id;
break;
case Field::OBJECT_OPPORTUNITY:
$objectId = $activity->opportunity_id;
break;
case Field::OBJECT_LEAD:
$objectId = $activity->lead_id;
break;
case Field::OBJECT_TASK:
case Field::OBJECT_EVENT:
$objectId = $activity->id;
break;
}
if ($objectId) {
/** @var FieldData $data */
$data = $activity->data()->create([
'crm_layout_entity_id' => $entity->id,
'crm_field_id' => $entity->crm_field_id,
'object_type' => $entity->field->object_type,
'object_id' => $objectId,
'value' => $value,
]);
// Never send read-only field data to the CRM.
if ($entity->read_only === false && $entity->is_visible) {
$existingValue = $existingData
->where('crm_layout_entity_id', $entity->id)
->where('crm_field_id', $entity->crm_field_id)
->where('object_type', $entity->field->object_type)
->where('object_id', $objectId)
->first();
// If the field was actually changed, we need to reflect this in the CRM too.
if ($existingValue === null || $existingValue->value !== $value) {
$updatedData[] = $data->id;
}
}
}
}
}
}
return $updatedData;
}
/**
* Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.
*
* @param ServiceInterface $crmService
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array
{
$fieldData = [];
foreach ($entities as $entityId => $value) {
// Only bother with fields that have a value.
if ($value) {
// Extract the entity from the UUID. Check the field is valid and part of the follow-up section.
$entity = $layout->entities()
->uuid($entityId, false)
->whereHas('parent', function ($query) {
$query->where('label', 'follow-up');
})
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->first();
if ($entity) {
// Convert raw data into values that the CRM can consume.
$value = $crmService->normalizeValue($entity->field->type, $value);
// Add the field and value to the payload.
$fieldData += [
$entity->field->crm_provider_id => $value,
];
}
}
}
return $fieldData;
}
/**
* @param Activity $activity
*/
private function validateSummary(Activity $activity): void
{
$team = $activity->user->team;
$crmProvider = $team->crm->provider;
$attributes = [];
$rules = [
'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,
'title' => 'string|max:250',
'prospects' => 'required|array',
'opportunity_id' => new CrmReference($crmProvider),
'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',
'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator
'summary' => 'max:50000',
'nId' => 'exists:notifications,id',
'crm_id' => new CrmReference($crmProvider),
'entities' => 'array',
'is_internal' => 'boolean',
];
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));
// Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.
$entities = $layout->entities()
->where('read_only', 0)
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->whereHas('parent', function ($query) use ($activity) {
if ($activity->isLoggable() === false) {
$query->where('label', '<>', 'follow-up');
}
});
$isInternal = $this->request->input('is_internal', false);
foreach ($entities->get() as $entity) {
$rules += $this->buildFieldValidator($entity, $isInternal);
$attributes += $this->buildFieldMessage($entity);
}
$this->request->validate($rules, [], $attributes);
}
private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array
{
return [
'entities.' . $entity->id_string => $entity->getValidator($isInternal),
];
}
/**
* @param LayoutEntity $entity
*
* @return array
*/
private function buildFieldMessage(LayoutEntity $entity): array
{
$label = $entity->label;
if ($label === null) {
$label = $entity->field->label;
}
return [
'entities.' . $entity->id_string => $label,
];
}
public function search(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->debugLog(
$user,
'User extracted from request',
['user' => $user->getId(), 'tz' => $user->getTimezone()]
);
$searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());
$this->debugLog(
$user,
'ActivitySearch criteria built',
['searchCriteria' => $searchCriteria]
);
$filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);
$this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);
$this->validateSearch($request, $filterSet);
$this->debugLog($user, 'Request validated');
$searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);
/** @var Collection<Activity> $activities */
$activities = $searchResponse['results'];
$this->debugLog($user, 'Activities ES response extracted');
$hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(
$user->getTeamId(),
TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),
);
if ($hideInternalMeetingsSetting?->getValue() === '1') {
$activities = $activities->filter(function (Activity $activity) {
if ($activity->is_internal && empty($activity->actual_start_time)) {
return false;
}
return true;
});
}
$this->debugLog($user, 'Internal meetings (?!) filtered');
$this->response->getManager()
->parseIncludes([
'category',
'organizer.group',
'prospect',
'stage',
'opportunity',
'stats',
'scorecards',
'masterTrack',
'activeParticipants',
'notification',
])
->setSerializer(new JsonSerializer());
$transformerExcludes = $this->request->input('exclude');
if ($transformerExcludes) {
$this->response->getManager()->parseExcludes($transformerExcludes);
}
$this->debugLog($user, 'Response Manager (?!) applied');
$transformer = new ActivityTransformer();
$transformer->setConsumer($user);
$this->debugLog($user, 'Activity Transformer added');
$resource = new \League\Fractal\Resource\Collection($activities, $transformer);
$page = $searchCriteria->getPageNumber();
$this->debugLog($user, 'Search criteria page number called', ['page' => $page]);
$histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');
$this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);
return $this->response->withArray([
'pagination' => [
'total' => $searchResponse['totalHits'],
'current' => $page,
'prev' => max($page - 1, 1),
'next' => $page + 1,
],
'results' => $this->response->getManager()->createData($resource)->toArray(),
'histogram' => $histogram,
]);
}
private function debugLog(User $user, string $logMessage, ?array $context = []): void
{
// Debug for Learning People Only
if ($user->getTeamId() !== 260) {
return;
}
Log::notice(
sprintf('[activity-search-controller] %s', $logMessage),
$context
);
}
/** @throws ValidationException */
private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void
{
$rules = [
'exclude' => 'array',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
];
if ($prefix !== null && mb_strpos($prefix, '.') !== false) {
$rules[rtrim($prefix, '.')] = sprintf(
'required|array|max:%d',
$filterSet->count()
);
}
$validationRules = $filterSet->getValidationRules($prefix)
->merge($rules)
->all();
$request->validate($validationRules);
}
public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$search = $this->updateOrCreateActivitySearch($request);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function updateActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('update', $search);
$this->updateOrCreateActivitySearch($request, $search);
return $this->response->withOk();
}
private function storeNamedSearchFilters(
Collection $request,
Search $search,
FilterDefinitionCollection $filterSet,
?string $prefix = null,
): self {
$arrayTypeProperties = $filterSet
->getPropertyTypes([
FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,
])
->all();
$supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);
foreach ($supportedRequestProperties as $requestPropertyName) {
if (! array_has($request, $requestPropertyName)) {
continue;
}
/** @var string|string[] $propertyValue */
$propertyValue = array_get($request, $requestPropertyName);
$propertyName = $prefix === null
? $requestPropertyName
: mb_substr($requestPropertyName, mb_strlen($prefix));
$isArrayType = array_has($arrayTypeProperties, $propertyName);
if (! $isArrayType) {
/** @var string $requestPropertyValue */
$search->filters()->updateOrCreate(
[
'filter' => $propertyName,
],
[
'value' => $propertyValue,
]
);
continue;
}
/** @var string[] $requestPropertyValue */
/** @var SearchFilter[]|Collection $existingFilterValues */
$existingFilterValuesKeyed = $search->filters()
->where('filter', $propertyName)
->get()
->keyBy('id');
// Iterate over values provided as request parameters
foreach ($propertyValue as $value) {
/** @var SearchFilter|null $valueFilter */
$valueFilter = $search->filters()
->where(
[
'filter' => $propertyName,
'value' => $value,
]
)
->first();
if ($valueFilter !== null) {
// Remove filter value pair from list to be deleted
$existingFilterValuesKeyed->forget($valueFilter->id);
} else {
// Add new filter/value pair
$search->filters()->updateOrCreate([
'filter' => $propertyName,
'value' => $value,
]);
}
}
// Delete filter value pairs for this filter that no longer exist in request parameters
foreach ($existingFilterValuesKeyed as $existingFilter) {
$existingFilter->delete();
}
}
/** @var Collection<int, SearchFilter> $filtersKeyed */
$filtersKeyed = $search->filters()->get()->keyBy('filter');
// wipe removed filters from this search
foreach ($filtersKeyed as $filterName => $filter) {
if (array_has($request, $prefix . $filterName)) {
continue;
}
// Remove all filter values for this filter
$search->filters()->where('filter', $filterName)->delete();
}
return $this;
}
/**
* @throws AuthorizationException
*/
public function fetchActivitySearch(
Search $search,
Request $request,
SearchTransformer $searchTransformer,
): JsonResponse {
$this->authorize('view', $search);
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withCollection(
$user->searches()->get(),
$searchTransformer
->withConsumer($user)
);
}
/**
* Deletes a saved search
*
* @param Request $request
* @param Search $search
*
* @throws Exception
*
* @return JsonResponse
*/
public function deleteActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('delete', $search);
// Orphan any AutomatedReports that use this search
$search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);
// Delete filters and the search itself
$search->filters()->delete();
$search->delete();
return $this->response->withOk();
}
public function live(Request $request, ElasticActivityRepository $repository): JsonResponse
{
$user = $this->getUserFromRequest($request);
$this->request->validate([
'sort_direction' => 'in:asc,desc',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
]);
$activities = $repository->getLiveCoachingEligibleActivities(
user: $user,
lookBackMinutes: self::LOOK_BACK,
limit: (int) $this->request->input('limit', 25),
page: (int) $this->request->input('page', 1),
sortBy: ['actual_start_time', 'scheduled_start_time'],
sortDirection: (string) $this->request->input('sort_direction', 'asc'),
);
$this->response
->getManager()
->parseIncludes(['organizer.group', 'prospect'])
->setSerializer(new JsonSerializer());
return $this->response->withCollection($activities, new ActivityTransformer());
}
/**
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function show(Activity $activity, ActivityService $activityService): JsonResponse
{
$this->authorize('show', $activity);
$user = $activity->getUser();
$team = $user->getTeam();
// Sync the opportunity with the latest data if possible.
if ($activity->opportunity_id) {
try {
$crmService = $this->providerRegistry->get($team->crm->provider);
if (! $user->isCrmRequired()) {
$crmService->setUser($team->getOwner());
} else {
$crmService->setUser($user);
}
$crmService->syncOpportunity($activity->opportunity->crm_provider_id);
} catch (Exception $exception) {
// Move on.
}
}
$activityData = $activityService->getActivityData($this->request->user(), $activity);
return response()->json($activityData);
}
public function createRecording(Activity $activity)
{
$this->authorize('record', $activity);
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Tell Twilio to start recording this activity.
if ($activity->recording_state === Activity::RECORDING_OFF) {
$job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withCreated();
}
return $this->response->errorGone('Activity is already recording.');
}
public function updateRecording(Request $request, Activity $activity)
{
$this->authorize('record', $activity);
$request->validate([
'preference' => 'boolean',
'state' => [
'string',
Rule::in([
Activity::RECORDING_IN_PROGRESS,
Activity::RECORDING_PAUSED,
]),
],
]);
if ($request->has('state')) {
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Toggle the recording state between paused and resumed.
if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {
$job = (new ToggleRecording($activity, $request->input('state')))
->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Recording is not toggleable.');
}
if ($request->has('preference')) {
$activity->update([
'recording_preference' => $request->input('preference') ? 1 : 0,
]);
return $this->response->withOk();
}
return $this->response->errorWrongArgs('Something went wrong');
}
public function stopRecording(Activity $activity)
{
$this->authorize('stopRecord', $activity);
// Tell Twilio to stop recording this activity.
if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {
$job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Activity is not recording.');
}
/**
* Add activity to this user's favorites playlist
*
* @throws AuthorizationException
*/
public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse
{
$this->authorize('favorite', $activity);
$user = $this->getUserFromRequest($this->request);
$favorite = $activity->wasFavoritedBy($user);
$name = $activity->activity_title ?? '';
// It needs to check at least one record.
if (! $favorite) {
$favoritePlaylist = $user->favoritePlaylist();
$playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(
$activity,
$user,
$favoritePlaylist
);
if ($playlistActivity !== null) {
$playlistActivity->update(
// Just update, don't sort.
['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],
);
} else {
$playlistActivity = $activity->playlistActivities()->create([
'playlist_id' => $favoritePlaylist->getId(),
'user_id' => $user->getId(),
'start_time' => 0,
'name' => mb_strimwidth($name, 0, 100),
]);
// Sort it on top.
$playlistActivity->update(
[
'sort' => $playlistActivityRepository->calculateNewSortOrder(
null,
$playlistActivity,
),
],
);
}
$playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);
return new JsonResponse([], JsonResponse::HTTP_CREATED);
}
return new JsonResponse(
[
'error' => [
'code' => AbstractResponse::CODE_CONFLICT,
'http_code' => JsonResponse::HTTP_CONFLICT,
'message' => 'Resource Already Exists',
],
],
JsonResponse::HTTP_CONFLICT,
);
}
/**
* Remove activity from this user's favorites playlist
*
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function unfavorite(Activity $activity)
{
$user = $t...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
32861
|
1254
|
29
|
2026-05-13T09:41:10.505726+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665270505_m1.jpg...
|
PhpStorm
|
faVsco.js – ActivityController.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use Carbon\Carbon;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\In;
use Illuminate\Validation\ValidationException;
use InvalidArgumentException;
use Jiminny\Component\ActivityAnalytics;
use Jiminny\Component\ActivitySearch;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Queue\Constants;
use Jiminny\Contracts\ES\Events\UpdateSingleEntity;
use Jiminny\Contracts\ES\UpdateTargetEnum;
use Jiminny\Contracts\Nudge\NudgeFactoryInterface;
use Jiminny\Contracts\Playlist\PlaylistTrackFactoryInterface;
use Jiminny\Contracts\Repositories\PlaylistActivityRepository;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Enums\TeamSetting;
use Jiminny\Events\Activities\AiAutomation\ActivityProspectAdded;
use Jiminny\Events\Activities\Coaching\Coached;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Controllers\CommentContextInterface;
use Jiminny\Http\Responses\Api\AbstractResponse;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\ActivityCommentTransformer;
use Jiminny\Http\Transformers\ActivityTopicTriggerTransformer;
use Jiminny\Http\Transformers\ActivityTransformer;
use Jiminny\Http\Transformers\AvailabilityNotificationTransformer;
use Jiminny\Http\Transformers\CoachingFeedbackTransformer;
use Jiminny\Http\Transformers\CoachingSectionsTransformer;
use Jiminny\Http\Transformers\SearchTransformer;
use Jiminny\Http\Transformers\StatsTransformer;
use Jiminny\Jobs\Crm\SaveActivity;
use Jiminny\Jobs\Crm\UpdateStage;
use Jiminny\Jobs\Telephony\StartRecording;
use Jiminny\Jobs\Telephony\StopRecording;
use Jiminny\Jobs\Telephony\ToggleRecording;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\CoachingFeedback;
use Jiminny\Models\CoachingSection;
use Jiminny\Models\CoachingSectionCriterion;
use Jiminny\Models\CoachingSectionFeedback;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\LanguageDialect;
use Jiminny\Models\Lead;
use Jiminny\Models\Nudge;
use Jiminny\Models\PlaybookCategory;
use Jiminny\Models\Playlist;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\Track;
use Jiminny\Models\User;
use Jiminny\Repositories\CoachingFeedbackRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Rules\CrmReference;
use Jiminny\Rules\MultidimensionalArrayMaxCharRule;
use Jiminny\Services\ActivityService;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Services\PlaybackService;
use Jiminny\Services\UserService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
use Ramsey\Uuid\Uuid;
use Sentry;
use Symfony\Component\HttpFoundation;
final class ActivityController extends Controller implements CommentContextInterface
{
// Number of minutes to look back on activities. i.e. a timeout on activity duration.
private const int LOOK_BACK = 180;
public function __construct(
private ProviderRegistry $providerRegistry,
private ActivityService $activityService,
Response $response,
private UserService $userService,
private ActivitySearch\Service\ActivitySearch $activitySearch,
private NudgeFactoryInterface $nudgeFactory,
private ActivityCommentService $activityCommentService,
private LoggerInterface $logger,
private readonly CoachingFeedbackRepository $coachingFeedbackRepository,
private readonly TeamRepository $teamRepository,
) {
parent::__construct($response);
}
public static function getCommentImplementation(): string
{
return Comment::class;
}
public function delete()
{
$this->request->validate([
'*' => 'uuid:activities',
]);
$deletedIds = [];
foreach ($this->request->all() as $activityId) {
$activity = Activity::idOrUuId($activityId);
try {
if ($this->authorize('delete', $activity)) {
$activity->delete();
$deletedIds[] = $activityId;
\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);
}
} catch (AuthorizationException $authorizationException) {
// They didn't have permission.
}
}
return $this->response->withArray($deletedIds);
}
public function update(Request $request, Activity $activity)
{
$this->authorize('updateMetadata', $activity);
$request->validate([
'title' => 'string|max:250',
'category_id' => 'uuid:playbook_categories',
'language' => [
new In(
LanguageDialect::query()
->with('language')
->cursor()
->map(static function (LanguageDialect $languageDialect): string {
return $languageDialect->getLanguageLocale();
})
->all()
),
],
]);
if ($request->has('title')) {
$activity->title = $request->input('title');
}
if ($request->has('category_id')) {
$category = PlaybookCategory::uuid($request->input('category_id'));
if ($category->playbook->team_id !== $request->user()->team_id) {
return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
if ($request->has('language')) {
if (! $activity->isInProgress()) {
return $this->response->withError(
'Activity language can only be set while the meeting is in progress.',
400
);
}
$activity->setLanguageCode($request->input('language'));
}
$activity->save();
return $this->response->withOk();
}
// XXX: This should be merged with the update method.
/**
* @param Activity $activity
*
* @throws AuthorizationException
* @throws SocialAccountTokenInvalidException
*
* @return mixed
*/
public function summarize(Activity $activity): mixed
{
$this->logger->info('[Log Activity] Summarizing activity ', [
'activityId' => $activity->getUuid(),
'payload' => $this->request->all(),
]);
$this->authorize('update', $activity);
$this->logger->info('[Log Activity] Validating summary');
// Validate the payload.
$this->validateSummary($activity);
// All objects must belong to this team.
/** @var User $user */
$user = $this->request->user();
$team = $user->getTeam();
$crmService = $this->providerRegistry->get($team->crm->provider);
try {
$crmUser = $user;
if ($user->isCrmRequired() === false) {
$crmUser = $team->owner;
}
$crmService->setUser($crmUser);
} catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());
}
$rawEntities = $this->request->input('entities');
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid(
$this->request->input('layout_id')
);
// Delay execution of CRM jobs to avoid locking issues.
$jobDelay = 0;
// If we have arrived from a notification, mark it as read.
$notificationId = $this->request->input('nId');
if ($notificationId) {
$notification = $user->unreadNotifications->where('id', $notificationId)->first();
if ($notification) {
$notification->markAsRead();
}
}
$title = $this->request->input('title');
$prospects = $this->request->input('prospects');
$opportunityId = $this->request->input('opportunity_id');
$stageId = $this->request->input('stage_id');
$categoryId = $this->request->input('category_id');
$summary = $this->request->input('summary');
$crmProviderId = $this->request->input('crm_id');
$isInternal = $this->request->input('is_internal') ?? false;
$lead = null;
$category = null;
$account = null;
$contact = null;
$opportunity = null;
$stage = null;
$callStage = null;
foreach ($prospects as $prospectData) {
$objectId = $prospectData['id'];
if ($objectId === null) {
continue;
}
$objectType = $prospectData['type'];
$this->logger->info('debug', ['prospect_data' => $prospectData]);
try {
if ($objectType === null) {
$this->logger->info('no object type');
if ($crmService instanceof SupportsObjectTypeParseInterface) {
$objectType = $crmService->parseObjectType($objectId);
}
}
switch ($objectType) {
case 'lead':
$this->logger->info('Processing lead');
/** @var Lead|null $lead */
$lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();
// Lead does not exist locally, import it.
if ($lead === null) {
$this->logger->info('Lead does not exist locally');
/** @var Lead $lead */
$lead = $crmService->syncLead($objectId);
}
$this->logger->info('Lead found', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
if ($stageId === null) {
$this->logger->info('Stage ID is null');
// If it was not provided, just assume it is the current stage.
$callStage = $lead->stage;
break;
}
$this->logger->info('Looking for stage');
// Determine if they have changed the stage.
/** @var Stage $stage */
$stage = $team->crm->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_LEAD)
->firstOrFail();
$this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);
if ($lead->stage_id && $lead->stage_id !== $stage->id) {
$this->logger->info('Stage has changed');
// Storage current stage on activity.
$callStage = $lead->stage;
// The stage has changed, update in remote CRM.
dispatch(new UpdateStage($activity, $lead, $callStage, $stage));
$this->logger->info(
sprintf(
'[%s] User changing lead stage from %s to %s',
$crmService->getDisplayName(),
$callStage->getName(),
$stage->getName()
),
[
'user' => $user->getUuid(),
'lead' => $lead->getUuid(),
]
);
} else {
$this->logger->info('Stage has not changed');
// Stage remains as current.
$callStage = $stage;
}
break;
case 'account':
$this->logger->info('Processing account');
// If the object is not a lead, it should be an account.
$account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();
// Account does not exist locally, import it.
if ($account === null) {
$this->logger->info('Account does not exist locally');
$account = $crmService->syncAccount($objectId);
}
$this->logger->info('Account found', ['accountId' => $account->id]);
break;
case 'contact':
$this->logger->info('processing contact');
$contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$this->logger->info('contact does not exist locally');
$contact = $crmService->syncContact($objectId);
}
$this->logger->info('resolving account');
$account = $this->resolveAccount($team, $contact, $crmService, $prospects);
break;
}
// If they have specified an opportunity, retrieve this with stage.
if ($opportunityId) {
$this->logger->info('opportunity id is set');
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if ($opportunity === null) {
$this->logger->info('opportunity does not exist locally');
$opportunity = $crmService->syncOpportunity($opportunityId);
}
if ($stageId === null) {
$this->logger->info('stage id is null');
// If it was not provided, just assume it is the current stage.
$callStage = $opportunity->stage ?? null;
} else {
$this->logger->info('looking for stage');
/** @var ?Stage $opportunityStage */
$opportunityStage = $team->crm
->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
// There is a chance we still cannot import this opportunity.
if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {
$this->logger->info('opportunity stage has changed');
// Storage current stage on activity.
$callStage = $opportunity->stage;
dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));
$this->logger->info(
sprintf(
'[%s] User changing opportunity stage from %s to %s',
$crmService->getDisplayName(),
$callStage->name,
$opportunityStage->name
),
[
'userId' => $user->id_string,
'opportunityId' => $opportunity->id_string,
]
);
} else {
$this->logger->info('opportunity stage has not changed');
// Stage remains as current.
$callStage = $opportunityStage;
}
}
}
if ($crmProviderId) {
// Cast $crmProviderId to string otherwise it won't use database index for some records
$linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();
// Check if this activity has already been assigned to a different activity.
if ($linkedActivity && $linkedActivity->id !== $activity->id) {
throw new InvalidArgumentException(
'Sorry, the linked task has already been logged under a different call. '
. 'Please choose another linked task.'
);
}
}
} catch (InvalidArgumentException $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($exception->getMessage());
} catch (Exception $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorInternalError(
'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'
);
}
}
if ($categoryId) {
$category = PlaybookCategory::uuid($categoryId);
if ($category->playbook->team_id !== $team->id) {
throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
$this->logger->info('Prospect data', [
'lead_id' => $lead?->getId(),
'account_id' => $account?->getId(),
'contact_id' => $contact?->getId(),
'opportunity_id' => $opportunity?->getId(),
'stage_id' => $stage?->getId(),
]);
if ($title) {
$activity->title = $title;
}
if ($summary) {
$activity->summary = $summary;
}
if ($crmProviderId) {
$activity->crm_provider_id = $crmProviderId;
}
if ($callStage) {
$this->logger->info('Setting stage id', ['stageId' => $callStage->id]);
$activity->stage_id = $callStage->id;
}
if ($lead) {
$this->logger->info('Setting lead id', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
// If we are changed from an account > lead, unset the account data.
$this->logger->info('Unsetting account id, opportunity id, contact id, value');
$activity->account_id = null;
$activity->opportunity_id = null;
$activity->contact_id = null;
$activity->value = null;
}
if ($account) {
$this->logger->info('Setting account id', ['accountId' => $account->id]);
$activity->account_id = $account->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('unsetting lead id');
$activity->lead_id = null;
// Unset the contact if switching different accounts. Will be set up below if still applicable.
if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {
$this->logger->info('Unsetting contact id');
$activity->contact_id = null;
}
}
if ($opportunity) {
$this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);
$this->logger->info('unsetting lead id');
$activity->opportunity_id = $opportunity->id;
$activity->value = $opportunity->value;
// If we are changed from an lead > account, unset the lead data.
$activity->lead_id = null;
}
if ($contact) {
$this->logger->info('setting contact id', ['contactId' => $contact->id]);
$activity->contact_id = $contact->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('Unsetting lead id');
$activity->lead_id = null;
}
$activity->is_internal = $isInternal;
$activity->save();
$activity->refresh();
$this->logger->notice('Activity saved', [
'activity_id' => $activity->getId(),
'lead_id' => $activity->lead_id,
'account_id' => $activity->account_id,
'contact_id' => $activity->contact_id,
'opportunity_id' => $activity->opportunity_id,
'stage_id' => $activity->stage_id,
'crm_provider_id' => $activity->getCrmProviderId(),
]);
// Store entities as field data on the activity.
$updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);
if ($activity->isLoggable()) {
// Follow-up Task or Event data.
$followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);
$this->logger->info('CRM LOG manual log triggered', [
'activityId' => $activity->getUuid(),
'followupData' => $followupData,
'userId' => $user->getUuid(),
]);
// Store data in the CRM.
// ++add check for crm_required
$job = new SaveActivity($activity, $followupData);
if ($updatedData) {
$job->delay(Carbon::now()->addMinutes($jobDelay));
}
dispatch($job);
// Manually dispatch log for Opportunity or Prospect added
if ($activity->hasOpportunity() || $activity->hasProspect()) {
event(new ActivityProspectAdded(
activity: $activity,
eventSource: 'manually-log-crm-data'
));
}
}
return $this->response->withOk();
}
/**
* Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.
*
* @param ServiceInterface $service
* @param Activity $activity
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array
{
$updatedData = [];
$existingData = $activity->data()->get();
// We need to delete any existing data to overwrite with latest values.
$activity->data()->delete();
$layoutEntities = $layout->entities()
->with('field', 'parent')
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->get();
/** @var LayoutEntity $entity */
foreach ($layoutEntities as $entity) {
// If the user has provided a value for this entity
if (array_key_exists($entity->id_string, $entities)) {
$value = $entities[$entity->id_string];
// Convert raw data into values that the CRM can consume.
if ($value) {
$value = $service->normalizeValue($entity->field->type, $value);
}
// Check the field is part of the activity-summary section.
if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {
// This is the internal database ID, not the external CRM ID.
$objectId = null;
switch ($entity->field->object_type) {
case Field::OBJECT_ACCOUNT:
$objectId = $activity->account_id;
break;
case Field::OBJECT_CONTACT:
$objectId = $activity->contact_id;
break;
case Field::OBJECT_OPPORTUNITY:
$objectId = $activity->opportunity_id;
break;
case Field::OBJECT_LEAD:
$objectId = $activity->lead_id;
break;
case Field::OBJECT_TASK:
case Field::OBJECT_EVENT:
$objectId = $activity->id;
break;
}
if ($objectId) {
/** @var FieldData $data */
$data = $activity->data()->create([
'crm_layout_entity_id' => $entity->id,
'crm_field_id' => $entity->crm_field_id,
'object_type' => $entity->field->object_type,
'object_id' => $objectId,
'value' => $value,
]);
// Never send read-only field data to the CRM.
if ($entity->read_only === false && $entity->is_visible) {
$existingValue = $existingData
->where('crm_layout_entity_id', $entity->id)
->where('crm_field_id', $entity->crm_field_id)
->where('object_type', $entity->field->object_type)
->where('object_id', $objectId)
->first();
// If the field was actually changed, we need to reflect this in the CRM too.
if ($existingValue === null || $existingValue->value !== $value) {
$updatedData[] = $data->id;
}
}
}
}
}
}
return $updatedData;
}
/**
* Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.
*
* @param ServiceInterface $crmService
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array
{
$fieldData = [];
foreach ($entities as $entityId => $value) {
// Only bother with fields that have a value.
if ($value) {
// Extract the entity from the UUID. Check the field is valid and part of the follow-up section.
$entity = $layout->entities()
->uuid($entityId, false)
->whereHas('parent', function ($query) {
$query->where('label', 'follow-up');
})
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->first();
if ($entity) {
// Convert raw data into values that the CRM can consume.
$value = $crmService->normalizeValue($entity->field->type, $value);
// Add the field and value to the payload.
$fieldData += [
$entity->field->crm_provider_id => $value,
];
}
}
}
return $fieldData;
}
/**
* @param Activity $activity
*/
private function validateSummary(Activity $activity): void
{
$team = $activity->user->team;
$crmProvider = $team->crm->provider;
$attributes = [];
$rules = [
'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,
'title' => 'string|max:250',
'prospects' => 'required|array',
'opportunity_id' => new CrmReference($crmProvider),
'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',
'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator
'summary' => 'max:50000',
'nId' => 'exists:notifications,id',
'crm_id' => new CrmReference($crmProvider),
'entities' => 'array',
'is_internal' => 'boolean',
];
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));
// Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.
$entities = $layout->entities()
->where('read_only', 0)
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->whereHas('parent', function ($query) use ($activity) {
if ($activity->isLoggable() === false) {
$query->where('label', '<>', 'follow-up');
}
});
$isInternal = $this->request->input('is_internal', false);
foreach ($entities->get() as $entity) {
$rules += $this->buildFieldValidator($entity, $isInternal);
$attributes += $this->buildFieldMessage($entity);
}
$this->request->validate($rules, [], $attributes);
}
private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array
{
return [
'entities.' . $entity->id_string => $entity->getValidator($isInternal),
];
}
/**
* @param LayoutEntity $entity
*
* @return array
*/
private function buildFieldMessage(LayoutEntity $entity): array
{
$label = $entity->label;
if ($label === null) {
$label = $entity->field->label;
}
return [
'entities.' . $entity->id_string => $label,
];
}
public function search(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->debugLog(
$user,
'User extracted from request',
['user' => $user->getId(), 'tz' => $user->getTimezone()]
);
$searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());
$this->debugLog(
$user,
'ActivitySearch criteria built',
['searchCriteria' => $searchCriteria]
);
$filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);
$this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);
$this->validateSearch($request, $filterSet);
$this->debugLog($user, 'Request validated');
$searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);
/** @var Collection<Activity> $activities */
$activities = $searchResponse['results'];
$this->debugLog($user, 'Activities ES response extracted');
$hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(
$user->getTeamId(),
TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),
);
if ($hideInternalMeetingsSetting?->getValue() === '1') {
$activities = $activities->filter(function (Activity $activity) {
if ($activity->is_internal && empty($activity->actual_start_time)) {
return false;
}
return true;
});
}
$this->debugLog($user, 'Internal meetings (?!) filtered');
$this->response->getManager()
->parseIncludes([
'category',
'organizer.group',
'prospect',
'stage',
'opportunity',
'stats',
'scorecards',
'masterTrack',
'activeParticipants',
'notification',
])
->setSerializer(new JsonSerializer());
$transformerExcludes = $this->request->input('exclude');
if ($transformerExcludes) {
$this->response->getManager()->parseExcludes($transformerExcludes);
}
$this->debugLog($user, 'Response Manager (?!) applied');
$transformer = new ActivityTransformer();
$transformer->setConsumer($user);
$this->debugLog($user, 'Activity Transformer added');
$resource = new \League\Fractal\Resource\Collection($activities, $transformer);
$page = $searchCriteria->getPageNumber();
$this->debugLog($user, 'Search criteria page number called', ['page' => $page]);
$histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');
$this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);
return $this->response->withArray([
'pagination' => [
'total' => $searchResponse['totalHits'],
'current' => $page,
'prev' => max($page - 1, 1),
'next' => $page + 1,
],
'results' => $this->response->getManager()->createData($resource)->toArray(),
'histogram' => $histogram,
]);
}
private function debugLog(User $user, string $logMessage, ?array $context = []): void
{
// Debug for Learning People Only
if ($user->getTeamId() !== 260) {
return;
}
Log::notice(
sprintf('[activity-search-controller] %s', $logMessage),
$context
);
}
/** @throws ValidationException */
private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void
{
$rules = [
'exclude' => 'array',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
];
if ($prefix !== null && mb_strpos($prefix, '.') !== false) {
$rules[rtrim($prefix, '.')] = sprintf(
'required|array|max:%d',
$filterSet->count()
);
}
$validationRules = $filterSet->getValidationRules($prefix)
->merge($rules)
->all();
$request->validate($validationRules);
}
public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$search = $this->updateOrCreateActivitySearch($request);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function updateActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('update', $search);
$this->updateOrCreateActivitySearch($request, $search);
return $this->response->withOk();
}
private function storeNamedSearchFilters(
Collection $request,
Search $search,
FilterDefinitionCollection $filterSet,
?string $prefix = null,
): self {
$arrayTypeProperties = $filterSet
->getPropertyTypes([
FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,
])
->all();
$supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);
foreach ($supportedRequestProperties as $requestPropertyName) {
if (! array_has($request, $requestPropertyName)) {
continue;
}
/** @var string|string[] $propertyValue */
$propertyValue = array_get($request, $requestPropertyName);
$propertyName = $prefix === null
? $requestPropertyName
: mb_substr($requestPropertyName, mb_strlen($prefix));
$isArrayType = array_has($arrayTypeProperties, $propertyName);
if (! $isArrayType) {
/** @var string $requestPropertyValue */
$search->filters()->updateOrCreate(
[
'filter' => $propertyName,
],
[
'value' => $propertyValue,
]
);
continue;
}
/** @var string[] $requestPropertyValue */
/** @var SearchFilter[]|Collection $existingFilterValues */
$existingFilterValuesKeyed = $search->filters()
->where('filter', $propertyName)
->get()
->keyBy('id');
// Iterate over values provided as request parameters
foreach ($propertyValue as $value) {
/** @var SearchFilter|null $valueFilter */
$valueFilter = $search->filters()
->where(
[
'filter' => $propertyName,
'value' => $value,
]
)
->first();
if ($valueFilter !== null) {
// Remove filter value pair from list to be deleted
$existingFilterValuesKeyed->forget($valueFilter->id);
} else {
// Add new filter/value pair
$search->filters()->updateOrCreate([
'filter' => $propertyName,
'value' => $value,
]);
}
}
// Delete filter value pairs for this filter that no longer exist in request parameters
foreach ($existingFilterValuesKeyed as $existingFilter) {
$existingFilter->delete();
}
}
/** @var Collection<int, SearchFilter> $filtersKeyed */
$filtersKeyed = $search->filters()->get()->keyBy('filter');
// wipe removed filters from this search
foreach ($filtersKeyed as $filterName => $filter) {
if (array_has($request, $prefix . $filterName)) {
continue;
}
// Remove all filter values for this filter
$search->filters()->where('filter', $filterName)->delete();
}
return $this;
}
/**
* @throws AuthorizationException
*/
public function fetchActivitySearch(
Search $search,
Request $request,
SearchTransformer $searchTransformer,
): JsonResponse {
$this->authorize('view', $search);
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withCollection(
$user->searches()->get(),
$searchTransformer
->withConsumer($user)
);
}
/**
* Deletes a saved search
*
* @param Request $request
* @param Search $search
*
* @throws Exception
*
* @return JsonResponse
*/
public function deleteActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('delete', $search);
// Orphan any AutomatedReports that use this search
$search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);
// Delete filters and the search itself
$search->filters()->delete();
$search->delete();
return $this->response->withOk();
}
public function live(Request $request, ElasticActivityRepository $repository): JsonResponse
{
$user = $this->getUserFromRequest($request);
$this->request->validate([
'sort_direction' => 'in:asc,desc',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
]);
$activities = $repository->getLiveCoachingEligibleActivities(
user: $user,
lookBackMinutes: self::LOOK_BACK,
limit: (int) $this->request->input('limit', 25),
page: (int) $this->request->input('page', 1),
sortBy: ['actual_start_time', 'scheduled_start_time'],
sortDirection: (string) $this->request->input('sort_direction', 'asc'),
);
$this->response
->getManager()
->parseIncludes(['organizer.group', 'prospect'])
->setSerializer(new JsonSerializer());
return $this->response->withCollection($activities, new ActivityTransformer());
}
/**
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function show(Activity $activity, ActivityService $activityService): JsonResponse
{
$this->authorize('show', $activity);
$user = $activity->getUser();
$team = $user->getTeam();
// Sync the opportunity with the latest data if possible.
if ($activity->opportunity_id) {
try {
$crmService = $this->providerRegistry->get($team->crm->provider);
if (! $user->isCrmRequired()) {
$crmService->setUser($team->getOwner());
} else {
$crmService->setUser($user);
}
$crmService->syncOpportunity($activity->opportunity->crm_provider_id);
} catch (Exception $exception) {
// Move on.
}
}
$activityData = $activityService->getActivityData($this->request->user(), $activity);
return response()->json($activityData);
}
public function createRecording(Activity $activity)
{
$this->authorize('record', $activity);
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Tell Twilio to start recording this activity.
if ($activity->recording_state === Activity::RECORDING_OFF) {
$job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withCreated();
}
return $this->response->errorGone('Activity is already recording.');
}
public function updateRecording(Request $request, Activity $activity)
{
$this->authorize('record', $activity);
$request->validate([
'preference' => 'boolean',
'state' => [
'string',
Rule::in([
Activity::RECORDING_IN_PROGRESS,
Activity::RECORDING_PAUSED,
]),
],
]);
if ($request->has('state')) {
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Toggle the recording state between paused and resumed.
if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {
$job = (new ToggleRecording($activity, $request->input('state')))
->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Recording is not toggleable.');
}
if ($request->has('preference')) {
$activity->update([
'recording_preference' => $request->input('preference') ? 1 : 0,
]);
return $this->response->withOk();
}
return $this->response->errorWrongArgs('Something went wrong');
}
public function stopRecording(Activity $activity)
{
$this->authorize('stopRecord', $activity);
// Tell Twilio to stop recording this activity.
if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {
$job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Activity is not recording.');
}
/**
* Add activity to this user's favorites playlist
*
* @throws AuthorizationException
*/
public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse
{
$this->authorize('favorite', $activity);
$user = $this->getUserFromRequest($this->request);
$favorite = $activity->wasFavoritedBy($user);
$name = $activity->activity_title ?? '';
// It needs to check at least one record.
if (! $favorite) {
$favoritePlaylist = $user->favoritePlaylist();
$playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(
$activity,
$user,
$favoritePlaylist
);
if ($playlistActivity !== null) {
$playlistActivity->update(
// Just update, don't sort.
['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],
);
} else {
$playlistActivity = $activity->playlistActivities()->create([
'playlist_id' => $favoritePlaylist->getId(),
'user_id' => $user->getId(),
'start_time' => 0,
'name' => mb_strimwidth($name, 0, 100),
]);
// Sort it on top.
$playlistActivity->update(
[
'sort' => $playlistActivityRepository->calculateNewSortOrder(
null,
$playlistActivity,
),
],
);
}
$playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);
return new JsonResponse([], JsonResponse::HTTP_CREATED);
}
return new JsonResponse(
[
'error' => [
'code' => AbstractResponse::CODE_CONFLICT,
'http_code' => JsonResponse::HTTP_CONFLICT,
'message' => 'Resource Already Exists',
],
],
JsonResponse::HTTP_CONFLICT,
);
}
/**
* Remove activity from this user's favorites playlist
*
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function unfavorite(Activity $activity)
{
$user = $t...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"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":"Analyzing…","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 Carbon\\Carbon;\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Exception;\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Validation\\Rule;\nuse Illuminate\\Validation\\Rules\\In;\nuse Illuminate\\Validation\\ValidationException;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ActivityAnalytics;\nuse Jiminny\\Component\\ActivitySearch;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Contracts\\ES\\Events\\UpdateSingleEntity;\nuse Jiminny\\Contracts\\ES\\UpdateTargetEnum;\nuse Jiminny\\Contracts\\Nudge\\NudgeFactoryInterface;\nuse Jiminny\\Contracts\\Playlist\\PlaylistTrackFactoryInterface;\nuse Jiminny\\Contracts\\Repositories\\PlaylistActivityRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Enums\\TeamSetting;\nuse Jiminny\\Events\\Activities\\AiAutomation\\ActivityProspectAdded;\nuse Jiminny\\Events\\Activities\\Coaching\\Coached;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Controllers\\CommentContextInterface;\nuse Jiminny\\Http\\Responses\\Api\\AbstractResponse;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\ActivityCommentTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTopicTriggerTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTransformer;\nuse Jiminny\\Http\\Transformers\\AvailabilityNotificationTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingFeedbackTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingSectionsTransformer;\nuse Jiminny\\Http\\Transformers\\SearchTransformer;\nuse Jiminny\\Http\\Transformers\\StatsTransformer;\nuse Jiminny\\Jobs\\Crm\\SaveActivity;\nuse Jiminny\\Jobs\\Crm\\UpdateStage;\nuse Jiminny\\Jobs\\Telephony\\StartRecording;\nuse Jiminny\\Jobs\\Telephony\\StopRecording;\nuse Jiminny\\Jobs\\Telephony\\ToggleRecording;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\CoachingFeedback;\nuse Jiminny\\Models\\CoachingSection;\nuse Jiminny\\Models\\CoachingSectionCriterion;\nuse Jiminny\\Models\\CoachingSectionFeedback;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\LanguageDialect;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Nudge;\nuse Jiminny\\Models\\PlaybookCategory;\nuse Jiminny\\Models\\Playlist;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\Track;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\CoachingFeedbackRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Rules\\MultidimensionalArrayMaxCharRule;\nuse Jiminny\\Services\\ActivityService;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Services\\PlaybackService;\nuse Jiminny\\Services\\UserService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\nuse Ramsey\\Uuid\\Uuid;\nuse Sentry;\nuse Symfony\\Component\\HttpFoundation;\n\nfinal class ActivityController extends Controller implements CommentContextInterface\n{\n // Number of minutes to look back on activities. i.e. a timeout on activity duration.\n private const int LOOK_BACK = 180;\n\n public function __construct(\n private ProviderRegistry $providerRegistry,\n private ActivityService $activityService,\n Response $response,\n private UserService $userService,\n private ActivitySearch\\Service\\ActivitySearch $activitySearch,\n private NudgeFactoryInterface $nudgeFactory,\n private ActivityCommentService $activityCommentService,\n private LoggerInterface $logger,\n private readonly CoachingFeedbackRepository $coachingFeedbackRepository,\n private readonly TeamRepository $teamRepository,\n ) {\n parent::__construct($response);\n }\n\n public static function getCommentImplementation(): string\n {\n return Comment::class;\n }\n\n public function delete()\n {\n $this->request->validate([\n '*' => 'uuid:activities',\n ]);\n\n $deletedIds = [];\n foreach ($this->request->all() as $activityId) {\n $activity = Activity::idOrUuId($activityId);\n\n try {\n if ($this->authorize('delete', $activity)) {\n $activity->delete();\n $deletedIds[] = $activityId;\n\n \\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n }\n } catch (AuthorizationException $authorizationException) {\n // They didn't have permission.\n }\n }\n\n return $this->response->withArray($deletedIds);\n }\n\n public function update(Request $request, Activity $activity)\n {\n $this->authorize('updateMetadata', $activity);\n\n $request->validate([\n 'title' => 'string|max:250',\n 'category_id' => 'uuid:playbook_categories',\n 'language' => [\n new In(\n LanguageDialect::query()\n ->with('language')\n ->cursor()\n ->map(static function (LanguageDialect $languageDialect): string {\n return $languageDialect->getLanguageLocale();\n })\n ->all()\n ),\n ],\n ]);\n\n if ($request->has('title')) {\n $activity->title = $request->input('title');\n }\n\n if ($request->has('category_id')) {\n $category = PlaybookCategory::uuid($request->input('category_id'));\n\n if ($category->playbook->team_id !== $request->user()->team_id) {\n return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n if ($request->has('language')) {\n if (! $activity->isInProgress()) {\n return $this->response->withError(\n 'Activity language can only be set while the meeting is in progress.',\n 400\n );\n }\n\n $activity->setLanguageCode($request->input('language'));\n }\n\n $activity->save();\n\n return $this->response->withOk();\n }\n\n // XXX: This should be merged with the update method.\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws SocialAccountTokenInvalidException\n *\n * @return mixed\n */\n public function summarize(Activity $activity): mixed\n {\n $this->logger->info('[Log Activity] Summarizing activity ', [\n 'activityId' => $activity->getUuid(),\n 'payload' => $this->request->all(),\n ]);\n $this->authorize('update', $activity);\n\n $this->logger->info('[Log Activity] Validating summary');\n // Validate the payload.\n $this->validateSummary($activity);\n\n // All objects must belong to this team.\n /** @var User $user */\n $user = $this->request->user();\n $team = $user->getTeam();\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n try {\n $crmUser = $user;\n if ($user->isCrmRequired() === false) {\n $crmUser = $team->owner;\n }\n $crmService->setUser($crmUser);\n } catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());\n }\n\n $rawEntities = $this->request->input('entities');\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid(\n $this->request->input('layout_id')\n );\n\n // Delay execution of CRM jobs to avoid locking issues.\n $jobDelay = 0;\n\n // If we have arrived from a notification, mark it as read.\n $notificationId = $this->request->input('nId');\n if ($notificationId) {\n $notification = $user->unreadNotifications->where('id', $notificationId)->first();\n\n if ($notification) {\n $notification->markAsRead();\n }\n }\n\n $title = $this->request->input('title');\n $prospects = $this->request->input('prospects');\n $opportunityId = $this->request->input('opportunity_id');\n $stageId = $this->request->input('stage_id');\n $categoryId = $this->request->input('category_id');\n $summary = $this->request->input('summary');\n $crmProviderId = $this->request->input('crm_id');\n $isInternal = $this->request->input('is_internal') ?? false;\n\n $lead = null;\n $category = null;\n $account = null;\n $contact = null;\n $opportunity = null;\n $stage = null;\n $callStage = null;\n\n foreach ($prospects as $prospectData) {\n $objectId = $prospectData['id'];\n\n if ($objectId === null) {\n continue;\n }\n\n $objectType = $prospectData['type'];\n $this->logger->info('debug', ['prospect_data' => $prospectData]);\n\n try {\n if ($objectType === null) {\n $this->logger->info('no object type');\n if ($crmService instanceof SupportsObjectTypeParseInterface) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n }\n\n switch ($objectType) {\n case 'lead':\n $this->logger->info('Processing lead');\n /** @var Lead|null $lead */\n $lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();\n\n // Lead does not exist locally, import it.\n if ($lead === null) {\n $this->logger->info('Lead does not exist locally');\n /** @var Lead $lead */\n $lead = $crmService->syncLead($objectId);\n }\n\n $this->logger->info('Lead found', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n if ($stageId === null) {\n $this->logger->info('Stage ID is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $lead->stage;\n\n break;\n }\n\n $this->logger->info('Looking for stage');\n // Determine if they have changed the stage.\n /** @var Stage $stage */\n $stage = $team->crm->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_LEAD)\n ->firstOrFail();\n\n $this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);\n if ($lead->stage_id && $lead->stage_id !== $stage->id) {\n $this->logger->info('Stage has changed');\n // Storage current stage on activity.\n $callStage = $lead->stage;\n\n // The stage has changed, update in remote CRM.\n dispatch(new UpdateStage($activity, $lead, $callStage, $stage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing lead stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->getName(),\n $stage->getName()\n ),\n [\n 'user' => $user->getUuid(),\n 'lead' => $lead->getUuid(),\n ]\n );\n } else {\n $this->logger->info('Stage has not changed');\n // Stage remains as current.\n $callStage = $stage;\n }\n\n break;\n\n case 'account':\n $this->logger->info('Processing account');\n // If the object is not a lead, it should be an account.\n $account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();\n\n // Account does not exist locally, import it.\n if ($account === null) {\n $this->logger->info('Account does not exist locally');\n $account = $crmService->syncAccount($objectId);\n }\n\n $this->logger->info('Account found', ['accountId' => $account->id]);\n\n break;\n case 'contact':\n $this->logger->info('processing contact');\n $contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $this->logger->info('contact does not exist locally');\n $contact = $crmService->syncContact($objectId);\n }\n\n $this->logger->info('resolving account');\n $account = $this->resolveAccount($team, $contact, $crmService, $prospects);\n\n break;\n }\n\n // If they have specified an opportunity, retrieve this with stage.\n if ($opportunityId) {\n $this->logger->info('opportunity id is set');\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if ($opportunity === null) {\n $this->logger->info('opportunity does not exist locally');\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n if ($stageId === null) {\n $this->logger->info('stage id is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $opportunity->stage ?? null;\n } else {\n $this->logger->info('looking for stage');\n /** @var ?Stage $opportunityStage */\n $opportunityStage = $team->crm\n ->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n // There is a chance we still cannot import this opportunity.\n if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {\n $this->logger->info('opportunity stage has changed');\n // Storage current stage on activity.\n $callStage = $opportunity->stage;\n\n dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing opportunity stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->name,\n $opportunityStage->name\n ),\n [\n 'userId' => $user->id_string,\n 'opportunityId' => $opportunity->id_string,\n ]\n );\n } else {\n $this->logger->info('opportunity stage has not changed');\n // Stage remains as current.\n $callStage = $opportunityStage;\n }\n }\n }\n\n if ($crmProviderId) {\n // Cast $crmProviderId to string otherwise it won't use database index for some records\n $linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();\n\n // Check if this activity has already been assigned to a different activity.\n if ($linkedActivity && $linkedActivity->id !== $activity->id) {\n throw new InvalidArgumentException(\n 'Sorry, the linked task has already been logged under a different call. '\n . 'Please choose another linked task.'\n );\n }\n }\n } catch (InvalidArgumentException $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($exception->getMessage());\n } catch (Exception $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorInternalError(\n 'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'\n );\n }\n }\n\n if ($categoryId) {\n $category = PlaybookCategory::uuid($categoryId);\n\n if ($category->playbook->team_id !== $team->id) {\n throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n $this->logger->info('Prospect data', [\n 'lead_id' => $lead?->getId(),\n 'account_id' => $account?->getId(),\n 'contact_id' => $contact?->getId(),\n 'opportunity_id' => $opportunity?->getId(),\n 'stage_id' => $stage?->getId(),\n ]);\n\n if ($title) {\n $activity->title = $title;\n }\n\n if ($summary) {\n $activity->summary = $summary;\n }\n\n if ($crmProviderId) {\n $activity->crm_provider_id = $crmProviderId;\n }\n\n if ($callStage) {\n $this->logger->info('Setting stage id', ['stageId' => $callStage->id]);\n $activity->stage_id = $callStage->id;\n }\n\n if ($lead) {\n $this->logger->info('Setting lead id', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n // If we are changed from an account > lead, unset the account data.\n $this->logger->info('Unsetting account id, opportunity id, contact id, value');\n $activity->account_id = null;\n $activity->opportunity_id = null;\n $activity->contact_id = null;\n $activity->value = null;\n }\n\n if ($account) {\n $this->logger->info('Setting account id', ['accountId' => $account->id]);\n $activity->account_id = $account->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('unsetting lead id');\n $activity->lead_id = null;\n\n // Unset the contact if switching different accounts. Will be set up below if still applicable.\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {\n $this->logger->info('Unsetting contact id');\n $activity->contact_id = null;\n }\n }\n\n if ($opportunity) {\n $this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);\n $this->logger->info('unsetting lead id');\n $activity->opportunity_id = $opportunity->id;\n $activity->value = $opportunity->value;\n\n // If we are changed from an lead > account, unset the lead data.\n $activity->lead_id = null;\n }\n\n if ($contact) {\n $this->logger->info('setting contact id', ['contactId' => $contact->id]);\n $activity->contact_id = $contact->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('Unsetting lead id');\n $activity->lead_id = null;\n }\n\n $activity->is_internal = $isInternal;\n $activity->save();\n $activity->refresh();\n\n $this->logger->notice('Activity saved', [\n 'activity_id' => $activity->getId(),\n 'lead_id' => $activity->lead_id,\n 'account_id' => $activity->account_id,\n 'contact_id' => $activity->contact_id,\n 'opportunity_id' => $activity->opportunity_id,\n 'stage_id' => $activity->stage_id,\n 'crm_provider_id' => $activity->getCrmProviderId(),\n ]);\n\n // Store entities as field data on the activity.\n $updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);\n\n if ($activity->isLoggable()) {\n // Follow-up Task or Event data.\n $followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);\n\n $this->logger->info('CRM LOG manual log triggered', [\n 'activityId' => $activity->getUuid(),\n 'followupData' => $followupData,\n 'userId' => $user->getUuid(),\n ]);\n\n // Store data in the CRM.\n // ++add check for crm_required\n $job = new SaveActivity($activity, $followupData);\n\n if ($updatedData) {\n $job->delay(Carbon::now()->addMinutes($jobDelay));\n }\n\n dispatch($job);\n\n // Manually dispatch log for Opportunity or Prospect added\n if ($activity->hasOpportunity() || $activity->hasProspect()) {\n event(new ActivityProspectAdded(\n activity: $activity,\n eventSource: 'manually-log-crm-data'\n ));\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.\n *\n * @param ServiceInterface $service\n * @param Activity $activity\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array\n {\n $updatedData = [];\n $existingData = $activity->data()->get();\n\n // We need to delete any existing data to overwrite with latest values.\n $activity->data()->delete();\n\n $layoutEntities = $layout->entities()\n ->with('field', 'parent')\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->get();\n\n /** @var LayoutEntity $entity */\n foreach ($layoutEntities as $entity) {\n // If the user has provided a value for this entity\n if (array_key_exists($entity->id_string, $entities)) {\n $value = $entities[$entity->id_string];\n\n // Convert raw data into values that the CRM can consume.\n if ($value) {\n $value = $service->normalizeValue($entity->field->type, $value);\n }\n\n // Check the field is part of the activity-summary section.\n if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {\n // This is the internal database ID, not the external CRM ID.\n $objectId = null;\n\n switch ($entity->field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $objectId = $activity->account_id;\n\n break;\n\n case Field::OBJECT_CONTACT:\n $objectId = $activity->contact_id;\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n $objectId = $activity->opportunity_id;\n\n break;\n\n case Field::OBJECT_LEAD:\n $objectId = $activity->lead_id;\n\n break;\n\n case Field::OBJECT_TASK:\n case Field::OBJECT_EVENT:\n $objectId = $activity->id;\n\n break;\n }\n\n if ($objectId) {\n /** @var FieldData $data */\n $data = $activity->data()->create([\n 'crm_layout_entity_id' => $entity->id,\n 'crm_field_id' => $entity->crm_field_id,\n 'object_type' => $entity->field->object_type,\n 'object_id' => $objectId,\n 'value' => $value,\n ]);\n\n // Never send read-only field data to the CRM.\n if ($entity->read_only === false && $entity->is_visible) {\n $existingValue = $existingData\n ->where('crm_layout_entity_id', $entity->id)\n ->where('crm_field_id', $entity->crm_field_id)\n ->where('object_type', $entity->field->object_type)\n ->where('object_id', $objectId)\n ->first();\n\n // If the field was actually changed, we need to reflect this in the CRM too.\n if ($existingValue === null || $existingValue->value !== $value) {\n $updatedData[] = $data->id;\n }\n }\n }\n }\n }\n }\n\n return $updatedData;\n }\n\n /**\n * Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.\n *\n * @param ServiceInterface $crmService\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array\n {\n $fieldData = [];\n foreach ($entities as $entityId => $value) {\n // Only bother with fields that have a value.\n if ($value) {\n // Extract the entity from the UUID. Check the field is valid and part of the follow-up section.\n $entity = $layout->entities()\n ->uuid($entityId, false)\n ->whereHas('parent', function ($query) {\n $query->where('label', 'follow-up');\n })\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->first();\n\n if ($entity) {\n // Convert raw data into values that the CRM can consume.\n $value = $crmService->normalizeValue($entity->field->type, $value);\n\n // Add the field and value to the payload.\n $fieldData += [\n $entity->field->crm_provider_id => $value,\n ];\n }\n }\n }\n\n return $fieldData;\n }\n\n /**\n * @param Activity $activity\n */\n private function validateSummary(Activity $activity): void\n {\n $team = $activity->user->team;\n $crmProvider = $team->crm->provider;\n $attributes = [];\n\n $rules = [\n 'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,\n 'title' => 'string|max:250',\n 'prospects' => 'required|array',\n 'opportunity_id' => new CrmReference($crmProvider),\n 'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',\n 'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator\n 'summary' => 'max:50000',\n 'nId' => 'exists:notifications,id',\n 'crm_id' => new CrmReference($crmProvider),\n 'entities' => 'array',\n 'is_internal' => 'boolean',\n ];\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));\n\n // Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.\n $entities = $layout->entities()\n ->where('read_only', 0)\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->whereHas('parent', function ($query) use ($activity) {\n if ($activity->isLoggable() === false) {\n $query->where('label', '<>', 'follow-up');\n }\n });\n\n $isInternal = $this->request->input('is_internal', false);\n\n foreach ($entities->get() as $entity) {\n $rules += $this->buildFieldValidator($entity, $isInternal);\n $attributes += $this->buildFieldMessage($entity);\n }\n\n $this->request->validate($rules, [], $attributes);\n }\n\n private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array\n {\n return [\n 'entities.' . $entity->id_string => $entity->getValidator($isInternal),\n ];\n }\n\n /**\n * @param LayoutEntity $entity\n *\n * @return array\n */\n private function buildFieldMessage(LayoutEntity $entity): array\n {\n $label = $entity->label;\n if ($label === null) {\n $label = $entity->field->label;\n }\n\n return [\n 'entities.' . $entity->id_string => $label,\n ];\n }\n\n public function search(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->debugLog(\n $user,\n 'User extracted from request',\n ['user' => $user->getId(), 'tz' => $user->getTimezone()]\n );\n\n $searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());\n\n $this->debugLog(\n $user,\n 'ActivitySearch criteria built',\n ['searchCriteria' => $searchCriteria]\n );\n\n $filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);\n\n $this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);\n\n $this->validateSearch($request, $filterSet);\n\n $this->debugLog($user, 'Request validated');\n\n $searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);\n\n /** @var Collection<Activity> $activities */\n $activities = $searchResponse['results'];\n\n $this->debugLog($user, 'Activities ES response extracted');\n\n $hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(\n $user->getTeamId(),\n TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),\n );\n\n if ($hideInternalMeetingsSetting?->getValue() === '1') {\n $activities = $activities->filter(function (Activity $activity) {\n if ($activity->is_internal && empty($activity->actual_start_time)) {\n return false;\n }\n\n return true;\n });\n }\n\n $this->debugLog($user, 'Internal meetings (?!) filtered');\n\n $this->response->getManager()\n ->parseIncludes([\n 'category',\n 'organizer.group',\n 'prospect',\n 'stage',\n 'opportunity',\n 'stats',\n 'scorecards',\n 'masterTrack',\n 'activeParticipants',\n 'notification',\n ])\n ->setSerializer(new JsonSerializer());\n\n $transformerExcludes = $this->request->input('exclude');\n if ($transformerExcludes) {\n $this->response->getManager()->parseExcludes($transformerExcludes);\n }\n\n $this->debugLog($user, 'Response Manager (?!) applied');\n\n $transformer = new ActivityTransformer();\n $transformer->setConsumer($user);\n\n $this->debugLog($user, 'Activity Transformer added');\n\n $resource = new \\League\\Fractal\\Resource\\Collection($activities, $transformer);\n $page = $searchCriteria->getPageNumber();\n\n $this->debugLog($user, 'Search criteria page number called', ['page' => $page]);\n\n $histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');\n\n $this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);\n\n return $this->response->withArray([\n 'pagination' => [\n 'total' => $searchResponse['totalHits'],\n 'current' => $page,\n 'prev' => max($page - 1, 1),\n 'next' => $page + 1,\n ],\n 'results' => $this->response->getManager()->createData($resource)->toArray(),\n 'histogram' => $histogram,\n ]);\n }\n\n private function debugLog(User $user, string $logMessage, ?array $context = []): void\n {\n // Debug for Learning People Only\n if ($user->getTeamId() !== 260) {\n return;\n }\n\n Log::notice(\n sprintf('[activity-search-controller] %s', $logMessage),\n $context\n );\n }\n\n /** @throws ValidationException */\n private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void\n {\n $rules = [\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ];\n\n if ($prefix !== null && mb_strpos($prefix, '.') !== false) {\n $rules[rtrim($prefix, '.')] = sprintf(\n 'required|array|max:%d',\n $filterSet->count()\n );\n }\n\n $validationRules = $filterSet->getValidationRules($prefix)\n ->merge($rules)\n ->all();\n\n $request->validate($validationRules);\n }\n\n public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $search = $this->updateOrCreateActivitySearch($request);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function updateActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('update', $search);\n\n $this->updateOrCreateActivitySearch($request, $search);\n\n return $this->response->withOk();\n }\n\n private function storeNamedSearchFilters(\n Collection $request,\n Search $search,\n FilterDefinitionCollection $filterSet,\n ?string $prefix = null,\n ): self {\n $arrayTypeProperties = $filterSet\n ->getPropertyTypes([\n FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,\n ])\n ->all();\n\n $supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);\n\n foreach ($supportedRequestProperties as $requestPropertyName) {\n if (! array_has($request, $requestPropertyName)) {\n continue;\n }\n\n /** @var string|string[] $propertyValue */\n $propertyValue = array_get($request, $requestPropertyName);\n $propertyName = $prefix === null\n ? $requestPropertyName\n : mb_substr($requestPropertyName, mb_strlen($prefix));\n\n $isArrayType = array_has($arrayTypeProperties, $propertyName);\n\n if (! $isArrayType) {\n /** @var string $requestPropertyValue */\n\n $search->filters()->updateOrCreate(\n [\n 'filter' => $propertyName,\n ],\n [\n 'value' => $propertyValue,\n ]\n );\n\n continue;\n }\n\n /** @var string[] $requestPropertyValue */\n\n /** @var SearchFilter[]|Collection $existingFilterValues */\n $existingFilterValuesKeyed = $search->filters()\n ->where('filter', $propertyName)\n ->get()\n ->keyBy('id');\n\n // Iterate over values provided as request parameters\n foreach ($propertyValue as $value) {\n /** @var SearchFilter|null $valueFilter */\n $valueFilter = $search->filters()\n ->where(\n [\n 'filter' => $propertyName,\n 'value' => $value,\n ]\n )\n ->first();\n\n if ($valueFilter !== null) {\n // Remove filter value pair from list to be deleted\n $existingFilterValuesKeyed->forget($valueFilter->id);\n } else {\n // Add new filter/value pair\n $search->filters()->updateOrCreate([\n 'filter' => $propertyName,\n 'value' => $value,\n ]);\n }\n }\n\n // Delete filter value pairs for this filter that no longer exist in request parameters\n foreach ($existingFilterValuesKeyed as $existingFilter) {\n $existingFilter->delete();\n }\n }\n\n /** @var Collection<int, SearchFilter> $filtersKeyed */\n $filtersKeyed = $search->filters()->get()->keyBy('filter');\n\n // wipe removed filters from this search\n foreach ($filtersKeyed as $filterName => $filter) {\n if (array_has($request, $prefix . $filterName)) {\n continue;\n }\n\n // Remove all filter values for this filter\n $search->filters()->where('filter', $filterName)->delete();\n }\n\n return $this;\n }\n\n /**\n * @throws AuthorizationException\n */\n public function fetchActivitySearch(\n Search $search,\n Request $request,\n SearchTransformer $searchTransformer,\n ): JsonResponse {\n $this->authorize('view', $search);\n\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection(\n $user->searches()->get(),\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n /**\n * Deletes a saved search\n *\n * @param Request $request\n * @param Search $search\n *\n * @throws Exception\n *\n * @return JsonResponse\n */\n public function deleteActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('delete', $search);\n\n // Orphan any AutomatedReports that use this search\n $search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);\n\n // Delete filters and the search itself\n $search->filters()->delete();\n $search->delete();\n\n return $this->response->withOk();\n }\n\n public function live(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n $user = $this->getUserFromRequest($request);\n\n $this->request->validate([\n 'sort_direction' => 'in:asc,desc',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ]);\n\n $activities = $repository->getLiveCoachingEligibleActivities(\n user: $user,\n lookBackMinutes: self::LOOK_BACK,\n limit: (int) $this->request->input('limit', 25),\n page: (int) $this->request->input('page', 1),\n sortBy: ['actual_start_time', 'scheduled_start_time'],\n sortDirection: (string) $this->request->input('sort_direction', 'asc'),\n );\n\n $this->response\n ->getManager()\n ->parseIncludes(['organizer.group', 'prospect'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($activities, new ActivityTransformer());\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function show(Activity $activity, ActivityService $activityService): JsonResponse\n {\n $this->authorize('show', $activity);\n\n $user = $activity->getUser();\n $team = $user->getTeam();\n\n // Sync the opportunity with the latest data if possible.\n if ($activity->opportunity_id) {\n try {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n if (! $user->isCrmRequired()) {\n $crmService->setUser($team->getOwner());\n } else {\n $crmService->setUser($user);\n }\n\n $crmService->syncOpportunity($activity->opportunity->crm_provider_id);\n } catch (Exception $exception) {\n // Move on.\n }\n }\n\n $activityData = $activityService->getActivityData($this->request->user(), $activity);\n\n return response()->json($activityData);\n }\n\n public function createRecording(Activity $activity)\n {\n $this->authorize('record', $activity);\n\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Tell Twilio to start recording this activity.\n if ($activity->recording_state === Activity::RECORDING_OFF) {\n $job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withCreated();\n }\n\n return $this->response->errorGone('Activity is already recording.');\n }\n\n public function updateRecording(Request $request, Activity $activity)\n {\n $this->authorize('record', $activity);\n\n $request->validate([\n 'preference' => 'boolean',\n 'state' => [\n 'string',\n Rule::in([\n Activity::RECORDING_IN_PROGRESS,\n Activity::RECORDING_PAUSED,\n ]),\n ],\n ]);\n\n if ($request->has('state')) {\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Toggle the recording state between paused and resumed.\n if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {\n $job = (new ToggleRecording($activity, $request->input('state')))\n ->onQueue(Constants::QUEUE_CONFERENCES);\n\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Recording is not toggleable.');\n }\n\n if ($request->has('preference')) {\n $activity->update([\n 'recording_preference' => $request->input('preference') ? 1 : 0,\n ]);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorWrongArgs('Something went wrong');\n }\n\n public function stopRecording(Activity $activity)\n {\n $this->authorize('stopRecord', $activity);\n\n // Tell Twilio to stop recording this activity.\n if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {\n $job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Activity is not recording.');\n }\n\n /**\n * Add activity to this user's favorites playlist\n *\n * @throws AuthorizationException\n */\n public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse\n {\n $this->authorize('favorite', $activity);\n\n $user = $this->getUserFromRequest($this->request);\n $favorite = $activity->wasFavoritedBy($user);\n $name = $activity->activity_title ?? '';\n\n // It needs to check at least one record.\n if (! $favorite) {\n $favoritePlaylist = $user->favoritePlaylist();\n\n $playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(\n $activity,\n $user,\n $favoritePlaylist\n );\n\n if ($playlistActivity !== null) {\n $playlistActivity->update(\n // Just update, don't sort.\n ['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],\n );\n } else {\n $playlistActivity = $activity->playlistActivities()->create([\n 'playlist_id' => $favoritePlaylist->getId(),\n 'user_id' => $user->getId(),\n 'start_time' => 0,\n 'name' => mb_strimwidth($name, 0, 100),\n ]);\n // Sort it on top.\n $playlistActivity->update(\n [\n 'sort' => $playlistActivityRepository->calculateNewSortOrder(\n null,\n $playlistActivity,\n ),\n ],\n );\n }\n\n $playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);\n\n return new JsonResponse([], JsonResponse::HTTP_CREATED);\n }\n\n return new JsonResponse(\n [\n 'error' => [\n 'code' => AbstractResponse::CODE_CONFLICT,\n 'http_code' => JsonResponse::HTTP_CONFLICT,\n 'message' => 'Resource Already Exists',\n ],\n ],\n JsonResponse::HTTP_CONFLICT,\n );\n }\n\n /**\n * Remove activity from this user's favorites playlist\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unfavorite(Activity $activity)\n {\n $user = $this->request->user();\n\n $favorites = $activity->favoritedBy($user);\n\n if ($favorites && $favorites->isEmpty()) {\n return $this->response->errorNotFound('Favorite not found.');\n }\n\n $this->authorize('unfavorite', [$activity, $favorites]);\n\n // When you unfavorite an activity,\n // it should remove all the activities in it, including snippets.\n $isDeleted = $favorites->each(function ($favorite) {\n $favorite->forceDelete();\n });\n\n if ($isDeleted) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not remove favorite.');\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function notify(Activity $activity)\n {\n $this->authorize('notify', $activity);\n\n $user = $this->request->user();\n\n $existingNotification = $activity->availabilityNotifications()\n ->where('user_id', $user->id)\n ->exists();\n\n if ($existingNotification) {\n return $this->response->errorWrongArgs('Notification is already configured.');\n }\n\n $notification = Activity\\AvailabilityNotification::create([\n 'user_id' => $user->id,\n 'activity_id' => $activity->id,\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($notification, new AvailabilityNotificationTransformer());\n }\n\n /**\n * @param Activity $activity\n * @param Activity\\AvailabilityNotification $notification\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unnotify(Activity $activity, Activity\\AvailabilityNotification $notification)\n {\n $this->authorize('unnotify', [$activity, $notification]);\n\n if ($notification->sent_at || $notification->delete()) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not delete notification.');\n }\n\n public function play(Request $request, Activity $activity)\n {\n $this->authorize('stream', $activity);\n\n $request->validate([\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $activity->plays()->create([\n 'user_id' => $user->getId(),\n 'start_time' => $request->input('start_time'),\n ]);\n\n return $this->response->withCreated();\n }\n\n /**\n * @param Activity $activity\n *\n * @return mixed\n */\n public function comment(Activity $activity)\n {\n return $this->newComment($activity);\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @return mixed\n */\n public function replyComment(Activity $activity, Comment $comment)\n {\n return $this->newComment($activity, $comment);\n }\n\n /**\n * @param Activity $activity\n * @param Comment|null $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n protected function newComment(Activity $activity, ?Comment $comment = null)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n 'type' => 'integer|between:0,3',\n 'visibility' => sprintf('nullable|integer|between:1,%d', count(Comment::getVisibilityLevels())),\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n $threadStartId = null;\n if ($comment) {\n $threadStartId = $comment->thread_start_id ?: $comment->id;\n }\n\n try {\n $newComment = Comment::create([\n 'parent_comment_id' => $comment->id ?? null,\n 'thread_start_id' => $threadStartId,\n 'activity_id' => $activity->id,\n 'user_id' => $this->request->user()->id,\n 'comment' => trim($this->request->input('comment')),\n 'start_time' => $this->request->input('start_time', 0),\n 'end_time' => $this->request->input('end_time', 0),\n 'type' => $this->request->input('type', Comment::TYPE_NEUTRAL),\n 'visibility' => $this->request->input('visibility', Comment::VISIBILITY_PUBLIC),\n ]);\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($newComment, new ActivityCommentTransformer());\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not create comment.' . $exception->getMessage());\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function updateComment(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n try {\n $comment->update([\n 'comment' => trim($this->request->input('comment')),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment.');\n }\n }\n\n public function updateCommentVisibility(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'visibility' => sprintf('integer|between:1,%d', count(Comment::getVisibilityLevels())),\n ]);\n\n $visibility = $this->request->input('visibility');\n\n if ($comment->parent !== null) {\n return $this->response->errorWrongArgs('Comment visibility can only be updated on top level comments.');\n }\n\n try {\n $this->activityCommentService->updateCommentVisibility($comment, $visibility);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment\\'s visibility.');\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function deleteComment(Activity $activity, Comment $comment)\n {\n $this->authorize('deleteComment', [$activity, $comment]);\n\n // Delete comment and any children.\n $comment->delete();\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function fetchComments()\n {\n $user = $this->request->user();\n $this->request->validate([\n 'forUserId' => 'uuid:users,team_id,' . $user->team_id,\n 'types' => 'array',\n 'types.*' => 'integer|between:0,3',\n ]);\n $forUser = null;\n\n $types = [Comment::TYPE_NEUTRAL, Comment::TYPE_GAME_CHANGER, Comment::TYPE_POSITIVE];\n $user = $this->request->user();\n if ($this->request->has('forUserId')) {\n $forUser = $user->team->users()->uuid($this->request->input('forUserId'));\n }\n\n $comments = Comment::query()\n ->whereHas('activity', static function (Builder $builder) use ($user, $forUser): void {\n $builder\n // I left feedback on my own activity; or\n ->where('activities.user_id', $user->getId());\n if ($forUser) {\n // I left feedback on any activity for this user.\n $builder->orWhere([\n 'user_id' => $user->getId(),\n 'activities.user_id' => $forUser->getId(),\n ]);\n }\n })\n ->whereIn('type', $this->request->input('types', $types))\n ->orderBy('created_at', 'desc')\n ->get();\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity', 'user'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($comments, new ActivityCommentTransformer());\n }\n\n public function deleteCoachingFeedback(Activity $activity, CoachingFeedback $coachingFeedback)\n {\n $this->authorize('deleteCoachingFeedback', [$activity, $coachingFeedback]);\n $activity = $coachingFeedback->getActivity();\n\n if ($coachingFeedback->delete()) {\n event(new UpdateSingleEntity(\n entityId: $activity->getId(),\n updateTarget: UpdateTargetEnum::ACTIVITY,\n purpose: 'delete-coaching-feedback',\n ));\n\n return $this->response->withOk();\n }\n\n return $this->response->withError('Delete operation failed. Contact support.', 500);\n }\n\n /**\n * Add new or update Coaching feedback\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws \\Illuminate\\Validation\\ValidationException\n *\n * @return mixed\n */\n public function putCoachingFeedback(Request $request, Activity $activity)\n {\n $user = $request->user();\n\n if (! $user instanceof User) {\n abort(403);\n }\n $teamId = $user->getTeamId();\n\n $this->authorize('coach', $activity);\n\n $this->request->validate([\n 'coach_id' => 'required|uuid:users,team_id,' . $teamId,\n 'coachee_id' => 'required|uuid:users,team_id,' . $teamId,\n 'visibility' => ['required', Rule::in(CoachingFeedback::VISIBILITIES)],\n 'coaching_sections.*.uuid' => 'required|uuid:coaching_sections',\n 'coaching_sections.*.score' => ['required', Rule::in(CoachingSectionFeedback::SCORES)],\n 'coaching_sections.*.summary' => 'string|max:10000',\n 'coaching_sections.*.criteria.*.uuid' => 'required|uuid:coaching_section_criteria',\n 'coaching_sections.*.criteria.*.note' => 'required|string|max:10000',\n 'sharedWithUsers' => [\n 'required_if:visibility,' . CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS,\n 'array',\n ],\n 'sharedWithUsers.*' => [\n 'uuid:users,team_id,' . $teamId,\n ],\n ]);\n\n /** @var User $coach */\n $coach = User::uuid($this->request->input('coach_id'));\n /** @var User $coachee */\n $coachee = User::uuid($this->request->input('coachee_id'));\n $coachingSectionFeedbacks = $this->request->input('coaching_sections');\n\n $previousRecord = $this->coachingFeedbackRepository->getOneForActivityByCoacheeAndCoach(\n $coachee->getId(),\n $coach->getId(),\n $activity->getId()\n );\n $recordIsNew = false;\n if ($previousRecord === null) {\n $recordIsNew = true;\n }\n\n if (! $coachee->isSameTeamId($coach)) {\n return $this->response->errorForbidden('User not member of your team.');\n }\n\n if (! is_array($coachingSectionFeedbacks) || count($coachingSectionFeedbacks) < 1) {\n return $this->response->withError('At least one Coaching Framework Section shall be scored.', 422);\n }\n\n if (! $activity->participants()->where('participants.user_id', $coachee->id)->exists()) {\n return $this->response->withError('Coached user did not participate activity.', 422);\n }\n\n $visibility = $this->request->input('visibility');\n\n $shouldSendNotification = $recordIsNew;\n if ($recordIsNew === false && $visibility !== $previousRecord->getVisibility()) {\n $shouldSendNotification = true;\n }\n\n /**\n * Create CoachingFeedback\n *\n * @var CoachingFeedback $coachingFeedback\n */\n $coachingFeedback = $activity->coachingFeedbacks()->updateOrCreate(\n [\n 'coach_id' => $coach->id,\n 'coachee_id' => $coachee->id,\n ],\n [\n 'framework_id' => $activity->category->id,\n 'visibility' => $visibility,\n ]\n );\n\n $sharedUserIds = [];\n if ($visibility === CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS) {\n foreach ($this->request->input('sharedWithUsers') as $sharedWithUserUuid) {\n /** @var User $user */\n $user = User::uuid($sharedWithUserUuid);\n $sharedUserIds[] = $user->getId();\n }\n }\n\n $syncResult = $coachingFeedback->customAccessUsers()->sync($sharedUserIds);\n\n $scores = [];\n\n\n /**\n * Create CoachingSectionsFeedbacks.\n *\n * @var CoachingSectionFeedback $coachingSectionFeedback\n */\n foreach ($coachingSectionFeedbacks as $coachingSectionFeedbackInput) {\n $coachingSection = CoachingSection::uuid($coachingSectionFeedbackInput['uuid']);\n $coachingSectionFeedback = $coachingFeedback->sectionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_id' => $coachingSection->id,\n ],\n [\n 'score' => array_get($coachingSectionFeedbackInput, 'score'),\n 'summary' => array_get($coachingSectionFeedbackInput, 'summary') ?? '',\n ]\n );\n\n $scores[] = array_get($coachingSectionFeedbackInput, 'score');\n\n $criteria = array_get($coachingSectionFeedbackInput, 'criteria');\n if (is_array($criteria) && ! empty($criteria)) {\n foreach ($criteria as $criteriaFeedbackInput) {\n $coachingSectionFeedback->criterionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_criterion_id' => CoachingSectionCriterion::uuid(array_get($criteriaFeedbackInput, 'uuid'))\n ->id,\n ],\n ['note' => array_get($criteriaFeedbackInput, 'note')],\n );\n }\n }\n }\n\n $coachingFeedback->average_score = array_sum($scores) / count($scores);\n\n if ($recordIsNew === false && $coachingFeedback->getAverageScore() !== $previousRecord->getAverageScore()) {\n $shouldSendNotification = true;\n }\n if (! empty($syncResult['attached']) || ! empty($syncResult['detached']) || ! empty($syncResult['updated'])) {\n $shouldSendNotification = true;\n }\n\n $coachingFeedback->save();\n // ensure updated at for coaching feedback on section feedback summary added.\n $coachingFeedback->touch();\n\n if ($shouldSendNotification) {\n event(new Coached($coachingFeedback));\n }\n\n Datadog::increment('jiminny.activity.score.update', 1, ['company' => $activity->user->team->slug]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n $coachingFeedbackTransformer = new CoachingFeedbackTransformer();\n $coachingFeedbackTransformer->setConsumer($this->getUserFromRequest($request));\n\n return $this->response->withItem($coachingFeedback, $coachingFeedbackTransformer);\n }\n\n\n /**\n * Retrieve category criteria for coaching.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachingSections(Activity $activity)\n {\n $this->authorize('coach', $activity);\n\n if ($activity->category === null) {\n return $this->response->errorUnprocessable('Category has not yet been assigned.');\n }\n\n $criteria = $activity\n ->category\n ->coachingSections()\n ->where('is_enabled', 1)\n ->orderBy('sequence', 'asc');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($criteria->get(), new CoachingSectionsTransformer());\n }\n\n /**\n * @throws AuthorizationException\n * @throws ValidationException\n *\n * @return mixed\n */\n public function addToPlaylist(Activity $activity, PlaylistTrackFactoryInterface $playlistTrackFactory)\n {\n $this->request->validate([\n 'playlists' => 'required|array',\n 'playlists.*' => 'uuid:playlists',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'name' => 'required|max:100',\n ]);\n\n $this->authorize('addToPlaylist', [$activity, $this->request->input('playlists')]);\n\n $startTime = $this->request->input('start_time');\n $endTime = $this->request->input('end_time');\n $name = $this->request->input('name');\n /** @var User $user */\n $user = $this->request->user();\n\n // Get playlist by uuid.\n foreach ($this->request->input('playlists') as $playlistId) {\n // Pull out the playlist model.\n $playlist = Playlist::uuid($playlistId);\n\n $playlistTrackFactory->createTrack($playlist, $user, [\n 'name' => $name,\n 'activity' => $activity,\n 'start_time' => $startTime,\n 'end_time' => $endTime,\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function share(Request $request, Activity $activity): JsonResponse\n {\n $this->authorize('share', $activity);\n\n $request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'recipients.*.type' => 'in:user,group',\n 'recipients.*.id' => 'string|max:40',\n 'share' => 'string|max:255',\n ]);\n\n $user = $request->user();\n\n $recipients = $request->get('recipients');\n $users = $this->userService->convertRecipientsToUsers($user, $recipients);\n\n $shareData = [\n 'from_user_id' => $user->id,\n 'note' => $request->input('note'),\n 'start_time' => $request->input('start_time'),\n 'end_time' => $request->input('end_time'),\n ];\n\n // Create a share object against a notification provider channel\n if ($request->input('share')) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'notification_provider_channel' => $request->input('share'),\n ]\n )\n );\n\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n\n // Create a share object against each recipient\n foreach ($users as $recipient) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'to_user_id' => $recipient->id,\n ]\n )\n );\n\n // If parent_share_id has been selected yet\n if (! isset($shareData['parent_share_id'])) {\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachRequest(Activity $activity)\n {\n $this->authorize('coachRequest', $activity);\n\n $this->request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'coachers.*.type' => 'required|in:user',\n 'coachers.*.id' => 'required',\n ]);\n\n $coachers = $this->request->get('coachers');\n $user = $this->request->user();\n $users = $this->userService->convertRecipientsToUsers($user, $coachers);\n\n foreach ($users as $coacher) {\n CoachRequest::create([\n 'user_id' => $coacher->id,\n 'activity_id' => $activity->id,\n 'note' => $this->request->get('note'),\n 'start_time' => $this->request->get('start_time'),\n 'end_time' => $this->request->get('end_time'),\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function createActivityTopicTriggers(Activity $activity, LoggerInterface $logger): HttpFoundation\\JsonResponse\n {\n $this->authorize('analyzeTopicTriggers', $activity);\n\n if (! $activity->hasTranscription()) {\n return new HttpFoundation\\JsonResponse(\n [\n 'error' => 'Transcription not found.',\n ],\n JsonResponse::HTTP_NOT_FOUND\n );\n }\n\n $logger->info(__METHOD__ . ': queued for analysis', [\n 'activity' => $activity->id_string,\n ]);\n\n dispatch(new ActivityAnalytics\\Job\\AnalyzeActivityTopicTriggers($activity));\n\n return new HttpFoundation\\JsonResponse(null, JsonResponse::HTTP_CREATED);\n }\n\n public function fetchActivityTopicTriggers(\n Activity $activity,\n LoggerInterface $logger,\n ActivityTopicTriggerTransformer $transformer\n ): HttpFoundation\\JsonResponse {\n $this->authorize('fetchTopicTriggers', $activity);\n\n $logger->debug(__METHOD__, [\n 'activity' => $activity->id_string,\n ]);\n\n if (! $activity->isProcessed()) {\n return new HttpFoundation\\JsonResponse([]);\n }\n\n $payload = [];\n\n if ($activity->hasTopicTriggers()) {\n $payload = $activity->getTopicTriggersSorted()\n ->map(\n static fn (Activity\\TopicTrigger $activityTopicTrigger): array\n => $transformer->transform($activityTopicTrigger)\n )\n ->values()\n ->all();\n }\n\n return new HttpFoundation\\JsonResponse($payload);\n }\n\n /**\n * @param Activity $activity\n * @param StatsTransformer $statsTransformer\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function stats(Activity $activity, StatsTransformer $statsTransformer)\n {\n $this->authorize('stream', $activity);\n\n if (! $activity->hasTranscription()) {\n return $this->response->errorNotFound('Waveform data is not yet generated.');\n }\n\n $this->response\n ->getManager()\n ->parseIncludes(['wavedata'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($activity, $statsTransformer);\n }\n\n public function destroy(Activity $activity)\n {\n $this->authorize('delete', $activity);\n\n $activity->delete();\n\n \\Log::info('Soft delete activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n\n return $this->response->withNoContent();\n }\n\n public function note(Activity $activity)\n {\n $this->authorize('note', $activity);\n\n $this->request->validate([\n 'note' => 'required|min:1|max:2000',\n 'time' => 'required|numeric|min:0|max:86400',\n ]);\n\n $note = $this->request->input('note');\n $time = $this->request->input('time');\n\n $this->activityService->setActivity($activity);\n $this->activityService->takeNote($this->getUser(), $note, $time);\n\n return $this->response->withCreated();\n }\n\n /**\n * Mark an activity as private.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPrivate(Activity $activity)\n {\n $this->authorize('markAsPrivate', $activity);\n\n if ($activity->is_private === false) {\n $activity->is_private = true;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * Mark an activity as public.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPublic(Activity $activity)\n {\n $this->authorize('markAsPublic', $activity);\n\n if ($activity->is_private) {\n $activity->is_private = false;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws LogicException\n */\n public function fetchCloudFrontS3MediaKeys(Activity $activity, PlaybackService $playbackService): JsonResponse\n {\n $masterTrack = $activity->masterTrack()->first();\n\n if (! $masterTrack instanceof Track) {\n throw new LogicException(sprintf('Master track not found for activity \"%s\"', $activity->getUuid()));\n }\n\n return $this->response->withArray(\n $playbackService->generateCookies(\n $masterTrack,\n $this->request->ip(),\n ),\n );\n }\n\n /**\n * @throws ValidationException\n */\n private function updateOrCreateActivitySearch(Request $request, ?Search $search = null): Search\n {\n $request->validate([\n 'name' => 'required|string|min:2|max:100',\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $searchName = $request->input('name');\n\n if ($search !== null) {\n $search->update([\n 'name' => $searchName,\n ]);\n\n return $search;\n }\n\n $request->validate([\n 'filters' => ['required', 'array', new MultidimensionalArrayMaxCharRule(limit: 255)],\n 'nudges' => 'array|max:' . count(Nudge::MAP_CHANNEL),\n 'nudges.*.channel' => 'required|in:' . implode(',', Nudge::MAP_CHANNEL),\n 'nudges.*.frequency' => 'required|in:' . implode(',', Nudge::MAP_FREQUENCY),\n 'nudges.*.expiresAt' => [\n 'required',\n 'date',\n 'after:today',\n 'before_or_equal:' . now()->addYear()->format('Y-m-d'),\n ],\n ]);\n\n $searchCriteria = Criteria::createFromRequest(\n Collection::make($request->input('filters', []))->all(),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($searchCriteria, $user);\n $this->validateSearch($request, $filterSet, 'filters.');\n\n /** @var Search $search */\n $search = Search::create([\n 'name' => $searchName,\n 'uuid' => Uuid::uuid4()->toString(),\n 'user_id' => $user->getId(),\n ]);\n\n Collection::make($request->input('nudges', []))\n ->each(fn (array $attributes): Nudge => $this->nudgeFactory->createNudge($search, $attributes));\n\n $this->storeNamedSearchFilters(Collection::make($request->all()), $search, $filterSet, 'filters.');\n\n return $search;\n }\n\n private function resolveAccount(\n Team $team,\n Contact $contact,\n ServiceInterface $crmService,\n array $prospects,\n ): ?Account {\n $this->logger->info('Resolving account from contact');\n $account = $contact->getAccount();\n\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS)) {\n $this->logger->info('Team does not have feature to link activity to multiple prospects');\n\n return $account;\n }\n\n $this->logger->info('Resolving account from prospect data');\n $accountData = array_filter(\n $prospects,\n static fn (array $prospectData): bool => $prospectData['type'] === 'account'\n );\n\n if (! empty($accountData)) {\n $this->logger->info('Found account data in prospects');\n $accountData = reset($accountData);\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountData['id'])->first();\n\n if (! $account instanceof Account) {\n $this->logger->info('Account not found in database, syncing from CRM');\n $account = $crmService->syncAccount($accountData['id']);\n }\n }\n\n $this->logger->info('Resolved account', ['account' => $account->getId()]);\n\n return $account;\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Http\\Controllers\\API;\n\nuse Carbon\\Carbon;\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Exception;\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Validation\\Rule;\nuse Illuminate\\Validation\\Rules\\In;\nuse Illuminate\\Validation\\ValidationException;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ActivityAnalytics;\nuse Jiminny\\Component\\ActivitySearch;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Contracts\\ES\\Events\\UpdateSingleEntity;\nuse Jiminny\\Contracts\\ES\\UpdateTargetEnum;\nuse Jiminny\\Contracts\\Nudge\\NudgeFactoryInterface;\nuse Jiminny\\Contracts\\Playlist\\PlaylistTrackFactoryInterface;\nuse Jiminny\\Contracts\\Repositories\\PlaylistActivityRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Enums\\TeamSetting;\nuse Jiminny\\Events\\Activities\\AiAutomation\\ActivityProspectAdded;\nuse Jiminny\\Events\\Activities\\Coaching\\Coached;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Controllers\\CommentContextInterface;\nuse Jiminny\\Http\\Responses\\Api\\AbstractResponse;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\ActivityCommentTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTopicTriggerTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTransformer;\nuse Jiminny\\Http\\Transformers\\AvailabilityNotificationTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingFeedbackTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingSectionsTransformer;\nuse Jiminny\\Http\\Transformers\\SearchTransformer;\nuse Jiminny\\Http\\Transformers\\StatsTransformer;\nuse Jiminny\\Jobs\\Crm\\SaveActivity;\nuse Jiminny\\Jobs\\Crm\\UpdateStage;\nuse Jiminny\\Jobs\\Telephony\\StartRecording;\nuse Jiminny\\Jobs\\Telephony\\StopRecording;\nuse Jiminny\\Jobs\\Telephony\\ToggleRecording;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\CoachingFeedback;\nuse Jiminny\\Models\\CoachingSection;\nuse Jiminny\\Models\\CoachingSectionCriterion;\nuse Jiminny\\Models\\CoachingSectionFeedback;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\LanguageDialect;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Nudge;\nuse Jiminny\\Models\\PlaybookCategory;\nuse Jiminny\\Models\\Playlist;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\Track;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\CoachingFeedbackRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Rules\\MultidimensionalArrayMaxCharRule;\nuse Jiminny\\Services\\ActivityService;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Services\\PlaybackService;\nuse Jiminny\\Services\\UserService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\nuse Ramsey\\Uuid\\Uuid;\nuse Sentry;\nuse Symfony\\Component\\HttpFoundation;\n\nfinal class ActivityController extends Controller implements CommentContextInterface\n{\n // Number of minutes to look back on activities. i.e. a timeout on activity duration.\n private const int LOOK_BACK = 180;\n\n public function __construct(\n private ProviderRegistry $providerRegistry,\n private ActivityService $activityService,\n Response $response,\n private UserService $userService,\n private ActivitySearch\\Service\\ActivitySearch $activitySearch,\n private NudgeFactoryInterface $nudgeFactory,\n private ActivityCommentService $activityCommentService,\n private LoggerInterface $logger,\n private readonly CoachingFeedbackRepository $coachingFeedbackRepository,\n private readonly TeamRepository $teamRepository,\n ) {\n parent::__construct($response);\n }\n\n public static function getCommentImplementation(): string\n {\n return Comment::class;\n }\n\n public function delete()\n {\n $this->request->validate([\n '*' => 'uuid:activities',\n ]);\n\n $deletedIds = [];\n foreach ($this->request->all() as $activityId) {\n $activity = Activity::idOrUuId($activityId);\n\n try {\n if ($this->authorize('delete', $activity)) {\n $activity->delete();\n $deletedIds[] = $activityId;\n\n \\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n }\n } catch (AuthorizationException $authorizationException) {\n // They didn't have permission.\n }\n }\n\n return $this->response->withArray($deletedIds);\n }\n\n public function update(Request $request, Activity $activity)\n {\n $this->authorize('updateMetadata', $activity);\n\n $request->validate([\n 'title' => 'string|max:250',\n 'category_id' => 'uuid:playbook_categories',\n 'language' => [\n new In(\n LanguageDialect::query()\n ->with('language')\n ->cursor()\n ->map(static function (LanguageDialect $languageDialect): string {\n return $languageDialect->getLanguageLocale();\n })\n ->all()\n ),\n ],\n ]);\n\n if ($request->has('title')) {\n $activity->title = $request->input('title');\n }\n\n if ($request->has('category_id')) {\n $category = PlaybookCategory::uuid($request->input('category_id'));\n\n if ($category->playbook->team_id !== $request->user()->team_id) {\n return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n if ($request->has('language')) {\n if (! $activity->isInProgress()) {\n return $this->response->withError(\n 'Activity language can only be set while the meeting is in progress.',\n 400\n );\n }\n\n $activity->setLanguageCode($request->input('language'));\n }\n\n $activity->save();\n\n return $this->response->withOk();\n }\n\n // XXX: This should be merged with the update method.\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws SocialAccountTokenInvalidException\n *\n * @return mixed\n */\n public function summarize(Activity $activity): mixed\n {\n $this->logger->info('[Log Activity] Summarizing activity ', [\n 'activityId' => $activity->getUuid(),\n 'payload' => $this->request->all(),\n ]);\n $this->authorize('update', $activity);\n\n $this->logger->info('[Log Activity] Validating summary');\n // Validate the payload.\n $this->validateSummary($activity);\n\n // All objects must belong to this team.\n /** @var User $user */\n $user = $this->request->user();\n $team = $user->getTeam();\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n try {\n $crmUser = $user;\n if ($user->isCrmRequired() === false) {\n $crmUser = $team->owner;\n }\n $crmService->setUser($crmUser);\n } catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());\n }\n\n $rawEntities = $this->request->input('entities');\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid(\n $this->request->input('layout_id')\n );\n\n // Delay execution of CRM jobs to avoid locking issues.\n $jobDelay = 0;\n\n // If we have arrived from a notification, mark it as read.\n $notificationId = $this->request->input('nId');\n if ($notificationId) {\n $notification = $user->unreadNotifications->where('id', $notificationId)->first();\n\n if ($notification) {\n $notification->markAsRead();\n }\n }\n\n $title = $this->request->input('title');\n $prospects = $this->request->input('prospects');\n $opportunityId = $this->request->input('opportunity_id');\n $stageId = $this->request->input('stage_id');\n $categoryId = $this->request->input('category_id');\n $summary = $this->request->input('summary');\n $crmProviderId = $this->request->input('crm_id');\n $isInternal = $this->request->input('is_internal') ?? false;\n\n $lead = null;\n $category = null;\n $account = null;\n $contact = null;\n $opportunity = null;\n $stage = null;\n $callStage = null;\n\n foreach ($prospects as $prospectData) {\n $objectId = $prospectData['id'];\n\n if ($objectId === null) {\n continue;\n }\n\n $objectType = $prospectData['type'];\n $this->logger->info('debug', ['prospect_data' => $prospectData]);\n\n try {\n if ($objectType === null) {\n $this->logger->info('no object type');\n if ($crmService instanceof SupportsObjectTypeParseInterface) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n }\n\n switch ($objectType) {\n case 'lead':\n $this->logger->info('Processing lead');\n /** @var Lead|null $lead */\n $lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();\n\n // Lead does not exist locally, import it.\n if ($lead === null) {\n $this->logger->info('Lead does not exist locally');\n /** @var Lead $lead */\n $lead = $crmService->syncLead($objectId);\n }\n\n $this->logger->info('Lead found', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n if ($stageId === null) {\n $this->logger->info('Stage ID is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $lead->stage;\n\n break;\n }\n\n $this->logger->info('Looking for stage');\n // Determine if they have changed the stage.\n /** @var Stage $stage */\n $stage = $team->crm->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_LEAD)\n ->firstOrFail();\n\n $this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);\n if ($lead->stage_id && $lead->stage_id !== $stage->id) {\n $this->logger->info('Stage has changed');\n // Storage current stage on activity.\n $callStage = $lead->stage;\n\n // The stage has changed, update in remote CRM.\n dispatch(new UpdateStage($activity, $lead, $callStage, $stage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing lead stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->getName(),\n $stage->getName()\n ),\n [\n 'user' => $user->getUuid(),\n 'lead' => $lead->getUuid(),\n ]\n );\n } else {\n $this->logger->info('Stage has not changed');\n // Stage remains as current.\n $callStage = $stage;\n }\n\n break;\n\n case 'account':\n $this->logger->info('Processing account');\n // If the object is not a lead, it should be an account.\n $account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();\n\n // Account does not exist locally, import it.\n if ($account === null) {\n $this->logger->info('Account does not exist locally');\n $account = $crmService->syncAccount($objectId);\n }\n\n $this->logger->info('Account found', ['accountId' => $account->id]);\n\n break;\n case 'contact':\n $this->logger->info('processing contact');\n $contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $this->logger->info('contact does not exist locally');\n $contact = $crmService->syncContact($objectId);\n }\n\n $this->logger->info('resolving account');\n $account = $this->resolveAccount($team, $contact, $crmService, $prospects);\n\n break;\n }\n\n // If they have specified an opportunity, retrieve this with stage.\n if ($opportunityId) {\n $this->logger->info('opportunity id is set');\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if ($opportunity === null) {\n $this->logger->info('opportunity does not exist locally');\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n if ($stageId === null) {\n $this->logger->info('stage id is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $opportunity->stage ?? null;\n } else {\n $this->logger->info('looking for stage');\n /** @var ?Stage $opportunityStage */\n $opportunityStage = $team->crm\n ->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n // There is a chance we still cannot import this opportunity.\n if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {\n $this->logger->info('opportunity stage has changed');\n // Storage current stage on activity.\n $callStage = $opportunity->stage;\n\n dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing opportunity stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->name,\n $opportunityStage->name\n ),\n [\n 'userId' => $user->id_string,\n 'opportunityId' => $opportunity->id_string,\n ]\n );\n } else {\n $this->logger->info('opportunity stage has not changed');\n // Stage remains as current.\n $callStage = $opportunityStage;\n }\n }\n }\n\n if ($crmProviderId) {\n // Cast $crmProviderId to string otherwise it won't use database index for some records\n $linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();\n\n // Check if this activity has already been assigned to a different activity.\n if ($linkedActivity && $linkedActivity->id !== $activity->id) {\n throw new InvalidArgumentException(\n 'Sorry, the linked task has already been logged under a different call. '\n . 'Please choose another linked task.'\n );\n }\n }\n } catch (InvalidArgumentException $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($exception->getMessage());\n } catch (Exception $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorInternalError(\n 'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'\n );\n }\n }\n\n if ($categoryId) {\n $category = PlaybookCategory::uuid($categoryId);\n\n if ($category->playbook->team_id !== $team->id) {\n throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n $this->logger->info('Prospect data', [\n 'lead_id' => $lead?->getId(),\n 'account_id' => $account?->getId(),\n 'contact_id' => $contact?->getId(),\n 'opportunity_id' => $opportunity?->getId(),\n 'stage_id' => $stage?->getId(),\n ]);\n\n if ($title) {\n $activity->title = $title;\n }\n\n if ($summary) {\n $activity->summary = $summary;\n }\n\n if ($crmProviderId) {\n $activity->crm_provider_id = $crmProviderId;\n }\n\n if ($callStage) {\n $this->logger->info('Setting stage id', ['stageId' => $callStage->id]);\n $activity->stage_id = $callStage->id;\n }\n\n if ($lead) {\n $this->logger->info('Setting lead id', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n // If we are changed from an account > lead, unset the account data.\n $this->logger->info('Unsetting account id, opportunity id, contact id, value');\n $activity->account_id = null;\n $activity->opportunity_id = null;\n $activity->contact_id = null;\n $activity->value = null;\n }\n\n if ($account) {\n $this->logger->info('Setting account id', ['accountId' => $account->id]);\n $activity->account_id = $account->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('unsetting lead id');\n $activity->lead_id = null;\n\n // Unset the contact if switching different accounts. Will be set up below if still applicable.\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {\n $this->logger->info('Unsetting contact id');\n $activity->contact_id = null;\n }\n }\n\n if ($opportunity) {\n $this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);\n $this->logger->info('unsetting lead id');\n $activity->opportunity_id = $opportunity->id;\n $activity->value = $opportunity->value;\n\n // If we are changed from an lead > account, unset the lead data.\n $activity->lead_id = null;\n }\n\n if ($contact) {\n $this->logger->info('setting contact id', ['contactId' => $contact->id]);\n $activity->contact_id = $contact->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('Unsetting lead id');\n $activity->lead_id = null;\n }\n\n $activity->is_internal = $isInternal;\n $activity->save();\n $activity->refresh();\n\n $this->logger->notice('Activity saved', [\n 'activity_id' => $activity->getId(),\n 'lead_id' => $activity->lead_id,\n 'account_id' => $activity->account_id,\n 'contact_id' => $activity->contact_id,\n 'opportunity_id' => $activity->opportunity_id,\n 'stage_id' => $activity->stage_id,\n 'crm_provider_id' => $activity->getCrmProviderId(),\n ]);\n\n // Store entities as field data on the activity.\n $updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);\n\n if ($activity->isLoggable()) {\n // Follow-up Task or Event data.\n $followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);\n\n $this->logger->info('CRM LOG manual log triggered', [\n 'activityId' => $activity->getUuid(),\n 'followupData' => $followupData,\n 'userId' => $user->getUuid(),\n ]);\n\n // Store data in the CRM.\n // ++add check for crm_required\n $job = new SaveActivity($activity, $followupData);\n\n if ($updatedData) {\n $job->delay(Carbon::now()->addMinutes($jobDelay));\n }\n\n dispatch($job);\n\n // Manually dispatch log for Opportunity or Prospect added\n if ($activity->hasOpportunity() || $activity->hasProspect()) {\n event(new ActivityProspectAdded(\n activity: $activity,\n eventSource: 'manually-log-crm-data'\n ));\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.\n *\n * @param ServiceInterface $service\n * @param Activity $activity\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array\n {\n $updatedData = [];\n $existingData = $activity->data()->get();\n\n // We need to delete any existing data to overwrite with latest values.\n $activity->data()->delete();\n\n $layoutEntities = $layout->entities()\n ->with('field', 'parent')\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->get();\n\n /** @var LayoutEntity $entity */\n foreach ($layoutEntities as $entity) {\n // If the user has provided a value for this entity\n if (array_key_exists($entity->id_string, $entities)) {\n $value = $entities[$entity->id_string];\n\n // Convert raw data into values that the CRM can consume.\n if ($value) {\n $value = $service->normalizeValue($entity->field->type, $value);\n }\n\n // Check the field is part of the activity-summary section.\n if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {\n // This is the internal database ID, not the external CRM ID.\n $objectId = null;\n\n switch ($entity->field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $objectId = $activity->account_id;\n\n break;\n\n case Field::OBJECT_CONTACT:\n $objectId = $activity->contact_id;\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n $objectId = $activity->opportunity_id;\n\n break;\n\n case Field::OBJECT_LEAD:\n $objectId = $activity->lead_id;\n\n break;\n\n case Field::OBJECT_TASK:\n case Field::OBJECT_EVENT:\n $objectId = $activity->id;\n\n break;\n }\n\n if ($objectId) {\n /** @var FieldData $data */\n $data = $activity->data()->create([\n 'crm_layout_entity_id' => $entity->id,\n 'crm_field_id' => $entity->crm_field_id,\n 'object_type' => $entity->field->object_type,\n 'object_id' => $objectId,\n 'value' => $value,\n ]);\n\n // Never send read-only field data to the CRM.\n if ($entity->read_only === false && $entity->is_visible) {\n $existingValue = $existingData\n ->where('crm_layout_entity_id', $entity->id)\n ->where('crm_field_id', $entity->crm_field_id)\n ->where('object_type', $entity->field->object_type)\n ->where('object_id', $objectId)\n ->first();\n\n // If the field was actually changed, we need to reflect this in the CRM too.\n if ($existingValue === null || $existingValue->value !== $value) {\n $updatedData[] = $data->id;\n }\n }\n }\n }\n }\n }\n\n return $updatedData;\n }\n\n /**\n * Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.\n *\n * @param ServiceInterface $crmService\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array\n {\n $fieldData = [];\n foreach ($entities as $entityId => $value) {\n // Only bother with fields that have a value.\n if ($value) {\n // Extract the entity from the UUID. Check the field is valid and part of the follow-up section.\n $entity = $layout->entities()\n ->uuid($entityId, false)\n ->whereHas('parent', function ($query) {\n $query->where('label', 'follow-up');\n })\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->first();\n\n if ($entity) {\n // Convert raw data into values that the CRM can consume.\n $value = $crmService->normalizeValue($entity->field->type, $value);\n\n // Add the field and value to the payload.\n $fieldData += [\n $entity->field->crm_provider_id => $value,\n ];\n }\n }\n }\n\n return $fieldData;\n }\n\n /**\n * @param Activity $activity\n */\n private function validateSummary(Activity $activity): void\n {\n $team = $activity->user->team;\n $crmProvider = $team->crm->provider;\n $attributes = [];\n\n $rules = [\n 'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,\n 'title' => 'string|max:250',\n 'prospects' => 'required|array',\n 'opportunity_id' => new CrmReference($crmProvider),\n 'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',\n 'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator\n 'summary' => 'max:50000',\n 'nId' => 'exists:notifications,id',\n 'crm_id' => new CrmReference($crmProvider),\n 'entities' => 'array',\n 'is_internal' => 'boolean',\n ];\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));\n\n // Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.\n $entities = $layout->entities()\n ->where('read_only', 0)\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->whereHas('parent', function ($query) use ($activity) {\n if ($activity->isLoggable() === false) {\n $query->where('label', '<>', 'follow-up');\n }\n });\n\n $isInternal = $this->request->input('is_internal', false);\n\n foreach ($entities->get() as $entity) {\n $rules += $this->buildFieldValidator($entity, $isInternal);\n $attributes += $this->buildFieldMessage($entity);\n }\n\n $this->request->validate($rules, [], $attributes);\n }\n\n private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array\n {\n return [\n 'entities.' . $entity->id_string => $entity->getValidator($isInternal),\n ];\n }\n\n /**\n * @param LayoutEntity $entity\n *\n * @return array\n */\n private function buildFieldMessage(LayoutEntity $entity): array\n {\n $label = $entity->label;\n if ($label === null) {\n $label = $entity->field->label;\n }\n\n return [\n 'entities.' . $entity->id_string => $label,\n ];\n }\n\n public function search(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->debugLog(\n $user,\n 'User extracted from request',\n ['user' => $user->getId(), 'tz' => $user->getTimezone()]\n );\n\n $searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());\n\n $this->debugLog(\n $user,\n 'ActivitySearch criteria built',\n ['searchCriteria' => $searchCriteria]\n );\n\n $filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);\n\n $this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);\n\n $this->validateSearch($request, $filterSet);\n\n $this->debugLog($user, 'Request validated');\n\n $searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);\n\n /** @var Collection<Activity> $activities */\n $activities = $searchResponse['results'];\n\n $this->debugLog($user, 'Activities ES response extracted');\n\n $hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(\n $user->getTeamId(),\n TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),\n );\n\n if ($hideInternalMeetingsSetting?->getValue() === '1') {\n $activities = $activities->filter(function (Activity $activity) {\n if ($activity->is_internal && empty($activity->actual_start_time)) {\n return false;\n }\n\n return true;\n });\n }\n\n $this->debugLog($user, 'Internal meetings (?!) filtered');\n\n $this->response->getManager()\n ->parseIncludes([\n 'category',\n 'organizer.group',\n 'prospect',\n 'stage',\n 'opportunity',\n 'stats',\n 'scorecards',\n 'masterTrack',\n 'activeParticipants',\n 'notification',\n ])\n ->setSerializer(new JsonSerializer());\n\n $transformerExcludes = $this->request->input('exclude');\n if ($transformerExcludes) {\n $this->response->getManager()->parseExcludes($transformerExcludes);\n }\n\n $this->debugLog($user, 'Response Manager (?!) applied');\n\n $transformer = new ActivityTransformer();\n $transformer->setConsumer($user);\n\n $this->debugLog($user, 'Activity Transformer added');\n\n $resource = new \\League\\Fractal\\Resource\\Collection($activities, $transformer);\n $page = $searchCriteria->getPageNumber();\n\n $this->debugLog($user, 'Search criteria page number called', ['page' => $page]);\n\n $histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');\n\n $this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);\n\n return $this->response->withArray([\n 'pagination' => [\n 'total' => $searchResponse['totalHits'],\n 'current' => $page,\n 'prev' => max($page - 1, 1),\n 'next' => $page + 1,\n ],\n 'results' => $this->response->getManager()->createData($resource)->toArray(),\n 'histogram' => $histogram,\n ]);\n }\n\n private function debugLog(User $user, string $logMessage, ?array $context = []): void\n {\n // Debug for Learning People Only\n if ($user->getTeamId() !== 260) {\n return;\n }\n\n Log::notice(\n sprintf('[activity-search-controller] %s', $logMessage),\n $context\n );\n }\n\n /** @throws ValidationException */\n private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void\n {\n $rules = [\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ];\n\n if ($prefix !== null && mb_strpos($prefix, '.') !== false) {\n $rules[rtrim($prefix, '.')] = sprintf(\n 'required|array|max:%d',\n $filterSet->count()\n );\n }\n\n $validationRules = $filterSet->getValidationRules($prefix)\n ->merge($rules)\n ->all();\n\n $request->validate($validationRules);\n }\n\n public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $search = $this->updateOrCreateActivitySearch($request);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function updateActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('update', $search);\n\n $this->updateOrCreateActivitySearch($request, $search);\n\n return $this->response->withOk();\n }\n\n private function storeNamedSearchFilters(\n Collection $request,\n Search $search,\n FilterDefinitionCollection $filterSet,\n ?string $prefix = null,\n ): self {\n $arrayTypeProperties = $filterSet\n ->getPropertyTypes([\n FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,\n ])\n ->all();\n\n $supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);\n\n foreach ($supportedRequestProperties as $requestPropertyName) {\n if (! array_has($request, $requestPropertyName)) {\n continue;\n }\n\n /** @var string|string[] $propertyValue */\n $propertyValue = array_get($request, $requestPropertyName);\n $propertyName = $prefix === null\n ? $requestPropertyName\n : mb_substr($requestPropertyName, mb_strlen($prefix));\n\n $isArrayType = array_has($arrayTypeProperties, $propertyName);\n\n if (! $isArrayType) {\n /** @var string $requestPropertyValue */\n\n $search->filters()->updateOrCreate(\n [\n 'filter' => $propertyName,\n ],\n [\n 'value' => $propertyValue,\n ]\n );\n\n continue;\n }\n\n /** @var string[] $requestPropertyValue */\n\n /** @var SearchFilter[]|Collection $existingFilterValues */\n $existingFilterValuesKeyed = $search->filters()\n ->where('filter', $propertyName)\n ->get()\n ->keyBy('id');\n\n // Iterate over values provided as request parameters\n foreach ($propertyValue as $value) {\n /** @var SearchFilter|null $valueFilter */\n $valueFilter = $search->filters()\n ->where(\n [\n 'filter' => $propertyName,\n 'value' => $value,\n ]\n )\n ->first();\n\n if ($valueFilter !== null) {\n // Remove filter value pair from list to be deleted\n $existingFilterValuesKeyed->forget($valueFilter->id);\n } else {\n // Add new filter/value pair\n $search->filters()->updateOrCreate([\n 'filter' => $propertyName,\n 'value' => $value,\n ]);\n }\n }\n\n // Delete filter value pairs for this filter that no longer exist in request parameters\n foreach ($existingFilterValuesKeyed as $existingFilter) {\n $existingFilter->delete();\n }\n }\n\n /** @var Collection<int, SearchFilter> $filtersKeyed */\n $filtersKeyed = $search->filters()->get()->keyBy('filter');\n\n // wipe removed filters from this search\n foreach ($filtersKeyed as $filterName => $filter) {\n if (array_has($request, $prefix . $filterName)) {\n continue;\n }\n\n // Remove all filter values for this filter\n $search->filters()->where('filter', $filterName)->delete();\n }\n\n return $this;\n }\n\n /**\n * @throws AuthorizationException\n */\n public function fetchActivitySearch(\n Search $search,\n Request $request,\n SearchTransformer $searchTransformer,\n ): JsonResponse {\n $this->authorize('view', $search);\n\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection(\n $user->searches()->get(),\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n /**\n * Deletes a saved search\n *\n * @param Request $request\n * @param Search $search\n *\n * @throws Exception\n *\n * @return JsonResponse\n */\n public function deleteActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('delete', $search);\n\n // Orphan any AutomatedReports that use this search\n $search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);\n\n // Delete filters and the search itself\n $search->filters()->delete();\n $search->delete();\n\n return $this->response->withOk();\n }\n\n public function live(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n $user = $this->getUserFromRequest($request);\n\n $this->request->validate([\n 'sort_direction' => 'in:asc,desc',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ]);\n\n $activities = $repository->getLiveCoachingEligibleActivities(\n user: $user,\n lookBackMinutes: self::LOOK_BACK,\n limit: (int) $this->request->input('limit', 25),\n page: (int) $this->request->input('page', 1),\n sortBy: ['actual_start_time', 'scheduled_start_time'],\n sortDirection: (string) $this->request->input('sort_direction', 'asc'),\n );\n\n $this->response\n ->getManager()\n ->parseIncludes(['organizer.group', 'prospect'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($activities, new ActivityTransformer());\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function show(Activity $activity, ActivityService $activityService): JsonResponse\n {\n $this->authorize('show', $activity);\n\n $user = $activity->getUser();\n $team = $user->getTeam();\n\n // Sync the opportunity with the latest data if possible.\n if ($activity->opportunity_id) {\n try {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n if (! $user->isCrmRequired()) {\n $crmService->setUser($team->getOwner());\n } else {\n $crmService->setUser($user);\n }\n\n $crmService->syncOpportunity($activity->opportunity->crm_provider_id);\n } catch (Exception $exception) {\n // Move on.\n }\n }\n\n $activityData = $activityService->getActivityData($this->request->user(), $activity);\n\n return response()->json($activityData);\n }\n\n public function createRecording(Activity $activity)\n {\n $this->authorize('record', $activity);\n\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Tell Twilio to start recording this activity.\n if ($activity->recording_state === Activity::RECORDING_OFF) {\n $job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withCreated();\n }\n\n return $this->response->errorGone('Activity is already recording.');\n }\n\n public function updateRecording(Request $request, Activity $activity)\n {\n $this->authorize('record', $activity);\n\n $request->validate([\n 'preference' => 'boolean',\n 'state' => [\n 'string',\n Rule::in([\n Activity::RECORDING_IN_PROGRESS,\n Activity::RECORDING_PAUSED,\n ]),\n ],\n ]);\n\n if ($request->has('state')) {\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Toggle the recording state between paused and resumed.\n if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {\n $job = (new ToggleRecording($activity, $request->input('state')))\n ->onQueue(Constants::QUEUE_CONFERENCES);\n\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Recording is not toggleable.');\n }\n\n if ($request->has('preference')) {\n $activity->update([\n 'recording_preference' => $request->input('preference') ? 1 : 0,\n ]);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorWrongArgs('Something went wrong');\n }\n\n public function stopRecording(Activity $activity)\n {\n $this->authorize('stopRecord', $activity);\n\n // Tell Twilio to stop recording this activity.\n if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {\n $job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Activity is not recording.');\n }\n\n /**\n * Add activity to this user's favorites playlist\n *\n * @throws AuthorizationException\n */\n public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse\n {\n $this->authorize('favorite', $activity);\n\n $user = $this->getUserFromRequest($this->request);\n $favorite = $activity->wasFavoritedBy($user);\n $name = $activity->activity_title ?? '';\n\n // It needs to check at least one record.\n if (! $favorite) {\n $favoritePlaylist = $user->favoritePlaylist();\n\n $playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(\n $activity,\n $user,\n $favoritePlaylist\n );\n\n if ($playlistActivity !== null) {\n $playlistActivity->update(\n // Just update, don't sort.\n ['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],\n );\n } else {\n $playlistActivity = $activity->playlistActivities()->create([\n 'playlist_id' => $favoritePlaylist->getId(),\n 'user_id' => $user->getId(),\n 'start_time' => 0,\n 'name' => mb_strimwidth($name, 0, 100),\n ]);\n // Sort it on top.\n $playlistActivity->update(\n [\n 'sort' => $playlistActivityRepository->calculateNewSortOrder(\n null,\n $playlistActivity,\n ),\n ],\n );\n }\n\n $playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);\n\n return new JsonResponse([], JsonResponse::HTTP_CREATED);\n }\n\n return new JsonResponse(\n [\n 'error' => [\n 'code' => AbstractResponse::CODE_CONFLICT,\n 'http_code' => JsonResponse::HTTP_CONFLICT,\n 'message' => 'Resource Already Exists',\n ],\n ],\n JsonResponse::HTTP_CONFLICT,\n );\n }\n\n /**\n * Remove activity from this user's favorites playlist\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unfavorite(Activity $activity)\n {\n $user = $this->request->user();\n\n $favorites = $activity->favoritedBy($user);\n\n if ($favorites && $favorites->isEmpty()) {\n return $this->response->errorNotFound('Favorite not found.');\n }\n\n $this->authorize('unfavorite', [$activity, $favorites]);\n\n // When you unfavorite an activity,\n // it should remove all the activities in it, including snippets.\n $isDeleted = $favorites->each(function ($favorite) {\n $favorite->forceDelete();\n });\n\n if ($isDeleted) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not remove favorite.');\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function notify(Activity $activity)\n {\n $this->authorize('notify', $activity);\n\n $user = $this->request->user();\n\n $existingNotification = $activity->availabilityNotifications()\n ->where('user_id', $user->id)\n ->exists();\n\n if ($existingNotification) {\n return $this->response->errorWrongArgs('Notification is already configured.');\n }\n\n $notification = Activity\\AvailabilityNotification::create([\n 'user_id' => $user->id,\n 'activity_id' => $activity->id,\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($notification, new AvailabilityNotificationTransformer());\n }\n\n /**\n * @param Activity $activity\n * @param Activity\\AvailabilityNotification $notification\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unnotify(Activity $activity, Activity\\AvailabilityNotification $notification)\n {\n $this->authorize('unnotify', [$activity, $notification]);\n\n if ($notification->sent_at || $notification->delete()) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not delete notification.');\n }\n\n public function play(Request $request, Activity $activity)\n {\n $this->authorize('stream', $activity);\n\n $request->validate([\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $activity->plays()->create([\n 'user_id' => $user->getId(),\n 'start_time' => $request->input('start_time'),\n ]);\n\n return $this->response->withCreated();\n }\n\n /**\n * @param Activity $activity\n *\n * @return mixed\n */\n public function comment(Activity $activity)\n {\n return $this->newComment($activity);\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @return mixed\n */\n public function replyComment(Activity $activity, Comment $comment)\n {\n return $this->newComment($activity, $comment);\n }\n\n /**\n * @param Activity $activity\n * @param Comment|null $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n protected function newComment(Activity $activity, ?Comment $comment = null)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n 'type' => 'integer|between:0,3',\n 'visibility' => sprintf('nullable|integer|between:1,%d', count(Comment::getVisibilityLevels())),\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n $threadStartId = null;\n if ($comment) {\n $threadStartId = $comment->thread_start_id ?: $comment->id;\n }\n\n try {\n $newComment = Comment::create([\n 'parent_comment_id' => $comment->id ?? null,\n 'thread_start_id' => $threadStartId,\n 'activity_id' => $activity->id,\n 'user_id' => $this->request->user()->id,\n 'comment' => trim($this->request->input('comment')),\n 'start_time' => $this->request->input('start_time', 0),\n 'end_time' => $this->request->input('end_time', 0),\n 'type' => $this->request->input('type', Comment::TYPE_NEUTRAL),\n 'visibility' => $this->request->input('visibility', Comment::VISIBILITY_PUBLIC),\n ]);\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($newComment, new ActivityCommentTransformer());\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not create comment.' . $exception->getMessage());\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function updateComment(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n try {\n $comment->update([\n 'comment' => trim($this->request->input('comment')),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment.');\n }\n }\n\n public function updateCommentVisibility(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'visibility' => sprintf('integer|between:1,%d', count(Comment::getVisibilityLevels())),\n ]);\n\n $visibility = $this->request->input('visibility');\n\n if ($comment->parent !== null) {\n return $this->response->errorWrongArgs('Comment visibility can only be updated on top level comments.');\n }\n\n try {\n $this->activityCommentService->updateCommentVisibility($comment, $visibility);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment\\'s visibility.');\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function deleteComment(Activity $activity, Comment $comment)\n {\n $this->authorize('deleteComment', [$activity, $comment]);\n\n // Delete comment and any children.\n $comment->delete();\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function fetchComments()\n {\n $user = $this->request->user();\n $this->request->validate([\n 'forUserId' => 'uuid:users,team_id,' . $user->team_id,\n 'types' => 'array',\n 'types.*' => 'integer|between:0,3',\n ]);\n $forUser = null;\n\n $types = [Comment::TYPE_NEUTRAL, Comment::TYPE_GAME_CHANGER, Comment::TYPE_POSITIVE];\n $user = $this->request->user();\n if ($this->request->has('forUserId')) {\n $forUser = $user->team->users()->uuid($this->request->input('forUserId'));\n }\n\n $comments = Comment::query()\n ->whereHas('activity', static function (Builder $builder) use ($user, $forUser): void {\n $builder\n // I left feedback on my own activity; or\n ->where('activities.user_id', $user->getId());\n if ($forUser) {\n // I left feedback on any activity for this user.\n $builder->orWhere([\n 'user_id' => $user->getId(),\n 'activities.user_id' => $forUser->getId(),\n ]);\n }\n })\n ->whereIn('type', $this->request->input('types', $types))\n ->orderBy('created_at', 'desc')\n ->get();\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity', 'user'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($comments, new ActivityCommentTransformer());\n }\n\n public function deleteCoachingFeedback(Activity $activity, CoachingFeedback $coachingFeedback)\n {\n $this->authorize('deleteCoachingFeedback', [$activity, $coachingFeedback]);\n $activity = $coachingFeedback->getActivity();\n\n if ($coachingFeedback->delete()) {\n event(new UpdateSingleEntity(\n entityId: $activity->getId(),\n updateTarget: UpdateTargetEnum::ACTIVITY,\n purpose: 'delete-coaching-feedback',\n ));\n\n return $this->response->withOk();\n }\n\n return $this->response->withError('Delete operation failed. Contact support.', 500);\n }\n\n /**\n * Add new or update Coaching feedback\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws \\Illuminate\\Validation\\ValidationException\n *\n * @return mixed\n */\n public function putCoachingFeedback(Request $request, Activity $activity)\n {\n $user = $request->user();\n\n if (! $user instanceof User) {\n abort(403);\n }\n $teamId = $user->getTeamId();\n\n $this->authorize('coach', $activity);\n\n $this->request->validate([\n 'coach_id' => 'required|uuid:users,team_id,' . $teamId,\n 'coachee_id' => 'required|uuid:users,team_id,' . $teamId,\n 'visibility' => ['required', Rule::in(CoachingFeedback::VISIBILITIES)],\n 'coaching_sections.*.uuid' => 'required|uuid:coaching_sections',\n 'coaching_sections.*.score' => ['required', Rule::in(CoachingSectionFeedback::SCORES)],\n 'coaching_sections.*.summary' => 'string|max:10000',\n 'coaching_sections.*.criteria.*.uuid' => 'required|uuid:coaching_section_criteria',\n 'coaching_sections.*.criteria.*.note' => 'required|string|max:10000',\n 'sharedWithUsers' => [\n 'required_if:visibility,' . CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS,\n 'array',\n ],\n 'sharedWithUsers.*' => [\n 'uuid:users,team_id,' . $teamId,\n ],\n ]);\n\n /** @var User $coach */\n $coach = User::uuid($this->request->input('coach_id'));\n /** @var User $coachee */\n $coachee = User::uuid($this->request->input('coachee_id'));\n $coachingSectionFeedbacks = $this->request->input('coaching_sections');\n\n $previousRecord = $this->coachingFeedbackRepository->getOneForActivityByCoacheeAndCoach(\n $coachee->getId(),\n $coach->getId(),\n $activity->getId()\n );\n $recordIsNew = false;\n if ($previousRecord === null) {\n $recordIsNew = true;\n }\n\n if (! $coachee->isSameTeamId($coach)) {\n return $this->response->errorForbidden('User not member of your team.');\n }\n\n if (! is_array($coachingSectionFeedbacks) || count($coachingSectionFeedbacks) < 1) {\n return $this->response->withError('At least one Coaching Framework Section shall be scored.', 422);\n }\n\n if (! $activity->participants()->where('participants.user_id', $coachee->id)->exists()) {\n return $this->response->withError('Coached user did not participate activity.', 422);\n }\n\n $visibility = $this->request->input('visibility');\n\n $shouldSendNotification = $recordIsNew;\n if ($recordIsNew === false && $visibility !== $previousRecord->getVisibility()) {\n $shouldSendNotification = true;\n }\n\n /**\n * Create CoachingFeedback\n *\n * @var CoachingFeedback $coachingFeedback\n */\n $coachingFeedback = $activity->coachingFeedbacks()->updateOrCreate(\n [\n 'coach_id' => $coach->id,\n 'coachee_id' => $coachee->id,\n ],\n [\n 'framework_id' => $activity->category->id,\n 'visibility' => $visibility,\n ]\n );\n\n $sharedUserIds = [];\n if ($visibility === CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS) {\n foreach ($this->request->input('sharedWithUsers') as $sharedWithUserUuid) {\n /** @var User $user */\n $user = User::uuid($sharedWithUserUuid);\n $sharedUserIds[] = $user->getId();\n }\n }\n\n $syncResult = $coachingFeedback->customAccessUsers()->sync($sharedUserIds);\n\n $scores = [];\n\n\n /**\n * Create CoachingSectionsFeedbacks.\n *\n * @var CoachingSectionFeedback $coachingSectionFeedback\n */\n foreach ($coachingSectionFeedbacks as $coachingSectionFeedbackInput) {\n $coachingSection = CoachingSection::uuid($coachingSectionFeedbackInput['uuid']);\n $coachingSectionFeedback = $coachingFeedback->sectionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_id' => $coachingSection->id,\n ],\n [\n 'score' => array_get($coachingSectionFeedbackInput, 'score'),\n 'summary' => array_get($coachingSectionFeedbackInput, 'summary') ?? '',\n ]\n );\n\n $scores[] = array_get($coachingSectionFeedbackInput, 'score');\n\n $criteria = array_get($coachingSectionFeedbackInput, 'criteria');\n if (is_array($criteria) && ! empty($criteria)) {\n foreach ($criteria as $criteriaFeedbackInput) {\n $coachingSectionFeedback->criterionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_criterion_id' => CoachingSectionCriterion::uuid(array_get($criteriaFeedbackInput, 'uuid'))\n ->id,\n ],\n ['note' => array_get($criteriaFeedbackInput, 'note')],\n );\n }\n }\n }\n\n $coachingFeedback->average_score = array_sum($scores) / count($scores);\n\n if ($recordIsNew === false && $coachingFeedback->getAverageScore() !== $previousRecord->getAverageScore()) {\n $shouldSendNotification = true;\n }\n if (! empty($syncResult['attached']) || ! empty($syncResult['detached']) || ! empty($syncResult['updated'])) {\n $shouldSendNotification = true;\n }\n\n $coachingFeedback->save();\n // ensure updated at for coaching feedback on section feedback summary added.\n $coachingFeedback->touch();\n\n if ($shouldSendNotification) {\n event(new Coached($coachingFeedback));\n }\n\n Datadog::increment('jiminny.activity.score.update', 1, ['company' => $activity->user->team->slug]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n $coachingFeedbackTransformer = new CoachingFeedbackTransformer();\n $coachingFeedbackTransformer->setConsumer($this->getUserFromRequest($request));\n\n return $this->response->withItem($coachingFeedback, $coachingFeedbackTransformer);\n }\n\n\n /**\n * Retrieve category criteria for coaching.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachingSections(Activity $activity)\n {\n $this->authorize('coach', $activity);\n\n if ($activity->category === null) {\n return $this->response->errorUnprocessable('Category has not yet been assigned.');\n }\n\n $criteria = $activity\n ->category\n ->coachingSections()\n ->where('is_enabled', 1)\n ->orderBy('sequence', 'asc');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($criteria->get(), new CoachingSectionsTransformer());\n }\n\n /**\n * @throws AuthorizationException\n * @throws ValidationException\n *\n * @return mixed\n */\n public function addToPlaylist(Activity $activity, PlaylistTrackFactoryInterface $playlistTrackFactory)\n {\n $this->request->validate([\n 'playlists' => 'required|array',\n 'playlists.*' => 'uuid:playlists',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'name' => 'required|max:100',\n ]);\n\n $this->authorize('addToPlaylist', [$activity, $this->request->input('playlists')]);\n\n $startTime = $this->request->input('start_time');\n $endTime = $this->request->input('end_time');\n $name = $this->request->input('name');\n /** @var User $user */\n $user = $this->request->user();\n\n // Get playlist by uuid.\n foreach ($this->request->input('playlists') as $playlistId) {\n // Pull out the playlist model.\n $playlist = Playlist::uuid($playlistId);\n\n $playlistTrackFactory->createTrack($playlist, $user, [\n 'name' => $name,\n 'activity' => $activity,\n 'start_time' => $startTime,\n 'end_time' => $endTime,\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function share(Request $request, Activity $activity): JsonResponse\n {\n $this->authorize('share', $activity);\n\n $request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'recipients.*.type' => 'in:user,group',\n 'recipients.*.id' => 'string|max:40',\n 'share' => 'string|max:255',\n ]);\n\n $user = $request->user();\n\n $recipients = $request->get('recipients');\n $users = $this->userService->convertRecipientsToUsers($user, $recipients);\n\n $shareData = [\n 'from_user_id' => $user->id,\n 'note' => $request->input('note'),\n 'start_time' => $request->input('start_time'),\n 'end_time' => $request->input('end_time'),\n ];\n\n // Create a share object against a notification provider channel\n if ($request->input('share')) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'notification_provider_channel' => $request->input('share'),\n ]\n )\n );\n\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n\n // Create a share object against each recipient\n foreach ($users as $recipient) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'to_user_id' => $recipient->id,\n ]\n )\n );\n\n // If parent_share_id has been selected yet\n if (! isset($shareData['parent_share_id'])) {\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachRequest(Activity $activity)\n {\n $this->authorize('coachRequest', $activity);\n\n $this->request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'coachers.*.type' => 'required|in:user',\n 'coachers.*.id' => 'required',\n ]);\n\n $coachers = $this->request->get('coachers');\n $user = $this->request->user();\n $users = $this->userService->convertRecipientsToUsers($user, $coachers);\n\n foreach ($users as $coacher) {\n CoachRequest::create([\n 'user_id' => $coacher->id,\n 'activity_id' => $activity->id,\n 'note' => $this->request->get('note'),\n 'start_time' => $this->request->get('start_time'),\n 'end_time' => $this->request->get('end_time'),\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function createActivityTopicTriggers(Activity $activity, LoggerInterface $logger): HttpFoundation\\JsonResponse\n {\n $this->authorize('analyzeTopicTriggers', $activity);\n\n if (! $activity->hasTranscription()) {\n return new HttpFoundation\\JsonResponse(\n [\n 'error' => 'Transcription not found.',\n ],\n JsonResponse::HTTP_NOT_FOUND\n );\n }\n\n $logger->info(__METHOD__ . ': queued for analysis', [\n 'activity' => $activity->id_string,\n ]);\n\n dispatch(new ActivityAnalytics\\Job\\AnalyzeActivityTopicTriggers($activity));\n\n return new HttpFoundation\\JsonResponse(null, JsonResponse::HTTP_CREATED);\n }\n\n public function fetchActivityTopicTriggers(\n Activity $activity,\n LoggerInterface $logger,\n ActivityTopicTriggerTransformer $transformer\n ): HttpFoundation\\JsonResponse {\n $this->authorize('fetchTopicTriggers', $activity);\n\n $logger->debug(__METHOD__, [\n 'activity' => $activity->id_string,\n ]);\n\n if (! $activity->isProcessed()) {\n return new HttpFoundation\\JsonResponse([]);\n }\n\n $payload = [];\n\n if ($activity->hasTopicTriggers()) {\n $payload = $activity->getTopicTriggersSorted()\n ->map(\n static fn (Activity\\TopicTrigger $activityTopicTrigger): array\n => $transformer->transform($activityTopicTrigger)\n )\n ->values()\n ->all();\n }\n\n return new HttpFoundation\\JsonResponse($payload);\n }\n\n /**\n * @param Activity $activity\n * @param StatsTransformer $statsTransformer\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function stats(Activity $activity, StatsTransformer $statsTransformer)\n {\n $this->authorize('stream', $activity);\n\n if (! $activity->hasTranscription()) {\n return $this->response->errorNotFound('Waveform data is not yet generated.');\n }\n\n $this->response\n ->getManager()\n ->parseIncludes(['wavedata'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($activity, $statsTransformer);\n }\n\n public function destroy(Activity $activity)\n {\n $this->authorize('delete', $activity);\n\n $activity->delete();\n\n \\Log::info('Soft delete activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n\n return $this->response->withNoContent();\n }\n\n public function note(Activity $activity)\n {\n $this->authorize('note', $activity);\n\n $this->request->validate([\n 'note' => 'required|min:1|max:2000',\n 'time' => 'required|numeric|min:0|max:86400',\n ]);\n\n $note = $this->request->input('note');\n $time = $this->request->input('time');\n\n $this->activityService->setActivity($activity);\n $this->activityService->takeNote($this->getUser(), $note, $time);\n\n return $this->response->withCreated();\n }\n\n /**\n * Mark an activity as private.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPrivate(Activity $activity)\n {\n $this->authorize('markAsPrivate', $activity);\n\n if ($activity->is_private === false) {\n $activity->is_private = true;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * Mark an activity as public.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPublic(Activity $activity)\n {\n $this->authorize('markAsPublic', $activity);\n\n if ($activity->is_private) {\n $activity->is_private = false;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws LogicException\n */\n public function fetchCloudFrontS3MediaKeys(Activity $activity, PlaybackService $playbackService): JsonResponse\n {\n $masterTrack = $activity->masterTrack()->first();\n\n if (! $masterTrack instanceof Track) {\n throw new LogicException(sprintf('Master track not found for activity \"%s\"', $activity->getUuid()));\n }\n\n return $this->response->withArray(\n $playbackService->generateCookies(\n $masterTrack,\n $this->request->ip(),\n ),\n );\n }\n\n /**\n * @throws ValidationException\n */\n private function updateOrCreateActivitySearch(Request $request, ?Search $search = null): Search\n {\n $request->validate([\n 'name' => 'required|string|min:2|max:100',\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $searchName = $request->input('name');\n\n if ($search !== null) {\n $search->update([\n 'name' => $searchName,\n ]);\n\n return $search;\n }\n\n $request->validate([\n 'filters' => ['required', 'array', new MultidimensionalArrayMaxCharRule(limit: 255)],\n 'nudges' => 'array|max:' . count(Nudge::MAP_CHANNEL),\n 'nudges.*.channel' => 'required|in:' . implode(',', Nudge::MAP_CHANNEL),\n 'nudges.*.frequency' => 'required|in:' . implode(',', Nudge::MAP_FREQUENCY),\n 'nudges.*.expiresAt' => [\n 'required',\n 'date',\n 'after:today',\n 'before_or_equal:' . now()->addYear()->format('Y-m-d'),\n ],\n ]);\n\n $searchCriteria = Criteria::createFromRequest(\n Collection::make($request->input('filters', []))->all(),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($searchCriteria, $user);\n $this->validateSearch($request, $filterSet, 'filters.');\n\n /** @var Search $search */\n $search = Search::create([\n 'name' => $searchName,\n 'uuid' => Uuid::uuid4()->toString(),\n 'user_id' => $user->getId(),\n ]);\n\n Collection::make($request->input('nudges', []))\n ->each(fn (array $attributes): Nudge => $this->nudgeFactory->createNudge($search, $attributes));\n\n $this->storeNamedSearchFilters(Collection::make($request->all()), $search, $filterSet, 'filters.');\n\n return $search;\n }\n\n private function resolveAccount(\n Team $team,\n Contact $contact,\n ServiceInterface $crmService,\n array $prospects,\n ): ?Account {\n $this->logger->info('Resolving account from contact');\n $account = $contact->getAccount();\n\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS)) {\n $this->logger->info('Team does not have feature to link activity to multiple prospects');\n\n return $account;\n }\n\n $this->logger->info('Resolving account from prospect data');\n $accountData = array_filter(\n $prospects,\n static fn (array $prospectData): bool => $prospectData['type'] === 'account'\n );\n\n if (! empty($accountData)) {\n $this->logger->info('Found account data in prospects');\n $accountData = reset($accountData);\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountData['id'])->first();\n\n if (! $account instanceof Account) {\n $this->logger->info('Account not found in database, syncing from CRM');\n $account = $crmService->syncAccount($accountData['id']);\n }\n }\n\n $this->logger->info('Resolved account', ['account' => $account->getId()]);\n\n return $account;\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}]...
|
-7287184300264252456
|
-8385861013499833196
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use Carbon\Carbon;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\In;
use Illuminate\Validation\ValidationException;
use InvalidArgumentException;
use Jiminny\Component\ActivityAnalytics;
use Jiminny\Component\ActivitySearch;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Queue\Constants;
use Jiminny\Contracts\ES\Events\UpdateSingleEntity;
use Jiminny\Contracts\ES\UpdateTargetEnum;
use Jiminny\Contracts\Nudge\NudgeFactoryInterface;
use Jiminny\Contracts\Playlist\PlaylistTrackFactoryInterface;
use Jiminny\Contracts\Repositories\PlaylistActivityRepository;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Enums\TeamSetting;
use Jiminny\Events\Activities\AiAutomation\ActivityProspectAdded;
use Jiminny\Events\Activities\Coaching\Coached;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Controllers\CommentContextInterface;
use Jiminny\Http\Responses\Api\AbstractResponse;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\ActivityCommentTransformer;
use Jiminny\Http\Transformers\ActivityTopicTriggerTransformer;
use Jiminny\Http\Transformers\ActivityTransformer;
use Jiminny\Http\Transformers\AvailabilityNotificationTransformer;
use Jiminny\Http\Transformers\CoachingFeedbackTransformer;
use Jiminny\Http\Transformers\CoachingSectionsTransformer;
use Jiminny\Http\Transformers\SearchTransformer;
use Jiminny\Http\Transformers\StatsTransformer;
use Jiminny\Jobs\Crm\SaveActivity;
use Jiminny\Jobs\Crm\UpdateStage;
use Jiminny\Jobs\Telephony\StartRecording;
use Jiminny\Jobs\Telephony\StopRecording;
use Jiminny\Jobs\Telephony\ToggleRecording;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\CoachingFeedback;
use Jiminny\Models\CoachingSection;
use Jiminny\Models\CoachingSectionCriterion;
use Jiminny\Models\CoachingSectionFeedback;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\LanguageDialect;
use Jiminny\Models\Lead;
use Jiminny\Models\Nudge;
use Jiminny\Models\PlaybookCategory;
use Jiminny\Models\Playlist;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\Track;
use Jiminny\Models\User;
use Jiminny\Repositories\CoachingFeedbackRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Rules\CrmReference;
use Jiminny\Rules\MultidimensionalArrayMaxCharRule;
use Jiminny\Services\ActivityService;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Services\PlaybackService;
use Jiminny\Services\UserService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
use Ramsey\Uuid\Uuid;
use Sentry;
use Symfony\Component\HttpFoundation;
final class ActivityController extends Controller implements CommentContextInterface
{
// Number of minutes to look back on activities. i.e. a timeout on activity duration.
private const int LOOK_BACK = 180;
public function __construct(
private ProviderRegistry $providerRegistry,
private ActivityService $activityService,
Response $response,
private UserService $userService,
private ActivitySearch\Service\ActivitySearch $activitySearch,
private NudgeFactoryInterface $nudgeFactory,
private ActivityCommentService $activityCommentService,
private LoggerInterface $logger,
private readonly CoachingFeedbackRepository $coachingFeedbackRepository,
private readonly TeamRepository $teamRepository,
) {
parent::__construct($response);
}
public static function getCommentImplementation(): string
{
return Comment::class;
}
public function delete()
{
$this->request->validate([
'*' => 'uuid:activities',
]);
$deletedIds = [];
foreach ($this->request->all() as $activityId) {
$activity = Activity::idOrUuId($activityId);
try {
if ($this->authorize('delete', $activity)) {
$activity->delete();
$deletedIds[] = $activityId;
\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);
}
} catch (AuthorizationException $authorizationException) {
// They didn't have permission.
}
}
return $this->response->withArray($deletedIds);
}
public function update(Request $request, Activity $activity)
{
$this->authorize('updateMetadata', $activity);
$request->validate([
'title' => 'string|max:250',
'category_id' => 'uuid:playbook_categories',
'language' => [
new In(
LanguageDialect::query()
->with('language')
->cursor()
->map(static function (LanguageDialect $languageDialect): string {
return $languageDialect->getLanguageLocale();
})
->all()
),
],
]);
if ($request->has('title')) {
$activity->title = $request->input('title');
}
if ($request->has('category_id')) {
$category = PlaybookCategory::uuid($request->input('category_id'));
if ($category->playbook->team_id !== $request->user()->team_id) {
return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
if ($request->has('language')) {
if (! $activity->isInProgress()) {
return $this->response->withError(
'Activity language can only be set while the meeting is in progress.',
400
);
}
$activity->setLanguageCode($request->input('language'));
}
$activity->save();
return $this->response->withOk();
}
// XXX: This should be merged with the update method.
/**
* @param Activity $activity
*
* @throws AuthorizationException
* @throws SocialAccountTokenInvalidException
*
* @return mixed
*/
public function summarize(Activity $activity): mixed
{
$this->logger->info('[Log Activity] Summarizing activity ', [
'activityId' => $activity->getUuid(),
'payload' => $this->request->all(),
]);
$this->authorize('update', $activity);
$this->logger->info('[Log Activity] Validating summary');
// Validate the payload.
$this->validateSummary($activity);
// All objects must belong to this team.
/** @var User $user */
$user = $this->request->user();
$team = $user->getTeam();
$crmService = $this->providerRegistry->get($team->crm->provider);
try {
$crmUser = $user;
if ($user->isCrmRequired() === false) {
$crmUser = $team->owner;
}
$crmService->setUser($crmUser);
} catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());
}
$rawEntities = $this->request->input('entities');
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid(
$this->request->input('layout_id')
);
// Delay execution of CRM jobs to avoid locking issues.
$jobDelay = 0;
// If we have arrived from a notification, mark it as read.
$notificationId = $this->request->input('nId');
if ($notificationId) {
$notification = $user->unreadNotifications->where('id', $notificationId)->first();
if ($notification) {
$notification->markAsRead();
}
}
$title = $this->request->input('title');
$prospects = $this->request->input('prospects');
$opportunityId = $this->request->input('opportunity_id');
$stageId = $this->request->input('stage_id');
$categoryId = $this->request->input('category_id');
$summary = $this->request->input('summary');
$crmProviderId = $this->request->input('crm_id');
$isInternal = $this->request->input('is_internal') ?? false;
$lead = null;
$category = null;
$account = null;
$contact = null;
$opportunity = null;
$stage = null;
$callStage = null;
foreach ($prospects as $prospectData) {
$objectId = $prospectData['id'];
if ($objectId === null) {
continue;
}
$objectType = $prospectData['type'];
$this->logger->info('debug', ['prospect_data' => $prospectData]);
try {
if ($objectType === null) {
$this->logger->info('no object type');
if ($crmService instanceof SupportsObjectTypeParseInterface) {
$objectType = $crmService->parseObjectType($objectId);
}
}
switch ($objectType) {
case 'lead':
$this->logger->info('Processing lead');
/** @var Lead|null $lead */
$lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();
// Lead does not exist locally, import it.
if ($lead === null) {
$this->logger->info('Lead does not exist locally');
/** @var Lead $lead */
$lead = $crmService->syncLead($objectId);
}
$this->logger->info('Lead found', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
if ($stageId === null) {
$this->logger->info('Stage ID is null');
// If it was not provided, just assume it is the current stage.
$callStage = $lead->stage;
break;
}
$this->logger->info('Looking for stage');
// Determine if they have changed the stage.
/** @var Stage $stage */
$stage = $team->crm->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_LEAD)
->firstOrFail();
$this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);
if ($lead->stage_id && $lead->stage_id !== $stage->id) {
$this->logger->info('Stage has changed');
// Storage current stage on activity.
$callStage = $lead->stage;
// The stage has changed, update in remote CRM.
dispatch(new UpdateStage($activity, $lead, $callStage, $stage));
$this->logger->info(
sprintf(
'[%s] User changing lead stage from %s to %s',
$crmService->getDisplayName(),
$callStage->getName(),
$stage->getName()
),
[
'user' => $user->getUuid(),
'lead' => $lead->getUuid(),
]
);
} else {
$this->logger->info('Stage has not changed');
// Stage remains as current.
$callStage = $stage;
}
break;
case 'account':
$this->logger->info('Processing account');
// If the object is not a lead, it should be an account.
$account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();
// Account does not exist locally, import it.
if ($account === null) {
$this->logger->info('Account does not exist locally');
$account = $crmService->syncAccount($objectId);
}
$this->logger->info('Account found', ['accountId' => $account->id]);
break;
case 'contact':
$this->logger->info('processing contact');
$contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$this->logger->info('contact does not exist locally');
$contact = $crmService->syncContact($objectId);
}
$this->logger->info('resolving account');
$account = $this->resolveAccount($team, $contact, $crmService, $prospects);
break;
}
// If they have specified an opportunity, retrieve this with stage.
if ($opportunityId) {
$this->logger->info('opportunity id is set');
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if ($opportunity === null) {
$this->logger->info('opportunity does not exist locally');
$opportunity = $crmService->syncOpportunity($opportunityId);
}
if ($stageId === null) {
$this->logger->info('stage id is null');
// If it was not provided, just assume it is the current stage.
$callStage = $opportunity->stage ?? null;
} else {
$this->logger->info('looking for stage');
/** @var ?Stage $opportunityStage */
$opportunityStage = $team->crm
->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
// There is a chance we still cannot import this opportunity.
if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {
$this->logger->info('opportunity stage has changed');
// Storage current stage on activity.
$callStage = $opportunity->stage;
dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));
$this->logger->info(
sprintf(
'[%s] User changing opportunity stage from %s to %s',
$crmService->getDisplayName(),
$callStage->name,
$opportunityStage->name
),
[
'userId' => $user->id_string,
'opportunityId' => $opportunity->id_string,
]
);
} else {
$this->logger->info('opportunity stage has not changed');
// Stage remains as current.
$callStage = $opportunityStage;
}
}
}
if ($crmProviderId) {
// Cast $crmProviderId to string otherwise it won't use database index for some records
$linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();
// Check if this activity has already been assigned to a different activity.
if ($linkedActivity && $linkedActivity->id !== $activity->id) {
throw new InvalidArgumentException(
'Sorry, the linked task has already been logged under a different call. '
. 'Please choose another linked task.'
);
}
}
} catch (InvalidArgumentException $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($exception->getMessage());
} catch (Exception $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorInternalError(
'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'
);
}
}
if ($categoryId) {
$category = PlaybookCategory::uuid($categoryId);
if ($category->playbook->team_id !== $team->id) {
throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
$this->logger->info('Prospect data', [
'lead_id' => $lead?->getId(),
'account_id' => $account?->getId(),
'contact_id' => $contact?->getId(),
'opportunity_id' => $opportunity?->getId(),
'stage_id' => $stage?->getId(),
]);
if ($title) {
$activity->title = $title;
}
if ($summary) {
$activity->summary = $summary;
}
if ($crmProviderId) {
$activity->crm_provider_id = $crmProviderId;
}
if ($callStage) {
$this->logger->info('Setting stage id', ['stageId' => $callStage->id]);
$activity->stage_id = $callStage->id;
}
if ($lead) {
$this->logger->info('Setting lead id', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
// If we are changed from an account > lead, unset the account data.
$this->logger->info('Unsetting account id, opportunity id, contact id, value');
$activity->account_id = null;
$activity->opportunity_id = null;
$activity->contact_id = null;
$activity->value = null;
}
if ($account) {
$this->logger->info('Setting account id', ['accountId' => $account->id]);
$activity->account_id = $account->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('unsetting lead id');
$activity->lead_id = null;
// Unset the contact if switching different accounts. Will be set up below if still applicable.
if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {
$this->logger->info('Unsetting contact id');
$activity->contact_id = null;
}
}
if ($opportunity) {
$this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);
$this->logger->info('unsetting lead id');
$activity->opportunity_id = $opportunity->id;
$activity->value = $opportunity->value;
// If we are changed from an lead > account, unset the lead data.
$activity->lead_id = null;
}
if ($contact) {
$this->logger->info('setting contact id', ['contactId' => $contact->id]);
$activity->contact_id = $contact->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('Unsetting lead id');
$activity->lead_id = null;
}
$activity->is_internal = $isInternal;
$activity->save();
$activity->refresh();
$this->logger->notice('Activity saved', [
'activity_id' => $activity->getId(),
'lead_id' => $activity->lead_id,
'account_id' => $activity->account_id,
'contact_id' => $activity->contact_id,
'opportunity_id' => $activity->opportunity_id,
'stage_id' => $activity->stage_id,
'crm_provider_id' => $activity->getCrmProviderId(),
]);
// Store entities as field data on the activity.
$updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);
if ($activity->isLoggable()) {
// Follow-up Task or Event data.
$followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);
$this->logger->info('CRM LOG manual log triggered', [
'activityId' => $activity->getUuid(),
'followupData' => $followupData,
'userId' => $user->getUuid(),
]);
// Store data in the CRM.
// ++add check for crm_required
$job = new SaveActivity($activity, $followupData);
if ($updatedData) {
$job->delay(Carbon::now()->addMinutes($jobDelay));
}
dispatch($job);
// Manually dispatch log for Opportunity or Prospect added
if ($activity->hasOpportunity() || $activity->hasProspect()) {
event(new ActivityProspectAdded(
activity: $activity,
eventSource: 'manually-log-crm-data'
));
}
}
return $this->response->withOk();
}
/**
* Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.
*
* @param ServiceInterface $service
* @param Activity $activity
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array
{
$updatedData = [];
$existingData = $activity->data()->get();
// We need to delete any existing data to overwrite with latest values.
$activity->data()->delete();
$layoutEntities = $layout->entities()
->with('field', 'parent')
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->get();
/** @var LayoutEntity $entity */
foreach ($layoutEntities as $entity) {
// If the user has provided a value for this entity
if (array_key_exists($entity->id_string, $entities)) {
$value = $entities[$entity->id_string];
// Convert raw data into values that the CRM can consume.
if ($value) {
$value = $service->normalizeValue($entity->field->type, $value);
}
// Check the field is part of the activity-summary section.
if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {
// This is the internal database ID, not the external CRM ID.
$objectId = null;
switch ($entity->field->object_type) {
case Field::OBJECT_ACCOUNT:
$objectId = $activity->account_id;
break;
case Field::OBJECT_CONTACT:
$objectId = $activity->contact_id;
break;
case Field::OBJECT_OPPORTUNITY:
$objectId = $activity->opportunity_id;
break;
case Field::OBJECT_LEAD:
$objectId = $activity->lead_id;
break;
case Field::OBJECT_TASK:
case Field::OBJECT_EVENT:
$objectId = $activity->id;
break;
}
if ($objectId) {
/** @var FieldData $data */
$data = $activity->data()->create([
'crm_layout_entity_id' => $entity->id,
'crm_field_id' => $entity->crm_field_id,
'object_type' => $entity->field->object_type,
'object_id' => $objectId,
'value' => $value,
]);
// Never send read-only field data to the CRM.
if ($entity->read_only === false && $entity->is_visible) {
$existingValue = $existingData
->where('crm_layout_entity_id', $entity->id)
->where('crm_field_id', $entity->crm_field_id)
->where('object_type', $entity->field->object_type)
->where('object_id', $objectId)
->first();
// If the field was actually changed, we need to reflect this in the CRM too.
if ($existingValue === null || $existingValue->value !== $value) {
$updatedData[] = $data->id;
}
}
}
}
}
}
return $updatedData;
}
/**
* Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.
*
* @param ServiceInterface $crmService
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array
{
$fieldData = [];
foreach ($entities as $entityId => $value) {
// Only bother with fields that have a value.
if ($value) {
// Extract the entity from the UUID. Check the field is valid and part of the follow-up section.
$entity = $layout->entities()
->uuid($entityId, false)
->whereHas('parent', function ($query) {
$query->where('label', 'follow-up');
})
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->first();
if ($entity) {
// Convert raw data into values that the CRM can consume.
$value = $crmService->normalizeValue($entity->field->type, $value);
// Add the field and value to the payload.
$fieldData += [
$entity->field->crm_provider_id => $value,
];
}
}
}
return $fieldData;
}
/**
* @param Activity $activity
*/
private function validateSummary(Activity $activity): void
{
$team = $activity->user->team;
$crmProvider = $team->crm->provider;
$attributes = [];
$rules = [
'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,
'title' => 'string|max:250',
'prospects' => 'required|array',
'opportunity_id' => new CrmReference($crmProvider),
'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',
'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator
'summary' => 'max:50000',
'nId' => 'exists:notifications,id',
'crm_id' => new CrmReference($crmProvider),
'entities' => 'array',
'is_internal' => 'boolean',
];
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));
// Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.
$entities = $layout->entities()
->where('read_only', 0)
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->whereHas('parent', function ($query) use ($activity) {
if ($activity->isLoggable() === false) {
$query->where('label', '<>', 'follow-up');
}
});
$isInternal = $this->request->input('is_internal', false);
foreach ($entities->get() as $entity) {
$rules += $this->buildFieldValidator($entity, $isInternal);
$attributes += $this->buildFieldMessage($entity);
}
$this->request->validate($rules, [], $attributes);
}
private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array
{
return [
'entities.' . $entity->id_string => $entity->getValidator($isInternal),
];
}
/**
* @param LayoutEntity $entity
*
* @return array
*/
private function buildFieldMessage(LayoutEntity $entity): array
{
$label = $entity->label;
if ($label === null) {
$label = $entity->field->label;
}
return [
'entities.' . $entity->id_string => $label,
];
}
public function search(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->debugLog(
$user,
'User extracted from request',
['user' => $user->getId(), 'tz' => $user->getTimezone()]
);
$searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());
$this->debugLog(
$user,
'ActivitySearch criteria built',
['searchCriteria' => $searchCriteria]
);
$filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);
$this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);
$this->validateSearch($request, $filterSet);
$this->debugLog($user, 'Request validated');
$searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);
/** @var Collection<Activity> $activities */
$activities = $searchResponse['results'];
$this->debugLog($user, 'Activities ES response extracted');
$hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(
$user->getTeamId(),
TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),
);
if ($hideInternalMeetingsSetting?->getValue() === '1') {
$activities = $activities->filter(function (Activity $activity) {
if ($activity->is_internal && empty($activity->actual_start_time)) {
return false;
}
return true;
});
}
$this->debugLog($user, 'Internal meetings (?!) filtered');
$this->response->getManager()
->parseIncludes([
'category',
'organizer.group',
'prospect',
'stage',
'opportunity',
'stats',
'scorecards',
'masterTrack',
'activeParticipants',
'notification',
])
->setSerializer(new JsonSerializer());
$transformerExcludes = $this->request->input('exclude');
if ($transformerExcludes) {
$this->response->getManager()->parseExcludes($transformerExcludes);
}
$this->debugLog($user, 'Response Manager (?!) applied');
$transformer = new ActivityTransformer();
$transformer->setConsumer($user);
$this->debugLog($user, 'Activity Transformer added');
$resource = new \League\Fractal\Resource\Collection($activities, $transformer);
$page = $searchCriteria->getPageNumber();
$this->debugLog($user, 'Search criteria page number called', ['page' => $page]);
$histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');
$this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);
return $this->response->withArray([
'pagination' => [
'total' => $searchResponse['totalHits'],
'current' => $page,
'prev' => max($page - 1, 1),
'next' => $page + 1,
],
'results' => $this->response->getManager()->createData($resource)->toArray(),
'histogram' => $histogram,
]);
}
private function debugLog(User $user, string $logMessage, ?array $context = []): void
{
// Debug for Learning People Only
if ($user->getTeamId() !== 260) {
return;
}
Log::notice(
sprintf('[activity-search-controller] %s', $logMessage),
$context
);
}
/** @throws ValidationException */
private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void
{
$rules = [
'exclude' => 'array',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
];
if ($prefix !== null && mb_strpos($prefix, '.') !== false) {
$rules[rtrim($prefix, '.')] = sprintf(
'required|array|max:%d',
$filterSet->count()
);
}
$validationRules = $filterSet->getValidationRules($prefix)
->merge($rules)
->all();
$request->validate($validationRules);
}
public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$search = $this->updateOrCreateActivitySearch($request);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function updateActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('update', $search);
$this->updateOrCreateActivitySearch($request, $search);
return $this->response->withOk();
}
private function storeNamedSearchFilters(
Collection $request,
Search $search,
FilterDefinitionCollection $filterSet,
?string $prefix = null,
): self {
$arrayTypeProperties = $filterSet
->getPropertyTypes([
FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,
])
->all();
$supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);
foreach ($supportedRequestProperties as $requestPropertyName) {
if (! array_has($request, $requestPropertyName)) {
continue;
}
/** @var string|string[] $propertyValue */
$propertyValue = array_get($request, $requestPropertyName);
$propertyName = $prefix === null
? $requestPropertyName
: mb_substr($requestPropertyName, mb_strlen($prefix));
$isArrayType = array_has($arrayTypeProperties, $propertyName);
if (! $isArrayType) {
/** @var string $requestPropertyValue */
$search->filters()->updateOrCreate(
[
'filter' => $propertyName,
],
[
'value' => $propertyValue,
]
);
continue;
}
/** @var string[] $requestPropertyValue */
/** @var SearchFilter[]|Collection $existingFilterValues */
$existingFilterValuesKeyed = $search->filters()
->where('filter', $propertyName)
->get()
->keyBy('id');
// Iterate over values provided as request parameters
foreach ($propertyValue as $value) {
/** @var SearchFilter|null $valueFilter */
$valueFilter = $search->filters()
->where(
[
'filter' => $propertyName,
'value' => $value,
]
)
->first();
if ($valueFilter !== null) {
// Remove filter value pair from list to be deleted
$existingFilterValuesKeyed->forget($valueFilter->id);
} else {
// Add new filter/value pair
$search->filters()->updateOrCreate([
'filter' => $propertyName,
'value' => $value,
]);
}
}
// Delete filter value pairs for this filter that no longer exist in request parameters
foreach ($existingFilterValuesKeyed as $existingFilter) {
$existingFilter->delete();
}
}
/** @var Collection<int, SearchFilter> $filtersKeyed */
$filtersKeyed = $search->filters()->get()->keyBy('filter');
// wipe removed filters from this search
foreach ($filtersKeyed as $filterName => $filter) {
if (array_has($request, $prefix . $filterName)) {
continue;
}
// Remove all filter values for this filter
$search->filters()->where('filter', $filterName)->delete();
}
return $this;
}
/**
* @throws AuthorizationException
*/
public function fetchActivitySearch(
Search $search,
Request $request,
SearchTransformer $searchTransformer,
): JsonResponse {
$this->authorize('view', $search);
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withCollection(
$user->searches()->get(),
$searchTransformer
->withConsumer($user)
);
}
/**
* Deletes a saved search
*
* @param Request $request
* @param Search $search
*
* @throws Exception
*
* @return JsonResponse
*/
public function deleteActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('delete', $search);
// Orphan any AutomatedReports that use this search
$search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);
// Delete filters and the search itself
$search->filters()->delete();
$search->delete();
return $this->response->withOk();
}
public function live(Request $request, ElasticActivityRepository $repository): JsonResponse
{
$user = $this->getUserFromRequest($request);
$this->request->validate([
'sort_direction' => 'in:asc,desc',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
]);
$activities = $repository->getLiveCoachingEligibleActivities(
user: $user,
lookBackMinutes: self::LOOK_BACK,
limit: (int) $this->request->input('limit', 25),
page: (int) $this->request->input('page', 1),
sortBy: ['actual_start_time', 'scheduled_start_time'],
sortDirection: (string) $this->request->input('sort_direction', 'asc'),
);
$this->response
->getManager()
->parseIncludes(['organizer.group', 'prospect'])
->setSerializer(new JsonSerializer());
return $this->response->withCollection($activities, new ActivityTransformer());
}
/**
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function show(Activity $activity, ActivityService $activityService): JsonResponse
{
$this->authorize('show', $activity);
$user = $activity->getUser();
$team = $user->getTeam();
// Sync the opportunity with the latest data if possible.
if ($activity->opportunity_id) {
try {
$crmService = $this->providerRegistry->get($team->crm->provider);
if (! $user->isCrmRequired()) {
$crmService->setUser($team->getOwner());
} else {
$crmService->setUser($user);
}
$crmService->syncOpportunity($activity->opportunity->crm_provider_id);
} catch (Exception $exception) {
// Move on.
}
}
$activityData = $activityService->getActivityData($this->request->user(), $activity);
return response()->json($activityData);
}
public function createRecording(Activity $activity)
{
$this->authorize('record', $activity);
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Tell Twilio to start recording this activity.
if ($activity->recording_state === Activity::RECORDING_OFF) {
$job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withCreated();
}
return $this->response->errorGone('Activity is already recording.');
}
public function updateRecording(Request $request, Activity $activity)
{
$this->authorize('record', $activity);
$request->validate([
'preference' => 'boolean',
'state' => [
'string',
Rule::in([
Activity::RECORDING_IN_PROGRESS,
Activity::RECORDING_PAUSED,
]),
],
]);
if ($request->has('state')) {
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Toggle the recording state between paused and resumed.
if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {
$job = (new ToggleRecording($activity, $request->input('state')))
->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Recording is not toggleable.');
}
if ($request->has('preference')) {
$activity->update([
'recording_preference' => $request->input('preference') ? 1 : 0,
]);
return $this->response->withOk();
}
return $this->response->errorWrongArgs('Something went wrong');
}
public function stopRecording(Activity $activity)
{
$this->authorize('stopRecord', $activity);
// Tell Twilio to stop recording this activity.
if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {
$job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Activity is not recording.');
}
/**
* Add activity to this user's favorites playlist
*
* @throws AuthorizationException
*/
public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse
{
$this->authorize('favorite', $activity);
$user = $this->getUserFromRequest($this->request);
$favorite = $activity->wasFavoritedBy($user);
$name = $activity->activity_title ?? '';
// It needs to check at least one record.
if (! $favorite) {
$favoritePlaylist = $user->favoritePlaylist();
$playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(
$activity,
$user,
$favoritePlaylist
);
if ($playlistActivity !== null) {
$playlistActivity->update(
// Just update, don't sort.
['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],
);
} else {
$playlistActivity = $activity->playlistActivities()->create([
'playlist_id' => $favoritePlaylist->getId(),
'user_id' => $user->getId(),
'start_time' => 0,
'name' => mb_strimwidth($name, 0, 100),
]);
// Sort it on top.
$playlistActivity->update(
[
'sort' => $playlistActivityRepository->calculateNewSortOrder(
null,
$playlistActivity,
),
],
);
}
$playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);
return new JsonResponse([], JsonResponse::HTTP_CREATED);
}
return new JsonResponse(
[
'error' => [
'code' => AbstractResponse::CODE_CONFLICT,
'http_code' => JsonResponse::HTTP_CONFLICT,
'message' => 'Resource Already Exists',
],
],
JsonResponse::HTTP_CONFLICT,
);
}
/**
* Remove activity from this user's favorites playlist
*
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function unfavorite(Activity $activity)
{
$user = $t...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
32862
|
1255
|
39
|
2026-05-13T09:41:11.936915+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665271936_m2.jpg...
|
PhpStorm
|
faVsco.js – ActivityController.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use Carbon\Carbon;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\In;
use Illuminate\Validation\ValidationException;
use InvalidArgumentException;
use Jiminny\Component\ActivityAnalytics;
use Jiminny\Component\ActivitySearch;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Queue\Constants;
use Jiminny\Contracts\ES\Events\UpdateSingleEntity;
use Jiminny\Contracts\ES\UpdateTargetEnum;
use Jiminny\Contracts\Nudge\NudgeFactoryInterface;
use Jiminny\Contracts\Playlist\PlaylistTrackFactoryInterface;
use Jiminny\Contracts\Repositories\PlaylistActivityRepository;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Enums\TeamSetting;
use Jiminny\Events\Activities\AiAutomation\ActivityProspectAdded;
use Jiminny\Events\Activities\Coaching\Coached;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Controllers\CommentContextInterface;
use Jiminny\Http\Responses\Api\AbstractResponse;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\ActivityCommentTransformer;
use Jiminny\Http\Transformers\ActivityTopicTriggerTransformer;
use Jiminny\Http\Transformers\ActivityTransformer;
use Jiminny\Http\Transformers\AvailabilityNotificationTransformer;
use Jiminny\Http\Transformers\CoachingFeedbackTransformer;
use Jiminny\Http\Transformers\CoachingSectionsTransformer;
use Jiminny\Http\Transformers\SearchTransformer;
use Jiminny\Http\Transformers\StatsTransformer;
use Jiminny\Jobs\Crm\SaveActivity;
use Jiminny\Jobs\Crm\UpdateStage;
use Jiminny\Jobs\Telephony\StartRecording;
use Jiminny\Jobs\Telephony\StopRecording;
use Jiminny\Jobs\Telephony\ToggleRecording;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\CoachingFeedback;
use Jiminny\Models\CoachingSection;
use Jiminny\Models\CoachingSectionCriterion;
use Jiminny\Models\CoachingSectionFeedback;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\LanguageDialect;
use Jiminny\Models\Lead;
use Jiminny\Models\Nudge;
use Jiminny\Models\PlaybookCategory;
use Jiminny\Models\Playlist;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\Track;
use Jiminny\Models\User;
use Jiminny\Repositories\CoachingFeedbackRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Rules\CrmReference;
use Jiminny\Rules\MultidimensionalArrayMaxCharRule;
use Jiminny\Services\ActivityService;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Services\PlaybackService;
use Jiminny\Services\UserService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
use Ramsey\Uuid\Uuid;
use Sentry;
use Symfony\Component\HttpFoundation;
final class ActivityController extends Controller implements CommentContextInterface
{
// Number of minutes to look back on activities. i.e. a timeout on activity duration.
private const int LOOK_BACK = 180;
public function __construct(
private ProviderRegistry $providerRegistry,
private ActivityService $activityService,
Response $response,
private UserService $userService,
private ActivitySearch\Service\ActivitySearch $activitySearch,
private NudgeFactoryInterface $nudgeFactory,
private ActivityCommentService $activityCommentService,
private LoggerInterface $logger,
private readonly CoachingFeedbackRepository $coachingFeedbackRepository,
private readonly TeamRepository $teamRepository,
) {
parent::__construct($response);
}
public static function getCommentImplementation(): string
{
return Comment::class;
}
public function delete()
{
$this->request->validate([
'*' => 'uuid:activities',
]);
$deletedIds = [];
foreach ($this->request->all() as $activityId) {
$activity = Activity::idOrUuId($activityId);
try {
if ($this->authorize('delete', $activity)) {
$activity->delete();
$deletedIds[] = $activityId;
\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);
}
} catch (AuthorizationException $authorizationException) {
// They didn't have permission.
}
}
return $this->response->withArray($deletedIds);
}
public function update(Request $request, Activity $activity)
{
$this->authorize('updateMetadata', $activity);
$request->validate([
'title' => 'string|max:250',
'category_id' => 'uuid:playbook_categories',
'language' => [
new In(
LanguageDialect::query()
->with('language')
->cursor()
->map(static function (LanguageDialect $languageDialect): string {
return $languageDialect->getLanguageLocale();
})
->all()
),
],
]);
if ($request->has('title')) {
$activity->title = $request->input('title');
}
if ($request->has('category_id')) {
$category = PlaybookCategory::uuid($request->input('category_id'));
if ($category->playbook->team_id !== $request->user()->team_id) {
return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
if ($request->has('language')) {
if (! $activity->isInProgress()) {
return $this->response->withError(
'Activity language can only be set while the meeting is in progress.',
400
);
}
$activity->setLanguageCode($request->input('language'));
}
$activity->save();
return $this->response->withOk();
}
// XXX: This should be merged with the update method.
/**
* @param Activity $activity
*
* @throws AuthorizationException
* @throws SocialAccountTokenInvalidException
*
* @return mixed
*/
public function summarize(Activity $activity): mixed
{
$this->logger->info('[Log Activity] Summarizing activity ', [
'activityId' => $activity->getUuid(),
'payload' => $this->request->all(),
]);
$this->authorize('update', $activity);
$this->logger->info('[Log Activity] Validating summary');
// Validate the payload.
$this->validateSummary($activity);
// All objects must belong to this team.
/** @var User $user */
$user = $this->request->user();
$team = $user->getTeam();
$crmService = $this->providerRegistry->get($team->crm->provider);
try {
$crmUser = $user;
if ($user->isCrmRequired() === false) {
$crmUser = $team->owner;
}
$crmService->setUser($crmUser);
} catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());
}
$rawEntities = $this->request->input('entities');
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid(
$this->request->input('layout_id')
);
// Delay execution of CRM jobs to avoid locking issues.
$jobDelay = 0;
// If we have arrived from a notification, mark it as read.
$notificationId = $this->request->input('nId');
if ($notificationId) {
$notification = $user->unreadNotifications->where('id', $notificationId)->first();
if ($notification) {
$notification->markAsRead();
}
}
$title = $this->request->input('title');
$prospects = $this->request->input('prospects');
$opportunityId = $this->request->input('opportunity_id');
$stageId = $this->request->input('stage_id');
$categoryId = $this->request->input('category_id');
$summary = $this->request->input('summary');
$crmProviderId = $this->request->input('crm_id');
$isInternal = $this->request->input('is_internal') ?? false;
$lead = null;
$category = null;
$account = null;
$contact = null;
$opportunity = null;
$stage = null;
$callStage = null;
foreach ($prospects as $prospectData) {
$objectId = $prospectData['id'];
if ($objectId === null) {
continue;
}
$objectType = $prospectData['type'];
$this->logger->info('debug', ['prospect_data' => $prospectData]);
try {
if ($objectType === null) {
$this->logger->info('no object type');
if ($crmService instanceof SupportsObjectTypeParseInterface) {
$objectType = $crmService->parseObjectType($objectId);
}
}
switch ($objectType) {
case 'lead':
$this->logger->info('Processing lead');
/** @var Lead|null $lead */
$lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();
// Lead does not exist locally, import it.
if ($lead === null) {
$this->logger->info('Lead does not exist locally');
/** @var Lead $lead */
$lead = $crmService->syncLead($objectId);
}
$this->logger->info('Lead found', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
if ($stageId === null) {
$this->logger->info('Stage ID is null');
// If it was not provided, just assume it is the current stage.
$callStage = $lead->stage;
break;
}
$this->logger->info('Looking for stage');
// Determine if they have changed the stage.
/** @var Stage $stage */
$stage = $team->crm->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_LEAD)
->firstOrFail();
$this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);
if ($lead->stage_id && $lead->stage_id !== $stage->id) {
$this->logger->info('Stage has changed');
// Storage current stage on activity.
$callStage = $lead->stage;
// The stage has changed, update in remote CRM.
dispatch(new UpdateStage($activity, $lead, $callStage, $stage));
$this->logger->info(
sprintf(
'[%s] User changing lead stage from %s to %s',
$crmService->getDisplayName(),
$callStage->getName(),
$stage->getName()
),
[
'user' => $user->getUuid(),
'lead' => $lead->getUuid(),
]
);
} else {
$this->logger->info('Stage has not changed');
// Stage remains as current.
$callStage = $stage;
}
break;
case 'account':
$this->logger->info('Processing account');
// If the object is not a lead, it should be an account.
$account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();
// Account does not exist locally, import it.
if ($account === null) {
$this->logger->info('Account does not exist locally');
$account = $crmService->syncAccount($objectId);
}
$this->logger->info('Account found', ['accountId' => $account->id]);
break;
case 'contact':
$this->logger->info('processing contact');
$contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$this->logger->info('contact does not exist locally');
$contact = $crmService->syncContact($objectId);
}
$this->logger->info('resolving account');
$account = $this->resolveAccount($team, $contact, $crmService, $prospects);
break;
}
// If they have specified an opportunity, retrieve this with stage.
if ($opportunityId) {
$this->logger->info('opportunity id is set');
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if ($opportunity === null) {
$this->logger->info('opportunity does not exist locally');
$opportunity = $crmService->syncOpportunity($opportunityId);
}
if ($stageId === null) {
$this->logger->info('stage id is null');
// If it was not provided, just assume it is the current stage.
$callStage = $opportunity->stage ?? null;
} else {
$this->logger->info('looking for stage');
/** @var ?Stage $opportunityStage */
$opportunityStage = $team->crm
->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
// There is a chance we still cannot import this opportunity.
if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {
$this->logger->info('opportunity stage has changed');
// Storage current stage on activity.
$callStage = $opportunity->stage;
dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));
$this->logger->info(
sprintf(
'[%s] User changing opportunity stage from %s to %s',
$crmService->getDisplayName(),
$callStage->name,
$opportunityStage->name
),
[
'userId' => $user->id_string,
'opportunityId' => $opportunity->id_string,
]
);
} else {
$this->logger->info('opportunity stage has not changed');
// Stage remains as current.
$callStage = $opportunityStage;
}
}
}
if ($crmProviderId) {
// Cast $crmProviderId to string otherwise it won't use database index for some records
$linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();
// Check if this activity has already been assigned to a different activity.
if ($linkedActivity && $linkedActivity->id !== $activity->id) {
throw new InvalidArgumentException(
'Sorry, the linked task has already been logged under a different call. '
. 'Please choose another linked task.'
);
}
}
} catch (InvalidArgumentException $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($exception->getMessage());
} catch (Exception $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorInternalError(
'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'
);
}
}
if ($categoryId) {
$category = PlaybookCategory::uuid($categoryId);
if ($category->playbook->team_id !== $team->id) {
throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
$this->logger->info('Prospect data', [
'lead_id' => $lead?->getId(),
'account_id' => $account?->getId(),
'contact_id' => $contact?->getId(),
'opportunity_id' => $opportunity?->getId(),
'stage_id' => $stage?->getId(),
]);
if ($title) {
$activity->title = $title;
}
if ($summary) {
$activity->summary = $summary;
}
if ($crmProviderId) {
$activity->crm_provider_id = $crmProviderId;
}
if ($callStage) {
$this->logger->info('Setting stage id', ['stageId' => $callStage->id]);
$activity->stage_id = $callStage->id;
}
if ($lead) {
$this->logger->info('Setting lead id', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
// If we are changed from an account > lead, unset the account data.
$this->logger->info('Unsetting account id, opportunity id, contact id, value');
$activity->account_id = null;
$activity->opportunity_id = null;
$activity->contact_id = null;
$activity->value = null;
}
if ($account) {
$this->logger->info('Setting account id', ['accountId' => $account->id]);
$activity->account_id = $account->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('unsetting lead id');
$activity->lead_id = null;
// Unset the contact if switching different accounts. Will be set up below if still applicable.
if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {
$this->logger->info('Unsetting contact id');
$activity->contact_id = null;
}
}
if ($opportunity) {
$this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);
$this->logger->info('unsetting lead id');
$activity->opportunity_id = $opportunity->id;
$activity->value = $opportunity->value;
// If we are changed from an lead > account, unset the lead data.
$activity->lead_id = null;
}
if ($contact) {
$this->logger->info('setting contact id', ['contactId' => $contact->id]);
$activity->contact_id = $contact->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('Unsetting lead id');
$activity->lead_id = null;
}
$activity->is_internal = $isInternal;
$activity->save();
$activity->refresh();
$this->logger->notice('Activity saved', [
'activity_id' => $activity->getId(),
'lead_id' => $activity->lead_id,
'account_id' => $activity->account_id,
'contact_id' => $activity->contact_id,
'opportunity_id' => $activity->opportunity_id,
'stage_id' => $activity->stage_id,
'crm_provider_id' => $activity->getCrmProviderId(),
]);
// Store entities as field data on the activity.
$updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);
if ($activity->isLoggable()) {
// Follow-up Task or Event data.
$followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);
$this->logger->info('CRM LOG manual log triggered', [
'activityId' => $activity->getUuid(),
'followupData' => $followupData,
'userId' => $user->getUuid(),
]);
// Store data in the CRM.
// ++add check for crm_required
$job = new SaveActivity($activity, $followupData);
if ($updatedData) {
$job->delay(Carbon::now()->addMinutes($jobDelay));
}
dispatch($job);
// Manually dispatch log for Opportunity or Prospect added
if ($activity->hasOpportunity() || $activity->hasProspect()) {
event(new ActivityProspectAdded(
activity: $activity,
eventSource: 'manually-log-crm-data'
));
}
}
return $this->response->withOk();
}
/**
* Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.
*
* @param ServiceInterface $service
* @param Activity $activity
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array
{
$updatedData = [];
$existingData = $activity->data()->get();
// We need to delete any existing data to overwrite with latest values.
$activity->data()->delete();
$layoutEntities = $layout->entities()
->with('field', 'parent')
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->get();
/** @var LayoutEntity $entity */
foreach ($layoutEntities as $entity) {
// If the user has provided a value for this entity
if (array_key_exists($entity->id_string, $entities)) {
$value = $entities[$entity->id_string];
// Convert raw data into values that the CRM can consume.
if ($value) {
$value = $service->normalizeValue($entity->field->type, $value);
}
// Check the field is part of the activity-summary section.
if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {
// This is the internal database ID, not the external CRM ID.
$objectId = null;
switch ($entity->field->object_type) {
case Field::OBJECT_ACCOUNT:
$objectId = $activity->account_id;
break;
case Field::OBJECT_CONTACT:
$objectId = $activity->contact_id;
break;
case Field::OBJECT_OPPORTUNITY:
$objectId = $activity->opportunity_id;
break;
case Field::OBJECT_LEAD:
$objectId = $activity->lead_id;
break;
case Field::OBJECT_TASK:
case Field::OBJECT_EVENT:
$objectId = $activity->id;
break;
}
if ($objectId) {
/** @var FieldData $data */
$data = $activity->data()->create([
'crm_layout_entity_id' => $entity->id,
'crm_field_id' => $entity->crm_field_id,
'object_type' => $entity->field->object_type,
'object_id' => $objectId,
'value' => $value,
]);
// Never send read-only field data to the CRM.
if ($entity->read_only === false && $entity->is_visible) {
$existingValue = $existingData
->where('crm_layout_entity_id', $entity->id)
->where('crm_field_id', $entity->crm_field_id)
->where('object_type', $entity->field->object_type)
->where('object_id', $objectId)
->first();
// If the field was actually changed, we need to reflect this in the CRM too.
if ($existingValue === null || $existingValue->value !== $value) {
$updatedData[] = $data->id;
}
}
}
}
}
}
return $updatedData;
}
/**
* Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.
*
* @param ServiceInterface $crmService
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array
{
$fieldData = [];
foreach ($entities as $entityId => $value) {
// Only bother with fields that have a value.
if ($value) {
// Extract the entity from the UUID. Check the field is valid and part of the follow-up section.
$entity = $layout->entities()
->uuid($entityId, false)
->whereHas('parent', function ($query) {
$query->where('label', 'follow-up');
})
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->first();
if ($entity) {
// Convert raw data into values that the CRM can consume.
$value = $crmService->normalizeValue($entity->field->type, $value);
// Add the field and value to the payload.
$fieldData += [
$entity->field->crm_provider_id => $value,
];
}
}
}
return $fieldData;
}
/**
* @param Activity $activity
*/
private function validateSummary(Activity $activity): void
{
$team = $activity->user->team;
$crmProvider = $team->crm->provider;
$attributes = [];
$rules = [
'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,
'title' => 'string|max:250',
'prospects' => 'required|array',
'opportunity_id' => new CrmReference($crmProvider),
'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',
'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator
'summary' => 'max:50000',
'nId' => 'exists:notifications,id',
'crm_id' => new CrmReference($crmProvider),
'entities' => 'array',
'is_internal' => 'boolean',
];
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));
// Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.
$entities = $layout->entities()
->where('read_only', 0)
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->whereHas('parent', function ($query) use ($activity) {
if ($activity->isLoggable() === false) {
$query->where('label', '<>', 'follow-up');
}
});
$isInternal = $this->request->input('is_internal', false);
foreach ($entities->get() as $entity) {
$rules += $this->buildFieldValidator($entity, $isInternal);
$attributes += $this->buildFieldMessage($entity);
}
$this->request->validate($rules, [], $attributes);
}
private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array
{
return [
'entities.' . $entity->id_string => $entity->getValidator($isInternal),
];
}
/**
* @param LayoutEntity $entity
*
* @return array
*/
private function buildFieldMessage(LayoutEntity $entity): array
{
$label = $entity->label;
if ($label === null) {
$label = $entity->field->label;
}
return [
'entities.' . $entity->id_string => $label,
];
}
public function search(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->debugLog(
$user,
'User extracted from request',
['user' => $user->getId(), 'tz' => $user->getTimezone()]
);
$searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());
$this->debugLog(
$user,
'ActivitySearch criteria built',
['searchCriteria' => $searchCriteria]
);
$filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);
$this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);
$this->validateSearch($request, $filterSet);
$this->debugLog($user, 'Request validated');
$searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);
/** @var Collection<Activity> $activities */
$activities = $searchResponse['results'];
$this->debugLog($user, 'Activities ES response extracted');
$hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(
$user->getTeamId(),
TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),
);
if ($hideInternalMeetingsSetting?->getValue() === '1') {
$activities = $activities->filter(function (Activity $activity) {
if ($activity->is_internal && empty($activity->actual_start_time)) {
return false;
}
return true;
});
}
$this->debugLog($user, 'Internal meetings (?!) filtered');
$this->response->getManager()
->parseIncludes([
'category',
'organizer.group',
'prospect',
'stage',
'opportunity',
'stats',
'scorecards',
'masterTrack',
'activeParticipants',
'notification',
])
->setSerializer(new JsonSerializer());
$transformerExcludes = $this->request->input('exclude');
if ($transformerExcludes) {
$this->response->getManager()->parseExcludes($transformerExcludes);
}
$this->debugLog($user, 'Response Manager (?!) applied');
$transformer = new ActivityTransformer();
$transformer->setConsumer($user);
$this->debugLog($user, 'Activity Transformer added');
$resource = new \League\Fractal\Resource\Collection($activities, $transformer);
$page = $searchCriteria->getPageNumber();
$this->debugLog($user, 'Search criteria page number called', ['page' => $page]);
$histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');
$this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);
return $this->response->withArray([
'pagination' => [
'total' => $searchResponse['totalHits'],
'current' => $page,
'prev' => max($page - 1, 1),
'next' => $page + 1,
],
'results' => $this->response->getManager()->createData($resource)->toArray(),
'histogram' => $histogram,
]);
}
private function debugLog(User $user, string $logMessage, ?array $context = []): void
{
// Debug for Learning People Only
if ($user->getTeamId() !== 260) {
return;
}
Log::notice(
sprintf('[activity-search-controller] %s', $logMessage),
$context
);
}
/** @throws ValidationException */
private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void
{
$rules = [
'exclude' => 'array',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
];
if ($prefix !== null && mb_strpos($prefix, '.') !== false) {
$rules[rtrim($prefix, '.')] = sprintf(
'required|array|max:%d',
$filterSet->count()
);
}
$validationRules = $filterSet->getValidationRules($prefix)
->merge($rules)
->all();
$request->validate($validationRules);
}
public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$search = $this->updateOrCreateActivitySearch($request);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function updateActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('update', $search);
$this->updateOrCreateActivitySearch($request, $search);
return $this->response->withOk();
}
private function storeNamedSearchFilters(
Collection $request,
Search $search,
FilterDefinitionCollection $filterSet,
?string $prefix = null,
): self {
$arrayTypeProperties = $filterSet
->getPropertyTypes([
FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,
])
->all();
$supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);
foreach ($supportedRequestProperties as $requestPropertyName) {
if (! array_has($request, $requestPropertyName)) {
continue;
}
/** @var string|string[] $propertyValue */
$propertyValue = array_get($request, $requestPropertyName);
$propertyName = $prefix === null
? $requestPropertyName
: mb_substr($requestPropertyName, mb_strlen($prefix));
$isArrayType = array_has($arrayTypeProperties, $propertyName);
if (! $isArrayType) {
/** @var string $requestPropertyValue */
$search->filters()->updateOrCreate(
[
'filter' => $propertyName,
],
[
'value' => $propertyValue,
]
);
continue;
}
/** @var string[] $requestPropertyValue */
/** @var SearchFilter[]|Collection $existingFilterValues */
$existingFilterValuesKeyed = $search->filters()
->where('filter', $propertyName)
->get()
->keyBy('id');
// Iterate over values provided as request parameters
foreach ($propertyValue as $value) {
/** @var SearchFilter|null $valueFilter */
$valueFilter = $search->filters()
->where(
[
'filter' => $propertyName,
'value' => $value,
]
)
->first();
if ($valueFilter !== null) {
// Remove filter value pair from list to be deleted
$existingFilterValuesKeyed->forget($valueFilter->id);
} else {
// Add new filter/value pair
$search->filters()->updateOrCreate([
'filter' => $propertyName,
'value' => $value,
]);
}
}
// Delete filter value pairs for this filter that no longer exist in request parameters
foreach ($existingFilterValuesKeyed as $existingFilter) {
$existingFilter->delete();
}
}
/** @var Collection<int, SearchFilter> $filtersKeyed */
$filtersKeyed = $search->filters()->get()->keyBy('filter');
// wipe removed filters from this search
foreach ($filtersKeyed as $filterName => $filter) {
if (array_has($request, $prefix . $filterName)) {
continue;
}
// Remove all filter values for this filter
$search->filters()->where('filter', $filterName)->delete();
}
return $this;
}
/**
* @throws AuthorizationException
*/
public function fetchActivitySearch(
Search $search,
Request $request,
SearchTransformer $searchTransformer,
): JsonResponse {
$this->authorize('view', $search);
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withCollection(
$user->searches()->get(),
$searchTransformer
->withConsumer($user)
);
}
/**
* Deletes a saved search
*
* @param Request $request
* @param Search $search
*
* @throws Exception
*
* @return JsonResponse
*/
public function deleteActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('delete', $search);
// Orphan any AutomatedReports that use this search
$search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);
// Delete filters and the search itself
$search->filters()->delete();
$search->delete();
return $this->response->withOk();
}
public function live(Request $request, ElasticActivityRepository $repository): JsonResponse
{
$user = $this->getUserFromRequest($request);
$this->request->validate([
'sort_direction' => 'in:asc,desc',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
]);
$activities = $repository->getLiveCoachingEligibleActivities(
user: $user,
lookBackMinutes: self::LOOK_BACK,
limit: (int) $this->request->input('limit', 25),
page: (int) $this->request->input('page', 1),
sortBy: ['actual_start_time', 'scheduled_start_time'],
sortDirection: (string) $this->request->input('sort_direction', 'asc'),
);
$this->response
->getManager()
->parseIncludes(['organizer.group', 'prospect'])
->setSerializer(new JsonSerializer());
return $this->response->withCollection($activities, new ActivityTransformer());
}
/**
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function show(Activity $activity, ActivityService $activityService): JsonResponse
{
$this->authorize('show', $activity);
$user = $activity->getUser();
$team = $user->getTeam();
// Sync the opportunity with the latest data if possible.
if ($activity->opportunity_id) {
try {
$crmService = $this->providerRegistry->get($team->crm->provider);
if (! $user->isCrmRequired()) {
$crmService->setUser($team->getOwner());
} else {
$crmService->setUser($user);
}
$crmService->syncOpportunity($activity->opportunity->crm_provider_id);
} catch (Exception $exception) {
// Move on.
}
}
$activityData = $activityService->getActivityData($this->request->user(), $activity);
return response()->json($activityData);
}
public function createRecording(Activity $activity)
{
$this->authorize('record', $activity);
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Tell Twilio to start recording this activity.
if ($activity->recording_state === Activity::RECORDING_OFF) {
$job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withCreated();
}
return $this->response->errorGone('Activity is already recording.');
}
public function updateRecording(Request $request, Activity $activity)
{
$this->authorize('record', $activity);
$request->validate([
'preference' => 'boolean',
'state' => [
'string',
Rule::in([
Activity::RECORDING_IN_PROGRESS,
Activity::RECORDING_PAUSED,
]),
],
]);
if ($request->has('state')) {
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Toggle the recording state between paused and resumed.
if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {
$job = (new ToggleRecording($activity, $request->input('state')))
->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Recording is not toggleable.');
}
if ($request->has('preference')) {
$activity->update([
'recording_preference' => $request->input('preference') ? 1 : 0,
]);
return $this->response->withOk();
}
return $this->response->errorWrongArgs('Something went wrong');
}
public function stopRecording(Activity $activity)
{
$this->authorize('stopRecord', $activity);
// Tell Twilio to stop recording this activity.
if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {
$job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Activity is not recording.');
}
/**
* Add activity to this user's favorites playlist
*
* @throws AuthorizationException
*/
public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse
{
$this->authorize('favorite', $activity);
$user = $this->getUserFromRequest($this->request);
$favorite = $activity->wasFavoritedBy($user);
$name = $activity->activity_title ?? '';
// It needs to check at least one record.
if (! $favorite) {
$favoritePlaylist = $user->favoritePlaylist();
$playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(
$activity,
$user,
$favoritePlaylist
);
if ($playlistActivity !== null) {
$playlistActivity->update(
// Just update, don't sort.
['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],
);
} else {
$playlistActivity = $activity->playlistActivities()->create([
'playlist_id' => $favoritePlaylist->getId(),
'user_id' => $user->getId(),
'start_time' => 0,
'name' => mb_strimwidth($name, 0, 100),
]);
// Sort it on top.
$playlistActivity->update(
[
'sort' => $playlistActivityRepository->calculateNewSortOrder(
null,
$playlistActivity,
),
],
);
}
$playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);
return new JsonResponse([], JsonResponse::HTTP_CREATED);
}
return new JsonResponse(
[
'error' => [
'code' => AbstractResponse::CODE_CONFLICT,
'http_code' => JsonResponse::HTTP_CONFLICT,
'message' => 'Resource Already Exists',
],
],
JsonResponse::HTTP_CONFLICT,
);
}
/**
* Remove activity from this user's favorites playlist
*
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function unfavorite(Activity $activity)
{
$user = $t...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.034242023,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Analyzing…","depth":4,"bounds":{"left":0.37200797,"top":0.07581804,"width":0.019946808,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.39361703,"top":0.074221864,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.40093085,"top":0.074221864,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Http\\Controllers\\API;\n\nuse Carbon\\Carbon;\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Exception;\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Validation\\Rule;\nuse Illuminate\\Validation\\Rules\\In;\nuse Illuminate\\Validation\\ValidationException;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ActivityAnalytics;\nuse Jiminny\\Component\\ActivitySearch;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Contracts\\ES\\Events\\UpdateSingleEntity;\nuse Jiminny\\Contracts\\ES\\UpdateTargetEnum;\nuse Jiminny\\Contracts\\Nudge\\NudgeFactoryInterface;\nuse Jiminny\\Contracts\\Playlist\\PlaylistTrackFactoryInterface;\nuse Jiminny\\Contracts\\Repositories\\PlaylistActivityRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Enums\\TeamSetting;\nuse Jiminny\\Events\\Activities\\AiAutomation\\ActivityProspectAdded;\nuse Jiminny\\Events\\Activities\\Coaching\\Coached;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Controllers\\CommentContextInterface;\nuse Jiminny\\Http\\Responses\\Api\\AbstractResponse;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\ActivityCommentTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTopicTriggerTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTransformer;\nuse Jiminny\\Http\\Transformers\\AvailabilityNotificationTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingFeedbackTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingSectionsTransformer;\nuse Jiminny\\Http\\Transformers\\SearchTransformer;\nuse Jiminny\\Http\\Transformers\\StatsTransformer;\nuse Jiminny\\Jobs\\Crm\\SaveActivity;\nuse Jiminny\\Jobs\\Crm\\UpdateStage;\nuse Jiminny\\Jobs\\Telephony\\StartRecording;\nuse Jiminny\\Jobs\\Telephony\\StopRecording;\nuse Jiminny\\Jobs\\Telephony\\ToggleRecording;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\CoachingFeedback;\nuse Jiminny\\Models\\CoachingSection;\nuse Jiminny\\Models\\CoachingSectionCriterion;\nuse Jiminny\\Models\\CoachingSectionFeedback;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\LanguageDialect;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Nudge;\nuse Jiminny\\Models\\PlaybookCategory;\nuse Jiminny\\Models\\Playlist;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\Track;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\CoachingFeedbackRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Rules\\MultidimensionalArrayMaxCharRule;\nuse Jiminny\\Services\\ActivityService;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Services\\PlaybackService;\nuse Jiminny\\Services\\UserService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\nuse Ramsey\\Uuid\\Uuid;\nuse Sentry;\nuse Symfony\\Component\\HttpFoundation;\n\nfinal class ActivityController extends Controller implements CommentContextInterface\n{\n // Number of minutes to look back on activities. i.e. a timeout on activity duration.\n private const int LOOK_BACK = 180;\n\n public function __construct(\n private ProviderRegistry $providerRegistry,\n private ActivityService $activityService,\n Response $response,\n private UserService $userService,\n private ActivitySearch\\Service\\ActivitySearch $activitySearch,\n private NudgeFactoryInterface $nudgeFactory,\n private ActivityCommentService $activityCommentService,\n private LoggerInterface $logger,\n private readonly CoachingFeedbackRepository $coachingFeedbackRepository,\n private readonly TeamRepository $teamRepository,\n ) {\n parent::__construct($response);\n }\n\n public static function getCommentImplementation(): string\n {\n return Comment::class;\n }\n\n public function delete()\n {\n $this->request->validate([\n '*' => 'uuid:activities',\n ]);\n\n $deletedIds = [];\n foreach ($this->request->all() as $activityId) {\n $activity = Activity::idOrUuId($activityId);\n\n try {\n if ($this->authorize('delete', $activity)) {\n $activity->delete();\n $deletedIds[] = $activityId;\n\n \\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n }\n } catch (AuthorizationException $authorizationException) {\n // They didn't have permission.\n }\n }\n\n return $this->response->withArray($deletedIds);\n }\n\n public function update(Request $request, Activity $activity)\n {\n $this->authorize('updateMetadata', $activity);\n\n $request->validate([\n 'title' => 'string|max:250',\n 'category_id' => 'uuid:playbook_categories',\n 'language' => [\n new In(\n LanguageDialect::query()\n ->with('language')\n ->cursor()\n ->map(static function (LanguageDialect $languageDialect): string {\n return $languageDialect->getLanguageLocale();\n })\n ->all()\n ),\n ],\n ]);\n\n if ($request->has('title')) {\n $activity->title = $request->input('title');\n }\n\n if ($request->has('category_id')) {\n $category = PlaybookCategory::uuid($request->input('category_id'));\n\n if ($category->playbook->team_id !== $request->user()->team_id) {\n return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n if ($request->has('language')) {\n if (! $activity->isInProgress()) {\n return $this->response->withError(\n 'Activity language can only be set while the meeting is in progress.',\n 400\n );\n }\n\n $activity->setLanguageCode($request->input('language'));\n }\n\n $activity->save();\n\n return $this->response->withOk();\n }\n\n // XXX: This should be merged with the update method.\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws SocialAccountTokenInvalidException\n *\n * @return mixed\n */\n public function summarize(Activity $activity): mixed\n {\n $this->logger->info('[Log Activity] Summarizing activity ', [\n 'activityId' => $activity->getUuid(),\n 'payload' => $this->request->all(),\n ]);\n $this->authorize('update', $activity);\n\n $this->logger->info('[Log Activity] Validating summary');\n // Validate the payload.\n $this->validateSummary($activity);\n\n // All objects must belong to this team.\n /** @var User $user */\n $user = $this->request->user();\n $team = $user->getTeam();\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n try {\n $crmUser = $user;\n if ($user->isCrmRequired() === false) {\n $crmUser = $team->owner;\n }\n $crmService->setUser($crmUser);\n } catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());\n }\n\n $rawEntities = $this->request->input('entities');\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid(\n $this->request->input('layout_id')\n );\n\n // Delay execution of CRM jobs to avoid locking issues.\n $jobDelay = 0;\n\n // If we have arrived from a notification, mark it as read.\n $notificationId = $this->request->input('nId');\n if ($notificationId) {\n $notification = $user->unreadNotifications->where('id', $notificationId)->first();\n\n if ($notification) {\n $notification->markAsRead();\n }\n }\n\n $title = $this->request->input('title');\n $prospects = $this->request->input('prospects');\n $opportunityId = $this->request->input('opportunity_id');\n $stageId = $this->request->input('stage_id');\n $categoryId = $this->request->input('category_id');\n $summary = $this->request->input('summary');\n $crmProviderId = $this->request->input('crm_id');\n $isInternal = $this->request->input('is_internal') ?? false;\n\n $lead = null;\n $category = null;\n $account = null;\n $contact = null;\n $opportunity = null;\n $stage = null;\n $callStage = null;\n\n foreach ($prospects as $prospectData) {\n $objectId = $prospectData['id'];\n\n if ($objectId === null) {\n continue;\n }\n\n $objectType = $prospectData['type'];\n $this->logger->info('debug', ['prospect_data' => $prospectData]);\n\n try {\n if ($objectType === null) {\n $this->logger->info('no object type');\n if ($crmService instanceof SupportsObjectTypeParseInterface) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n }\n\n switch ($objectType) {\n case 'lead':\n $this->logger->info('Processing lead');\n /** @var Lead|null $lead */\n $lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();\n\n // Lead does not exist locally, import it.\n if ($lead === null) {\n $this->logger->info('Lead does not exist locally');\n /** @var Lead $lead */\n $lead = $crmService->syncLead($objectId);\n }\n\n $this->logger->info('Lead found', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n if ($stageId === null) {\n $this->logger->info('Stage ID is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $lead->stage;\n\n break;\n }\n\n $this->logger->info('Looking for stage');\n // Determine if they have changed the stage.\n /** @var Stage $stage */\n $stage = $team->crm->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_LEAD)\n ->firstOrFail();\n\n $this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);\n if ($lead->stage_id && $lead->stage_id !== $stage->id) {\n $this->logger->info('Stage has changed');\n // Storage current stage on activity.\n $callStage = $lead->stage;\n\n // The stage has changed, update in remote CRM.\n dispatch(new UpdateStage($activity, $lead, $callStage, $stage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing lead stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->getName(),\n $stage->getName()\n ),\n [\n 'user' => $user->getUuid(),\n 'lead' => $lead->getUuid(),\n ]\n );\n } else {\n $this->logger->info('Stage has not changed');\n // Stage remains as current.\n $callStage = $stage;\n }\n\n break;\n\n case 'account':\n $this->logger->info('Processing account');\n // If the object is not a lead, it should be an account.\n $account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();\n\n // Account does not exist locally, import it.\n if ($account === null) {\n $this->logger->info('Account does not exist locally');\n $account = $crmService->syncAccount($objectId);\n }\n\n $this->logger->info('Account found', ['accountId' => $account->id]);\n\n break;\n case 'contact':\n $this->logger->info('processing contact');\n $contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $this->logger->info('contact does not exist locally');\n $contact = $crmService->syncContact($objectId);\n }\n\n $this->logger->info('resolving account');\n $account = $this->resolveAccount($team, $contact, $crmService, $prospects);\n\n break;\n }\n\n // If they have specified an opportunity, retrieve this with stage.\n if ($opportunityId) {\n $this->logger->info('opportunity id is set');\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if ($opportunity === null) {\n $this->logger->info('opportunity does not exist locally');\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n if ($stageId === null) {\n $this->logger->info('stage id is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $opportunity->stage ?? null;\n } else {\n $this->logger->info('looking for stage');\n /** @var ?Stage $opportunityStage */\n $opportunityStage = $team->crm\n ->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n // There is a chance we still cannot import this opportunity.\n if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {\n $this->logger->info('opportunity stage has changed');\n // Storage current stage on activity.\n $callStage = $opportunity->stage;\n\n dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing opportunity stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->name,\n $opportunityStage->name\n ),\n [\n 'userId' => $user->id_string,\n 'opportunityId' => $opportunity->id_string,\n ]\n );\n } else {\n $this->logger->info('opportunity stage has not changed');\n // Stage remains as current.\n $callStage = $opportunityStage;\n }\n }\n }\n\n if ($crmProviderId) {\n // Cast $crmProviderId to string otherwise it won't use database index for some records\n $linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();\n\n // Check if this activity has already been assigned to a different activity.\n if ($linkedActivity && $linkedActivity->id !== $activity->id) {\n throw new InvalidArgumentException(\n 'Sorry, the linked task has already been logged under a different call. '\n . 'Please choose another linked task.'\n );\n }\n }\n } catch (InvalidArgumentException $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($exception->getMessage());\n } catch (Exception $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorInternalError(\n 'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'\n );\n }\n }\n\n if ($categoryId) {\n $category = PlaybookCategory::uuid($categoryId);\n\n if ($category->playbook->team_id !== $team->id) {\n throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n $this->logger->info('Prospect data', [\n 'lead_id' => $lead?->getId(),\n 'account_id' => $account?->getId(),\n 'contact_id' => $contact?->getId(),\n 'opportunity_id' => $opportunity?->getId(),\n 'stage_id' => $stage?->getId(),\n ]);\n\n if ($title) {\n $activity->title = $title;\n }\n\n if ($summary) {\n $activity->summary = $summary;\n }\n\n if ($crmProviderId) {\n $activity->crm_provider_id = $crmProviderId;\n }\n\n if ($callStage) {\n $this->logger->info('Setting stage id', ['stageId' => $callStage->id]);\n $activity->stage_id = $callStage->id;\n }\n\n if ($lead) {\n $this->logger->info('Setting lead id', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n // If we are changed from an account > lead, unset the account data.\n $this->logger->info('Unsetting account id, opportunity id, contact id, value');\n $activity->account_id = null;\n $activity->opportunity_id = null;\n $activity->contact_id = null;\n $activity->value = null;\n }\n\n if ($account) {\n $this->logger->info('Setting account id', ['accountId' => $account->id]);\n $activity->account_id = $account->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('unsetting lead id');\n $activity->lead_id = null;\n\n // Unset the contact if switching different accounts. Will be set up below if still applicable.\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {\n $this->logger->info('Unsetting contact id');\n $activity->contact_id = null;\n }\n }\n\n if ($opportunity) {\n $this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);\n $this->logger->info('unsetting lead id');\n $activity->opportunity_id = $opportunity->id;\n $activity->value = $opportunity->value;\n\n // If we are changed from an lead > account, unset the lead data.\n $activity->lead_id = null;\n }\n\n if ($contact) {\n $this->logger->info('setting contact id', ['contactId' => $contact->id]);\n $activity->contact_id = $contact->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('Unsetting lead id');\n $activity->lead_id = null;\n }\n\n $activity->is_internal = $isInternal;\n $activity->save();\n $activity->refresh();\n\n $this->logger->notice('Activity saved', [\n 'activity_id' => $activity->getId(),\n 'lead_id' => $activity->lead_id,\n 'account_id' => $activity->account_id,\n 'contact_id' => $activity->contact_id,\n 'opportunity_id' => $activity->opportunity_id,\n 'stage_id' => $activity->stage_id,\n 'crm_provider_id' => $activity->getCrmProviderId(),\n ]);\n\n // Store entities as field data on the activity.\n $updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);\n\n if ($activity->isLoggable()) {\n // Follow-up Task or Event data.\n $followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);\n\n $this->logger->info('CRM LOG manual log triggered', [\n 'activityId' => $activity->getUuid(),\n 'followupData' => $followupData,\n 'userId' => $user->getUuid(),\n ]);\n\n // Store data in the CRM.\n // ++add check for crm_required\n $job = new SaveActivity($activity, $followupData);\n\n if ($updatedData) {\n $job->delay(Carbon::now()->addMinutes($jobDelay));\n }\n\n dispatch($job);\n\n // Manually dispatch log for Opportunity or Prospect added\n if ($activity->hasOpportunity() || $activity->hasProspect()) {\n event(new ActivityProspectAdded(\n activity: $activity,\n eventSource: 'manually-log-crm-data'\n ));\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.\n *\n * @param ServiceInterface $service\n * @param Activity $activity\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array\n {\n $updatedData = [];\n $existingData = $activity->data()->get();\n\n // We need to delete any existing data to overwrite with latest values.\n $activity->data()->delete();\n\n $layoutEntities = $layout->entities()\n ->with('field', 'parent')\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->get();\n\n /** @var LayoutEntity $entity */\n foreach ($layoutEntities as $entity) {\n // If the user has provided a value for this entity\n if (array_key_exists($entity->id_string, $entities)) {\n $value = $entities[$entity->id_string];\n\n // Convert raw data into values that the CRM can consume.\n if ($value) {\n $value = $service->normalizeValue($entity->field->type, $value);\n }\n\n // Check the field is part of the activity-summary section.\n if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {\n // This is the internal database ID, not the external CRM ID.\n $objectId = null;\n\n switch ($entity->field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $objectId = $activity->account_id;\n\n break;\n\n case Field::OBJECT_CONTACT:\n $objectId = $activity->contact_id;\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n $objectId = $activity->opportunity_id;\n\n break;\n\n case Field::OBJECT_LEAD:\n $objectId = $activity->lead_id;\n\n break;\n\n case Field::OBJECT_TASK:\n case Field::OBJECT_EVENT:\n $objectId = $activity->id;\n\n break;\n }\n\n if ($objectId) {\n /** @var FieldData $data */\n $data = $activity->data()->create([\n 'crm_layout_entity_id' => $entity->id,\n 'crm_field_id' => $entity->crm_field_id,\n 'object_type' => $entity->field->object_type,\n 'object_id' => $objectId,\n 'value' => $value,\n ]);\n\n // Never send read-only field data to the CRM.\n if ($entity->read_only === false && $entity->is_visible) {\n $existingValue = $existingData\n ->where('crm_layout_entity_id', $entity->id)\n ->where('crm_field_id', $entity->crm_field_id)\n ->where('object_type', $entity->field->object_type)\n ->where('object_id', $objectId)\n ->first();\n\n // If the field was actually changed, we need to reflect this in the CRM too.\n if ($existingValue === null || $existingValue->value !== $value) {\n $updatedData[] = $data->id;\n }\n }\n }\n }\n }\n }\n\n return $updatedData;\n }\n\n /**\n * Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.\n *\n * @param ServiceInterface $crmService\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array\n {\n $fieldData = [];\n foreach ($entities as $entityId => $value) {\n // Only bother with fields that have a value.\n if ($value) {\n // Extract the entity from the UUID. Check the field is valid and part of the follow-up section.\n $entity = $layout->entities()\n ->uuid($entityId, false)\n ->whereHas('parent', function ($query) {\n $query->where('label', 'follow-up');\n })\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->first();\n\n if ($entity) {\n // Convert raw data into values that the CRM can consume.\n $value = $crmService->normalizeValue($entity->field->type, $value);\n\n // Add the field and value to the payload.\n $fieldData += [\n $entity->field->crm_provider_id => $value,\n ];\n }\n }\n }\n\n return $fieldData;\n }\n\n /**\n * @param Activity $activity\n */\n private function validateSummary(Activity $activity): void\n {\n $team = $activity->user->team;\n $crmProvider = $team->crm->provider;\n $attributes = [];\n\n $rules = [\n 'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,\n 'title' => 'string|max:250',\n 'prospects' => 'required|array',\n 'opportunity_id' => new CrmReference($crmProvider),\n 'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',\n 'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator\n 'summary' => 'max:50000',\n 'nId' => 'exists:notifications,id',\n 'crm_id' => new CrmReference($crmProvider),\n 'entities' => 'array',\n 'is_internal' => 'boolean',\n ];\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));\n\n // Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.\n $entities = $layout->entities()\n ->where('read_only', 0)\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->whereHas('parent', function ($query) use ($activity) {\n if ($activity->isLoggable() === false) {\n $query->where('label', '<>', 'follow-up');\n }\n });\n\n $isInternal = $this->request->input('is_internal', false);\n\n foreach ($entities->get() as $entity) {\n $rules += $this->buildFieldValidator($entity, $isInternal);\n $attributes += $this->buildFieldMessage($entity);\n }\n\n $this->request->validate($rules, [], $attributes);\n }\n\n private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array\n {\n return [\n 'entities.' . $entity->id_string => $entity->getValidator($isInternal),\n ];\n }\n\n /**\n * @param LayoutEntity $entity\n *\n * @return array\n */\n private function buildFieldMessage(LayoutEntity $entity): array\n {\n $label = $entity->label;\n if ($label === null) {\n $label = $entity->field->label;\n }\n\n return [\n 'entities.' . $entity->id_string => $label,\n ];\n }\n\n public function search(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->debugLog(\n $user,\n 'User extracted from request',\n ['user' => $user->getId(), 'tz' => $user->getTimezone()]\n );\n\n $searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());\n\n $this->debugLog(\n $user,\n 'ActivitySearch criteria built',\n ['searchCriteria' => $searchCriteria]\n );\n\n $filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);\n\n $this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);\n\n $this->validateSearch($request, $filterSet);\n\n $this->debugLog($user, 'Request validated');\n\n $searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);\n\n /** @var Collection<Activity> $activities */\n $activities = $searchResponse['results'];\n\n $this->debugLog($user, 'Activities ES response extracted');\n\n $hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(\n $user->getTeamId(),\n TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),\n );\n\n if ($hideInternalMeetingsSetting?->getValue() === '1') {\n $activities = $activities->filter(function (Activity $activity) {\n if ($activity->is_internal && empty($activity->actual_start_time)) {\n return false;\n }\n\n return true;\n });\n }\n\n $this->debugLog($user, 'Internal meetings (?!) filtered');\n\n $this->response->getManager()\n ->parseIncludes([\n 'category',\n 'organizer.group',\n 'prospect',\n 'stage',\n 'opportunity',\n 'stats',\n 'scorecards',\n 'masterTrack',\n 'activeParticipants',\n 'notification',\n ])\n ->setSerializer(new JsonSerializer());\n\n $transformerExcludes = $this->request->input('exclude');\n if ($transformerExcludes) {\n $this->response->getManager()->parseExcludes($transformerExcludes);\n }\n\n $this->debugLog($user, 'Response Manager (?!) applied');\n\n $transformer = new ActivityTransformer();\n $transformer->setConsumer($user);\n\n $this->debugLog($user, 'Activity Transformer added');\n\n $resource = new \\League\\Fractal\\Resource\\Collection($activities, $transformer);\n $page = $searchCriteria->getPageNumber();\n\n $this->debugLog($user, 'Search criteria page number called', ['page' => $page]);\n\n $histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');\n\n $this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);\n\n return $this->response->withArray([\n 'pagination' => [\n 'total' => $searchResponse['totalHits'],\n 'current' => $page,\n 'prev' => max($page - 1, 1),\n 'next' => $page + 1,\n ],\n 'results' => $this->response->getManager()->createData($resource)->toArray(),\n 'histogram' => $histogram,\n ]);\n }\n\n private function debugLog(User $user, string $logMessage, ?array $context = []): void\n {\n // Debug for Learning People Only\n if ($user->getTeamId() !== 260) {\n return;\n }\n\n Log::notice(\n sprintf('[activity-search-controller] %s', $logMessage),\n $context\n );\n }\n\n /** @throws ValidationException */\n private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void\n {\n $rules = [\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ];\n\n if ($prefix !== null && mb_strpos($prefix, '.') !== false) {\n $rules[rtrim($prefix, '.')] = sprintf(\n 'required|array|max:%d',\n $filterSet->count()\n );\n }\n\n $validationRules = $filterSet->getValidationRules($prefix)\n ->merge($rules)\n ->all();\n\n $request->validate($validationRules);\n }\n\n public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $search = $this->updateOrCreateActivitySearch($request);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function updateActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('update', $search);\n\n $this->updateOrCreateActivitySearch($request, $search);\n\n return $this->response->withOk();\n }\n\n private function storeNamedSearchFilters(\n Collection $request,\n Search $search,\n FilterDefinitionCollection $filterSet,\n ?string $prefix = null,\n ): self {\n $arrayTypeProperties = $filterSet\n ->getPropertyTypes([\n FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,\n ])\n ->all();\n\n $supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);\n\n foreach ($supportedRequestProperties as $requestPropertyName) {\n if (! array_has($request, $requestPropertyName)) {\n continue;\n }\n\n /** @var string|string[] $propertyValue */\n $propertyValue = array_get($request, $requestPropertyName);\n $propertyName = $prefix === null\n ? $requestPropertyName\n : mb_substr($requestPropertyName, mb_strlen($prefix));\n\n $isArrayType = array_has($arrayTypeProperties, $propertyName);\n\n if (! $isArrayType) {\n /** @var string $requestPropertyValue */\n\n $search->filters()->updateOrCreate(\n [\n 'filter' => $propertyName,\n ],\n [\n 'value' => $propertyValue,\n ]\n );\n\n continue;\n }\n\n /** @var string[] $requestPropertyValue */\n\n /** @var SearchFilter[]|Collection $existingFilterValues */\n $existingFilterValuesKeyed = $search->filters()\n ->where('filter', $propertyName)\n ->get()\n ->keyBy('id');\n\n // Iterate over values provided as request parameters\n foreach ($propertyValue as $value) {\n /** @var SearchFilter|null $valueFilter */\n $valueFilter = $search->filters()\n ->where(\n [\n 'filter' => $propertyName,\n 'value' => $value,\n ]\n )\n ->first();\n\n if ($valueFilter !== null) {\n // Remove filter value pair from list to be deleted\n $existingFilterValuesKeyed->forget($valueFilter->id);\n } else {\n // Add new filter/value pair\n $search->filters()->updateOrCreate([\n 'filter' => $propertyName,\n 'value' => $value,\n ]);\n }\n }\n\n // Delete filter value pairs for this filter that no longer exist in request parameters\n foreach ($existingFilterValuesKeyed as $existingFilter) {\n $existingFilter->delete();\n }\n }\n\n /** @var Collection<int, SearchFilter> $filtersKeyed */\n $filtersKeyed = $search->filters()->get()->keyBy('filter');\n\n // wipe removed filters from this search\n foreach ($filtersKeyed as $filterName => $filter) {\n if (array_has($request, $prefix . $filterName)) {\n continue;\n }\n\n // Remove all filter values for this filter\n $search->filters()->where('filter', $filterName)->delete();\n }\n\n return $this;\n }\n\n /**\n * @throws AuthorizationException\n */\n public function fetchActivitySearch(\n Search $search,\n Request $request,\n SearchTransformer $searchTransformer,\n ): JsonResponse {\n $this->authorize('view', $search);\n\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection(\n $user->searches()->get(),\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n /**\n * Deletes a saved search\n *\n * @param Request $request\n * @param Search $search\n *\n * @throws Exception\n *\n * @return JsonResponse\n */\n public function deleteActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('delete', $search);\n\n // Orphan any AutomatedReports that use this search\n $search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);\n\n // Delete filters and the search itself\n $search->filters()->delete();\n $search->delete();\n\n return $this->response->withOk();\n }\n\n public function live(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n $user = $this->getUserFromRequest($request);\n\n $this->request->validate([\n 'sort_direction' => 'in:asc,desc',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ]);\n\n $activities = $repository->getLiveCoachingEligibleActivities(\n user: $user,\n lookBackMinutes: self::LOOK_BACK,\n limit: (int) $this->request->input('limit', 25),\n page: (int) $this->request->input('page', 1),\n sortBy: ['actual_start_time', 'scheduled_start_time'],\n sortDirection: (string) $this->request->input('sort_direction', 'asc'),\n );\n\n $this->response\n ->getManager()\n ->parseIncludes(['organizer.group', 'prospect'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($activities, new ActivityTransformer());\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function show(Activity $activity, ActivityService $activityService): JsonResponse\n {\n $this->authorize('show', $activity);\n\n $user = $activity->getUser();\n $team = $user->getTeam();\n\n // Sync the opportunity with the latest data if possible.\n if ($activity->opportunity_id) {\n try {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n if (! $user->isCrmRequired()) {\n $crmService->setUser($team->getOwner());\n } else {\n $crmService->setUser($user);\n }\n\n $crmService->syncOpportunity($activity->opportunity->crm_provider_id);\n } catch (Exception $exception) {\n // Move on.\n }\n }\n\n $activityData = $activityService->getActivityData($this->request->user(), $activity);\n\n return response()->json($activityData);\n }\n\n public function createRecording(Activity $activity)\n {\n $this->authorize('record', $activity);\n\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Tell Twilio to start recording this activity.\n if ($activity->recording_state === Activity::RECORDING_OFF) {\n $job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withCreated();\n }\n\n return $this->response->errorGone('Activity is already recording.');\n }\n\n public function updateRecording(Request $request, Activity $activity)\n {\n $this->authorize('record', $activity);\n\n $request->validate([\n 'preference' => 'boolean',\n 'state' => [\n 'string',\n Rule::in([\n Activity::RECORDING_IN_PROGRESS,\n Activity::RECORDING_PAUSED,\n ]),\n ],\n ]);\n\n if ($request->has('state')) {\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Toggle the recording state between paused and resumed.\n if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {\n $job = (new ToggleRecording($activity, $request->input('state')))\n ->onQueue(Constants::QUEUE_CONFERENCES);\n\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Recording is not toggleable.');\n }\n\n if ($request->has('preference')) {\n $activity->update([\n 'recording_preference' => $request->input('preference') ? 1 : 0,\n ]);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorWrongArgs('Something went wrong');\n }\n\n public function stopRecording(Activity $activity)\n {\n $this->authorize('stopRecord', $activity);\n\n // Tell Twilio to stop recording this activity.\n if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {\n $job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Activity is not recording.');\n }\n\n /**\n * Add activity to this user's favorites playlist\n *\n * @throws AuthorizationException\n */\n public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse\n {\n $this->authorize('favorite', $activity);\n\n $user = $this->getUserFromRequest($this->request);\n $favorite = $activity->wasFavoritedBy($user);\n $name = $activity->activity_title ?? '';\n\n // It needs to check at least one record.\n if (! $favorite) {\n $favoritePlaylist = $user->favoritePlaylist();\n\n $playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(\n $activity,\n $user,\n $favoritePlaylist\n );\n\n if ($playlistActivity !== null) {\n $playlistActivity->update(\n // Just update, don't sort.\n ['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],\n );\n } else {\n $playlistActivity = $activity->playlistActivities()->create([\n 'playlist_id' => $favoritePlaylist->getId(),\n 'user_id' => $user->getId(),\n 'start_time' => 0,\n 'name' => mb_strimwidth($name, 0, 100),\n ]);\n // Sort it on top.\n $playlistActivity->update(\n [\n 'sort' => $playlistActivityRepository->calculateNewSortOrder(\n null,\n $playlistActivity,\n ),\n ],\n );\n }\n\n $playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);\n\n return new JsonResponse([], JsonResponse::HTTP_CREATED);\n }\n\n return new JsonResponse(\n [\n 'error' => [\n 'code' => AbstractResponse::CODE_CONFLICT,\n 'http_code' => JsonResponse::HTTP_CONFLICT,\n 'message' => 'Resource Already Exists',\n ],\n ],\n JsonResponse::HTTP_CONFLICT,\n );\n }\n\n /**\n * Remove activity from this user's favorites playlist\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unfavorite(Activity $activity)\n {\n $user = $this->request->user();\n\n $favorites = $activity->favoritedBy($user);\n\n if ($favorites && $favorites->isEmpty()) {\n return $this->response->errorNotFound('Favorite not found.');\n }\n\n $this->authorize('unfavorite', [$activity, $favorites]);\n\n // When you unfavorite an activity,\n // it should remove all the activities in it, including snippets.\n $isDeleted = $favorites->each(function ($favorite) {\n $favorite->forceDelete();\n });\n\n if ($isDeleted) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not remove favorite.');\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function notify(Activity $activity)\n {\n $this->authorize('notify', $activity);\n\n $user = $this->request->user();\n\n $existingNotification = $activity->availabilityNotifications()\n ->where('user_id', $user->id)\n ->exists();\n\n if ($existingNotification) {\n return $this->response->errorWrongArgs('Notification is already configured.');\n }\n\n $notification = Activity\\AvailabilityNotification::create([\n 'user_id' => $user->id,\n 'activity_id' => $activity->id,\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($notification, new AvailabilityNotificationTransformer());\n }\n\n /**\n * @param Activity $activity\n * @param Activity\\AvailabilityNotification $notification\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unnotify(Activity $activity, Activity\\AvailabilityNotification $notification)\n {\n $this->authorize('unnotify', [$activity, $notification]);\n\n if ($notification->sent_at || $notification->delete()) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not delete notification.');\n }\n\n public function play(Request $request, Activity $activity)\n {\n $this->authorize('stream', $activity);\n\n $request->validate([\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $activity->plays()->create([\n 'user_id' => $user->getId(),\n 'start_time' => $request->input('start_time'),\n ]);\n\n return $this->response->withCreated();\n }\n\n /**\n * @param Activity $activity\n *\n * @return mixed\n */\n public function comment(Activity $activity)\n {\n return $this->newComment($activity);\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @return mixed\n */\n public function replyComment(Activity $activity, Comment $comment)\n {\n return $this->newComment($activity, $comment);\n }\n\n /**\n * @param Activity $activity\n * @param Comment|null $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n protected function newComment(Activity $activity, ?Comment $comment = null)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n 'type' => 'integer|between:0,3',\n 'visibility' => sprintf('nullable|integer|between:1,%d', count(Comment::getVisibilityLevels())),\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n $threadStartId = null;\n if ($comment) {\n $threadStartId = $comment->thread_start_id ?: $comment->id;\n }\n\n try {\n $newComment = Comment::create([\n 'parent_comment_id' => $comment->id ?? null,\n 'thread_start_id' => $threadStartId,\n 'activity_id' => $activity->id,\n 'user_id' => $this->request->user()->id,\n 'comment' => trim($this->request->input('comment')),\n 'start_time' => $this->request->input('start_time', 0),\n 'end_time' => $this->request->input('end_time', 0),\n 'type' => $this->request->input('type', Comment::TYPE_NEUTRAL),\n 'visibility' => $this->request->input('visibility', Comment::VISIBILITY_PUBLIC),\n ]);\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($newComment, new ActivityCommentTransformer());\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not create comment.' . $exception->getMessage());\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function updateComment(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n try {\n $comment->update([\n 'comment' => trim($this->request->input('comment')),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment.');\n }\n }\n\n public function updateCommentVisibility(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'visibility' => sprintf('integer|between:1,%d', count(Comment::getVisibilityLevels())),\n ]);\n\n $visibility = $this->request->input('visibility');\n\n if ($comment->parent !== null) {\n return $this->response->errorWrongArgs('Comment visibility can only be updated on top level comments.');\n }\n\n try {\n $this->activityCommentService->updateCommentVisibility($comment, $visibility);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment\\'s visibility.');\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function deleteComment(Activity $activity, Comment $comment)\n {\n $this->authorize('deleteComment', [$activity, $comment]);\n\n // Delete comment and any children.\n $comment->delete();\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function fetchComments()\n {\n $user = $this->request->user();\n $this->request->validate([\n 'forUserId' => 'uuid:users,team_id,' . $user->team_id,\n 'types' => 'array',\n 'types.*' => 'integer|between:0,3',\n ]);\n $forUser = null;\n\n $types = [Comment::TYPE_NEUTRAL, Comment::TYPE_GAME_CHANGER, Comment::TYPE_POSITIVE];\n $user = $this->request->user();\n if ($this->request->has('forUserId')) {\n $forUser = $user->team->users()->uuid($this->request->input('forUserId'));\n }\n\n $comments = Comment::query()\n ->whereHas('activity', static function (Builder $builder) use ($user, $forUser): void {\n $builder\n // I left feedback on my own activity; or\n ->where('activities.user_id', $user->getId());\n if ($forUser) {\n // I left feedback on any activity for this user.\n $builder->orWhere([\n 'user_id' => $user->getId(),\n 'activities.user_id' => $forUser->getId(),\n ]);\n }\n })\n ->whereIn('type', $this->request->input('types', $types))\n ->orderBy('created_at', 'desc')\n ->get();\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity', 'user'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($comments, new ActivityCommentTransformer());\n }\n\n public function deleteCoachingFeedback(Activity $activity, CoachingFeedback $coachingFeedback)\n {\n $this->authorize('deleteCoachingFeedback', [$activity, $coachingFeedback]);\n $activity = $coachingFeedback->getActivity();\n\n if ($coachingFeedback->delete()) {\n event(new UpdateSingleEntity(\n entityId: $activity->getId(),\n updateTarget: UpdateTargetEnum::ACTIVITY,\n purpose: 'delete-coaching-feedback',\n ));\n\n return $this->response->withOk();\n }\n\n return $this->response->withError('Delete operation failed. Contact support.', 500);\n }\n\n /**\n * Add new or update Coaching feedback\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws \\Illuminate\\Validation\\ValidationException\n *\n * @return mixed\n */\n public function putCoachingFeedback(Request $request, Activity $activity)\n {\n $user = $request->user();\n\n if (! $user instanceof User) {\n abort(403);\n }\n $teamId = $user->getTeamId();\n\n $this->authorize('coach', $activity);\n\n $this->request->validate([\n 'coach_id' => 'required|uuid:users,team_id,' . $teamId,\n 'coachee_id' => 'required|uuid:users,team_id,' . $teamId,\n 'visibility' => ['required', Rule::in(CoachingFeedback::VISIBILITIES)],\n 'coaching_sections.*.uuid' => 'required|uuid:coaching_sections',\n 'coaching_sections.*.score' => ['required', Rule::in(CoachingSectionFeedback::SCORES)],\n 'coaching_sections.*.summary' => 'string|max:10000',\n 'coaching_sections.*.criteria.*.uuid' => 'required|uuid:coaching_section_criteria',\n 'coaching_sections.*.criteria.*.note' => 'required|string|max:10000',\n 'sharedWithUsers' => [\n 'required_if:visibility,' . CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS,\n 'array',\n ],\n 'sharedWithUsers.*' => [\n 'uuid:users,team_id,' . $teamId,\n ],\n ]);\n\n /** @var User $coach */\n $coach = User::uuid($this->request->input('coach_id'));\n /** @var User $coachee */\n $coachee = User::uuid($this->request->input('coachee_id'));\n $coachingSectionFeedbacks = $this->request->input('coaching_sections');\n\n $previousRecord = $this->coachingFeedbackRepository->getOneForActivityByCoacheeAndCoach(\n $coachee->getId(),\n $coach->getId(),\n $activity->getId()\n );\n $recordIsNew = false;\n if ($previousRecord === null) {\n $recordIsNew = true;\n }\n\n if (! $coachee->isSameTeamId($coach)) {\n return $this->response->errorForbidden('User not member of your team.');\n }\n\n if (! is_array($coachingSectionFeedbacks) || count($coachingSectionFeedbacks) < 1) {\n return $this->response->withError('At least one Coaching Framework Section shall be scored.', 422);\n }\n\n if (! $activity->participants()->where('participants.user_id', $coachee->id)->exists()) {\n return $this->response->withError('Coached user did not participate activity.', 422);\n }\n\n $visibility = $this->request->input('visibility');\n\n $shouldSendNotification = $recordIsNew;\n if ($recordIsNew === false && $visibility !== $previousRecord->getVisibility()) {\n $shouldSendNotification = true;\n }\n\n /**\n * Create CoachingFeedback\n *\n * @var CoachingFeedback $coachingFeedback\n */\n $coachingFeedback = $activity->coachingFeedbacks()->updateOrCreate(\n [\n 'coach_id' => $coach->id,\n 'coachee_id' => $coachee->id,\n ],\n [\n 'framework_id' => $activity->category->id,\n 'visibility' => $visibility,\n ]\n );\n\n $sharedUserIds = [];\n if ($visibility === CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS) {\n foreach ($this->request->input('sharedWithUsers') as $sharedWithUserUuid) {\n /** @var User $user */\n $user = User::uuid($sharedWithUserUuid);\n $sharedUserIds[] = $user->getId();\n }\n }\n\n $syncResult = $coachingFeedback->customAccessUsers()->sync($sharedUserIds);\n\n $scores = [];\n\n\n /**\n * Create CoachingSectionsFeedbacks.\n *\n * @var CoachingSectionFeedback $coachingSectionFeedback\n */\n foreach ($coachingSectionFeedbacks as $coachingSectionFeedbackInput) {\n $coachingSection = CoachingSection::uuid($coachingSectionFeedbackInput['uuid']);\n $coachingSectionFeedback = $coachingFeedback->sectionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_id' => $coachingSection->id,\n ],\n [\n 'score' => array_get($coachingSectionFeedbackInput, 'score'),\n 'summary' => array_get($coachingSectionFeedbackInput, 'summary') ?? '',\n ]\n );\n\n $scores[] = array_get($coachingSectionFeedbackInput, 'score');\n\n $criteria = array_get($coachingSectionFeedbackInput, 'criteria');\n if (is_array($criteria) && ! empty($criteria)) {\n foreach ($criteria as $criteriaFeedbackInput) {\n $coachingSectionFeedback->criterionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_criterion_id' => CoachingSectionCriterion::uuid(array_get($criteriaFeedbackInput, 'uuid'))\n ->id,\n ],\n ['note' => array_get($criteriaFeedbackInput, 'note')],\n );\n }\n }\n }\n\n $coachingFeedback->average_score = array_sum($scores) / count($scores);\n\n if ($recordIsNew === false && $coachingFeedback->getAverageScore() !== $previousRecord->getAverageScore()) {\n $shouldSendNotification = true;\n }\n if (! empty($syncResult['attached']) || ! empty($syncResult['detached']) || ! empty($syncResult['updated'])) {\n $shouldSendNotification = true;\n }\n\n $coachingFeedback->save();\n // ensure updated at for coaching feedback on section feedback summary added.\n $coachingFeedback->touch();\n\n if ($shouldSendNotification) {\n event(new Coached($coachingFeedback));\n }\n\n Datadog::increment('jiminny.activity.score.update', 1, ['company' => $activity->user->team->slug]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n $coachingFeedbackTransformer = new CoachingFeedbackTransformer();\n $coachingFeedbackTransformer->setConsumer($this->getUserFromRequest($request));\n\n return $this->response->withItem($coachingFeedback, $coachingFeedbackTransformer);\n }\n\n\n /**\n * Retrieve category criteria for coaching.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachingSections(Activity $activity)\n {\n $this->authorize('coach', $activity);\n\n if ($activity->category === null) {\n return $this->response->errorUnprocessable('Category has not yet been assigned.');\n }\n\n $criteria = $activity\n ->category\n ->coachingSections()\n ->where('is_enabled', 1)\n ->orderBy('sequence', 'asc');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($criteria->get(), new CoachingSectionsTransformer());\n }\n\n /**\n * @throws AuthorizationException\n * @throws ValidationException\n *\n * @return mixed\n */\n public function addToPlaylist(Activity $activity, PlaylistTrackFactoryInterface $playlistTrackFactory)\n {\n $this->request->validate([\n 'playlists' => 'required|array',\n 'playlists.*' => 'uuid:playlists',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'name' => 'required|max:100',\n ]);\n\n $this->authorize('addToPlaylist', [$activity, $this->request->input('playlists')]);\n\n $startTime = $this->request->input('start_time');\n $endTime = $this->request->input('end_time');\n $name = $this->request->input('name');\n /** @var User $user */\n $user = $this->request->user();\n\n // Get playlist by uuid.\n foreach ($this->request->input('playlists') as $playlistId) {\n // Pull out the playlist model.\n $playlist = Playlist::uuid($playlistId);\n\n $playlistTrackFactory->createTrack($playlist, $user, [\n 'name' => $name,\n 'activity' => $activity,\n 'start_time' => $startTime,\n 'end_time' => $endTime,\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function share(Request $request, Activity $activity): JsonResponse\n {\n $this->authorize('share', $activity);\n\n $request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'recipients.*.type' => 'in:user,group',\n 'recipients.*.id' => 'string|max:40',\n 'share' => 'string|max:255',\n ]);\n\n $user = $request->user();\n\n $recipients = $request->get('recipients');\n $users = $this->userService->convertRecipientsToUsers($user, $recipients);\n\n $shareData = [\n 'from_user_id' => $user->id,\n 'note' => $request->input('note'),\n 'start_time' => $request->input('start_time'),\n 'end_time' => $request->input('end_time'),\n ];\n\n // Create a share object against a notification provider channel\n if ($request->input('share')) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'notification_provider_channel' => $request->input('share'),\n ]\n )\n );\n\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n\n // Create a share object against each recipient\n foreach ($users as $recipient) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'to_user_id' => $recipient->id,\n ]\n )\n );\n\n // If parent_share_id has been selected yet\n if (! isset($shareData['parent_share_id'])) {\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachRequest(Activity $activity)\n {\n $this->authorize('coachRequest', $activity);\n\n $this->request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'coachers.*.type' => 'required|in:user',\n 'coachers.*.id' => 'required',\n ]);\n\n $coachers = $this->request->get('coachers');\n $user = $this->request->user();\n $users = $this->userService->convertRecipientsToUsers($user, $coachers);\n\n foreach ($users as $coacher) {\n CoachRequest::create([\n 'user_id' => $coacher->id,\n 'activity_id' => $activity->id,\n 'note' => $this->request->get('note'),\n 'start_time' => $this->request->get('start_time'),\n 'end_time' => $this->request->get('end_time'),\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function createActivityTopicTriggers(Activity $activity, LoggerInterface $logger): HttpFoundation\\JsonResponse\n {\n $this->authorize('analyzeTopicTriggers', $activity);\n\n if (! $activity->hasTranscription()) {\n return new HttpFoundation\\JsonResponse(\n [\n 'error' => 'Transcription not found.',\n ],\n JsonResponse::HTTP_NOT_FOUND\n );\n }\n\n $logger->info(__METHOD__ . ': queued for analysis', [\n 'activity' => $activity->id_string,\n ]);\n\n dispatch(new ActivityAnalytics\\Job\\AnalyzeActivityTopicTriggers($activity));\n\n return new HttpFoundation\\JsonResponse(null, JsonResponse::HTTP_CREATED);\n }\n\n public function fetchActivityTopicTriggers(\n Activity $activity,\n LoggerInterface $logger,\n ActivityTopicTriggerTransformer $transformer\n ): HttpFoundation\\JsonResponse {\n $this->authorize('fetchTopicTriggers', $activity);\n\n $logger->debug(__METHOD__, [\n 'activity' => $activity->id_string,\n ]);\n\n if (! $activity->isProcessed()) {\n return new HttpFoundation\\JsonResponse([]);\n }\n\n $payload = [];\n\n if ($activity->hasTopicTriggers()) {\n $payload = $activity->getTopicTriggersSorted()\n ->map(\n static fn (Activity\\TopicTrigger $activityTopicTrigger): array\n => $transformer->transform($activityTopicTrigger)\n )\n ->values()\n ->all();\n }\n\n return new HttpFoundation\\JsonResponse($payload);\n }\n\n /**\n * @param Activity $activity\n * @param StatsTransformer $statsTransformer\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function stats(Activity $activity, StatsTransformer $statsTransformer)\n {\n $this->authorize('stream', $activity);\n\n if (! $activity->hasTranscription()) {\n return $this->response->errorNotFound('Waveform data is not yet generated.');\n }\n\n $this->response\n ->getManager()\n ->parseIncludes(['wavedata'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($activity, $statsTransformer);\n }\n\n public function destroy(Activity $activity)\n {\n $this->authorize('delete', $activity);\n\n $activity->delete();\n\n \\Log::info('Soft delete activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n\n return $this->response->withNoContent();\n }\n\n public function note(Activity $activity)\n {\n $this->authorize('note', $activity);\n\n $this->request->validate([\n 'note' => 'required|min:1|max:2000',\n 'time' => 'required|numeric|min:0|max:86400',\n ]);\n\n $note = $this->request->input('note');\n $time = $this->request->input('time');\n\n $this->activityService->setActivity($activity);\n $this->activityService->takeNote($this->getUser(), $note, $time);\n\n return $this->response->withCreated();\n }\n\n /**\n * Mark an activity as private.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPrivate(Activity $activity)\n {\n $this->authorize('markAsPrivate', $activity);\n\n if ($activity->is_private === false) {\n $activity->is_private = true;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * Mark an activity as public.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPublic(Activity $activity)\n {\n $this->authorize('markAsPublic', $activity);\n\n if ($activity->is_private) {\n $activity->is_private = false;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws LogicException\n */\n public function fetchCloudFrontS3MediaKeys(Activity $activity, PlaybackService $playbackService): JsonResponse\n {\n $masterTrack = $activity->masterTrack()->first();\n\n if (! $masterTrack instanceof Track) {\n throw new LogicException(sprintf('Master track not found for activity \"%s\"', $activity->getUuid()));\n }\n\n return $this->response->withArray(\n $playbackService->generateCookies(\n $masterTrack,\n $this->request->ip(),\n ),\n );\n }\n\n /**\n * @throws ValidationException\n */\n private function updateOrCreateActivitySearch(Request $request, ?Search $search = null): Search\n {\n $request->validate([\n 'name' => 'required|string|min:2|max:100',\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $searchName = $request->input('name');\n\n if ($search !== null) {\n $search->update([\n 'name' => $searchName,\n ]);\n\n return $search;\n }\n\n $request->validate([\n 'filters' => ['required', 'array', new MultidimensionalArrayMaxCharRule(limit: 255)],\n 'nudges' => 'array|max:' . count(Nudge::MAP_CHANNEL),\n 'nudges.*.channel' => 'required|in:' . implode(',', Nudge::MAP_CHANNEL),\n 'nudges.*.frequency' => 'required|in:' . implode(',', Nudge::MAP_FREQUENCY),\n 'nudges.*.expiresAt' => [\n 'required',\n 'date',\n 'after:today',\n 'before_or_equal:' . now()->addYear()->format('Y-m-d'),\n ],\n ]);\n\n $searchCriteria = Criteria::createFromRequest(\n Collection::make($request->input('filters', []))->all(),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($searchCriteria, $user);\n $this->validateSearch($request, $filterSet, 'filters.');\n\n /** @var Search $search */\n $search = Search::create([\n 'name' => $searchName,\n 'uuid' => Uuid::uuid4()->toString(),\n 'user_id' => $user->getId(),\n ]);\n\n Collection::make($request->input('nudges', []))\n ->each(fn (array $attributes): Nudge => $this->nudgeFactory->createNudge($search, $attributes));\n\n $this->storeNamedSearchFilters(Collection::make($request->all()), $search, $filterSet, 'filters.');\n\n return $search;\n }\n\n private function resolveAccount(\n Team $team,\n Contact $contact,\n ServiceInterface $crmService,\n array $prospects,\n ): ?Account {\n $this->logger->info('Resolving account from contact');\n $account = $contact->getAccount();\n\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS)) {\n $this->logger->info('Team does not have feature to link activity to multiple prospects');\n\n return $account;\n }\n\n $this->logger->info('Resolving account from prospect data');\n $accountData = array_filter(\n $prospects,\n static fn (array $prospectData): bool => $prospectData['type'] === 'account'\n );\n\n if (! empty($accountData)) {\n $this->logger->info('Found account data in prospects');\n $accountData = reset($accountData);\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountData['id'])->first();\n\n if (! $account instanceof Account) {\n $this->logger->info('Account not found in database, syncing from CRM');\n $account = $crmService->syncAccount($accountData['id']);\n }\n }\n\n $this->logger->info('Resolved account', ['account' => $account->getId()]);\n\n return $account;\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Http\\Controllers\\API;\n\nuse Carbon\\Carbon;\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Exception;\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Validation\\Rule;\nuse Illuminate\\Validation\\Rules\\In;\nuse Illuminate\\Validation\\ValidationException;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ActivityAnalytics;\nuse Jiminny\\Component\\ActivitySearch;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Contracts\\ES\\Events\\UpdateSingleEntity;\nuse Jiminny\\Contracts\\ES\\UpdateTargetEnum;\nuse Jiminny\\Contracts\\Nudge\\NudgeFactoryInterface;\nuse Jiminny\\Contracts\\Playlist\\PlaylistTrackFactoryInterface;\nuse Jiminny\\Contracts\\Repositories\\PlaylistActivityRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Enums\\TeamSetting;\nuse Jiminny\\Events\\Activities\\AiAutomation\\ActivityProspectAdded;\nuse Jiminny\\Events\\Activities\\Coaching\\Coached;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Controllers\\CommentContextInterface;\nuse Jiminny\\Http\\Responses\\Api\\AbstractResponse;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\ActivityCommentTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTopicTriggerTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTransformer;\nuse Jiminny\\Http\\Transformers\\AvailabilityNotificationTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingFeedbackTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingSectionsTransformer;\nuse Jiminny\\Http\\Transformers\\SearchTransformer;\nuse Jiminny\\Http\\Transformers\\StatsTransformer;\nuse Jiminny\\Jobs\\Crm\\SaveActivity;\nuse Jiminny\\Jobs\\Crm\\UpdateStage;\nuse Jiminny\\Jobs\\Telephony\\StartRecording;\nuse Jiminny\\Jobs\\Telephony\\StopRecording;\nuse Jiminny\\Jobs\\Telephony\\ToggleRecording;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\CoachingFeedback;\nuse Jiminny\\Models\\CoachingSection;\nuse Jiminny\\Models\\CoachingSectionCriterion;\nuse Jiminny\\Models\\CoachingSectionFeedback;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\LanguageDialect;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Nudge;\nuse Jiminny\\Models\\PlaybookCategory;\nuse Jiminny\\Models\\Playlist;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\Track;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\CoachingFeedbackRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Rules\\MultidimensionalArrayMaxCharRule;\nuse Jiminny\\Services\\ActivityService;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Services\\PlaybackService;\nuse Jiminny\\Services\\UserService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\nuse Ramsey\\Uuid\\Uuid;\nuse Sentry;\nuse Symfony\\Component\\HttpFoundation;\n\nfinal class ActivityController extends Controller implements CommentContextInterface\n{\n // Number of minutes to look back on activities. i.e. a timeout on activity duration.\n private const int LOOK_BACK = 180;\n\n public function __construct(\n private ProviderRegistry $providerRegistry,\n private ActivityService $activityService,\n Response $response,\n private UserService $userService,\n private ActivitySearch\\Service\\ActivitySearch $activitySearch,\n private NudgeFactoryInterface $nudgeFactory,\n private ActivityCommentService $activityCommentService,\n private LoggerInterface $logger,\n private readonly CoachingFeedbackRepository $coachingFeedbackRepository,\n private readonly TeamRepository $teamRepository,\n ) {\n parent::__construct($response);\n }\n\n public static function getCommentImplementation(): string\n {\n return Comment::class;\n }\n\n public function delete()\n {\n $this->request->validate([\n '*' => 'uuid:activities',\n ]);\n\n $deletedIds = [];\n foreach ($this->request->all() as $activityId) {\n $activity = Activity::idOrUuId($activityId);\n\n try {\n if ($this->authorize('delete', $activity)) {\n $activity->delete();\n $deletedIds[] = $activityId;\n\n \\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n }\n } catch (AuthorizationException $authorizationException) {\n // They didn't have permission.\n }\n }\n\n return $this->response->withArray($deletedIds);\n }\n\n public function update(Request $request, Activity $activity)\n {\n $this->authorize('updateMetadata', $activity);\n\n $request->validate([\n 'title' => 'string|max:250',\n 'category_id' => 'uuid:playbook_categories',\n 'language' => [\n new In(\n LanguageDialect::query()\n ->with('language')\n ->cursor()\n ->map(static function (LanguageDialect $languageDialect): string {\n return $languageDialect->getLanguageLocale();\n })\n ->all()\n ),\n ],\n ]);\n\n if ($request->has('title')) {\n $activity->title = $request->input('title');\n }\n\n if ($request->has('category_id')) {\n $category = PlaybookCategory::uuid($request->input('category_id'));\n\n if ($category->playbook->team_id !== $request->user()->team_id) {\n return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n if ($request->has('language')) {\n if (! $activity->isInProgress()) {\n return $this->response->withError(\n 'Activity language can only be set while the meeting is in progress.',\n 400\n );\n }\n\n $activity->setLanguageCode($request->input('language'));\n }\n\n $activity->save();\n\n return $this->response->withOk();\n }\n\n // XXX: This should be merged with the update method.\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws SocialAccountTokenInvalidException\n *\n * @return mixed\n */\n public function summarize(Activity $activity): mixed\n {\n $this->logger->info('[Log Activity] Summarizing activity ', [\n 'activityId' => $activity->getUuid(),\n 'payload' => $this->request->all(),\n ]);\n $this->authorize('update', $activity);\n\n $this->logger->info('[Log Activity] Validating summary');\n // Validate the payload.\n $this->validateSummary($activity);\n\n // All objects must belong to this team.\n /** @var User $user */\n $user = $this->request->user();\n $team = $user->getTeam();\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n try {\n $crmUser = $user;\n if ($user->isCrmRequired() === false) {\n $crmUser = $team->owner;\n }\n $crmService->setUser($crmUser);\n } catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());\n }\n\n $rawEntities = $this->request->input('entities');\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid(\n $this->request->input('layout_id')\n );\n\n // Delay execution of CRM jobs to avoid locking issues.\n $jobDelay = 0;\n\n // If we have arrived from a notification, mark it as read.\n $notificationId = $this->request->input('nId');\n if ($notificationId) {\n $notification = $user->unreadNotifications->where('id', $notificationId)->first();\n\n if ($notification) {\n $notification->markAsRead();\n }\n }\n\n $title = $this->request->input('title');\n $prospects = $this->request->input('prospects');\n $opportunityId = $this->request->input('opportunity_id');\n $stageId = $this->request->input('stage_id');\n $categoryId = $this->request->input('category_id');\n $summary = $this->request->input('summary');\n $crmProviderId = $this->request->input('crm_id');\n $isInternal = $this->request->input('is_internal') ?? false;\n\n $lead = null;\n $category = null;\n $account = null;\n $contact = null;\n $opportunity = null;\n $stage = null;\n $callStage = null;\n\n foreach ($prospects as $prospectData) {\n $objectId = $prospectData['id'];\n\n if ($objectId === null) {\n continue;\n }\n\n $objectType = $prospectData['type'];\n $this->logger->info('debug', ['prospect_data' => $prospectData]);\n\n try {\n if ($objectType === null) {\n $this->logger->info('no object type');\n if ($crmService instanceof SupportsObjectTypeParseInterface) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n }\n\n switch ($objectType) {\n case 'lead':\n $this->logger->info('Processing lead');\n /** @var Lead|null $lead */\n $lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();\n\n // Lead does not exist locally, import it.\n if ($lead === null) {\n $this->logger->info('Lead does not exist locally');\n /** @var Lead $lead */\n $lead = $crmService->syncLead($objectId);\n }\n\n $this->logger->info('Lead found', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n if ($stageId === null) {\n $this->logger->info('Stage ID is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $lead->stage;\n\n break;\n }\n\n $this->logger->info('Looking for stage');\n // Determine if they have changed the stage.\n /** @var Stage $stage */\n $stage = $team->crm->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_LEAD)\n ->firstOrFail();\n\n $this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);\n if ($lead->stage_id && $lead->stage_id !== $stage->id) {\n $this->logger->info('Stage has changed');\n // Storage current stage on activity.\n $callStage = $lead->stage;\n\n // The stage has changed, update in remote CRM.\n dispatch(new UpdateStage($activity, $lead, $callStage, $stage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing lead stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->getName(),\n $stage->getName()\n ),\n [\n 'user' => $user->getUuid(),\n 'lead' => $lead->getUuid(),\n ]\n );\n } else {\n $this->logger->info('Stage has not changed');\n // Stage remains as current.\n $callStage = $stage;\n }\n\n break;\n\n case 'account':\n $this->logger->info('Processing account');\n // If the object is not a lead, it should be an account.\n $account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();\n\n // Account does not exist locally, import it.\n if ($account === null) {\n $this->logger->info('Account does not exist locally');\n $account = $crmService->syncAccount($objectId);\n }\n\n $this->logger->info('Account found', ['accountId' => $account->id]);\n\n break;\n case 'contact':\n $this->logger->info('processing contact');\n $contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $this->logger->info('contact does not exist locally');\n $contact = $crmService->syncContact($objectId);\n }\n\n $this->logger->info('resolving account');\n $account = $this->resolveAccount($team, $contact, $crmService, $prospects);\n\n break;\n }\n\n // If they have specified an opportunity, retrieve this with stage.\n if ($opportunityId) {\n $this->logger->info('opportunity id is set');\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if ($opportunity === null) {\n $this->logger->info('opportunity does not exist locally');\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n if ($stageId === null) {\n $this->logger->info('stage id is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $opportunity->stage ?? null;\n } else {\n $this->logger->info('looking for stage');\n /** @var ?Stage $opportunityStage */\n $opportunityStage = $team->crm\n ->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n // There is a chance we still cannot import this opportunity.\n if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {\n $this->logger->info('opportunity stage has changed');\n // Storage current stage on activity.\n $callStage = $opportunity->stage;\n\n dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing opportunity stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->name,\n $opportunityStage->name\n ),\n [\n 'userId' => $user->id_string,\n 'opportunityId' => $opportunity->id_string,\n ]\n );\n } else {\n $this->logger->info('opportunity stage has not changed');\n // Stage remains as current.\n $callStage = $opportunityStage;\n }\n }\n }\n\n if ($crmProviderId) {\n // Cast $crmProviderId to string otherwise it won't use database index for some records\n $linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();\n\n // Check if this activity has already been assigned to a different activity.\n if ($linkedActivity && $linkedActivity->id !== $activity->id) {\n throw new InvalidArgumentException(\n 'Sorry, the linked task has already been logged under a different call. '\n . 'Please choose another linked task.'\n );\n }\n }\n } catch (InvalidArgumentException $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($exception->getMessage());\n } catch (Exception $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorInternalError(\n 'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'\n );\n }\n }\n\n if ($categoryId) {\n $category = PlaybookCategory::uuid($categoryId);\n\n if ($category->playbook->team_id !== $team->id) {\n throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n $this->logger->info('Prospect data', [\n 'lead_id' => $lead?->getId(),\n 'account_id' => $account?->getId(),\n 'contact_id' => $contact?->getId(),\n 'opportunity_id' => $opportunity?->getId(),\n 'stage_id' => $stage?->getId(),\n ]);\n\n if ($title) {\n $activity->title = $title;\n }\n\n if ($summary) {\n $activity->summary = $summary;\n }\n\n if ($crmProviderId) {\n $activity->crm_provider_id = $crmProviderId;\n }\n\n if ($callStage) {\n $this->logger->info('Setting stage id', ['stageId' => $callStage->id]);\n $activity->stage_id = $callStage->id;\n }\n\n if ($lead) {\n $this->logger->info('Setting lead id', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n // If we are changed from an account > lead, unset the account data.\n $this->logger->info('Unsetting account id, opportunity id, contact id, value');\n $activity->account_id = null;\n $activity->opportunity_id = null;\n $activity->contact_id = null;\n $activity->value = null;\n }\n\n if ($account) {\n $this->logger->info('Setting account id', ['accountId' => $account->id]);\n $activity->account_id = $account->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('unsetting lead id');\n $activity->lead_id = null;\n\n // Unset the contact if switching different accounts. Will be set up below if still applicable.\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {\n $this->logger->info('Unsetting contact id');\n $activity->contact_id = null;\n }\n }\n\n if ($opportunity) {\n $this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);\n $this->logger->info('unsetting lead id');\n $activity->opportunity_id = $opportunity->id;\n $activity->value = $opportunity->value;\n\n // If we are changed from an lead > account, unset the lead data.\n $activity->lead_id = null;\n }\n\n if ($contact) {\n $this->logger->info('setting contact id', ['contactId' => $contact->id]);\n $activity->contact_id = $contact->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('Unsetting lead id');\n $activity->lead_id = null;\n }\n\n $activity->is_internal = $isInternal;\n $activity->save();\n $activity->refresh();\n\n $this->logger->notice('Activity saved', [\n 'activity_id' => $activity->getId(),\n 'lead_id' => $activity->lead_id,\n 'account_id' => $activity->account_id,\n 'contact_id' => $activity->contact_id,\n 'opportunity_id' => $activity->opportunity_id,\n 'stage_id' => $activity->stage_id,\n 'crm_provider_id' => $activity->getCrmProviderId(),\n ]);\n\n // Store entities as field data on the activity.\n $updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);\n\n if ($activity->isLoggable()) {\n // Follow-up Task or Event data.\n $followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);\n\n $this->logger->info('CRM LOG manual log triggered', [\n 'activityId' => $activity->getUuid(),\n 'followupData' => $followupData,\n 'userId' => $user->getUuid(),\n ]);\n\n // Store data in the CRM.\n // ++add check for crm_required\n $job = new SaveActivity($activity, $followupData);\n\n if ($updatedData) {\n $job->delay(Carbon::now()->addMinutes($jobDelay));\n }\n\n dispatch($job);\n\n // Manually dispatch log for Opportunity or Prospect added\n if ($activity->hasOpportunity() || $activity->hasProspect()) {\n event(new ActivityProspectAdded(\n activity: $activity,\n eventSource: 'manually-log-crm-data'\n ));\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.\n *\n * @param ServiceInterface $service\n * @param Activity $activity\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array\n {\n $updatedData = [];\n $existingData = $activity->data()->get();\n\n // We need to delete any existing data to overwrite with latest values.\n $activity->data()->delete();\n\n $layoutEntities = $layout->entities()\n ->with('field', 'parent')\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->get();\n\n /** @var LayoutEntity $entity */\n foreach ($layoutEntities as $entity) {\n // If the user has provided a value for this entity\n if (array_key_exists($entity->id_string, $entities)) {\n $value = $entities[$entity->id_string];\n\n // Convert raw data into values that the CRM can consume.\n if ($value) {\n $value = $service->normalizeValue($entity->field->type, $value);\n }\n\n // Check the field is part of the activity-summary section.\n if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {\n // This is the internal database ID, not the external CRM ID.\n $objectId = null;\n\n switch ($entity->field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $objectId = $activity->account_id;\n\n break;\n\n case Field::OBJECT_CONTACT:\n $objectId = $activity->contact_id;\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n $objectId = $activity->opportunity_id;\n\n break;\n\n case Field::OBJECT_LEAD:\n $objectId = $activity->lead_id;\n\n break;\n\n case Field::OBJECT_TASK:\n case Field::OBJECT_EVENT:\n $objectId = $activity->id;\n\n break;\n }\n\n if ($objectId) {\n /** @var FieldData $data */\n $data = $activity->data()->create([\n 'crm_layout_entity_id' => $entity->id,\n 'crm_field_id' => $entity->crm_field_id,\n 'object_type' => $entity->field->object_type,\n 'object_id' => $objectId,\n 'value' => $value,\n ]);\n\n // Never send read-only field data to the CRM.\n if ($entity->read_only === false && $entity->is_visible) {\n $existingValue = $existingData\n ->where('crm_layout_entity_id', $entity->id)\n ->where('crm_field_id', $entity->crm_field_id)\n ->where('object_type', $entity->field->object_type)\n ->where('object_id', $objectId)\n ->first();\n\n // If the field was actually changed, we need to reflect this in the CRM too.\n if ($existingValue === null || $existingValue->value !== $value) {\n $updatedData[] = $data->id;\n }\n }\n }\n }\n }\n }\n\n return $updatedData;\n }\n\n /**\n * Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.\n *\n * @param ServiceInterface $crmService\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array\n {\n $fieldData = [];\n foreach ($entities as $entityId => $value) {\n // Only bother with fields that have a value.\n if ($value) {\n // Extract the entity from the UUID. Check the field is valid and part of the follow-up section.\n $entity = $layout->entities()\n ->uuid($entityId, false)\n ->whereHas('parent', function ($query) {\n $query->where('label', 'follow-up');\n })\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->first();\n\n if ($entity) {\n // Convert raw data into values that the CRM can consume.\n $value = $crmService->normalizeValue($entity->field->type, $value);\n\n // Add the field and value to the payload.\n $fieldData += [\n $entity->field->crm_provider_id => $value,\n ];\n }\n }\n }\n\n return $fieldData;\n }\n\n /**\n * @param Activity $activity\n */\n private function validateSummary(Activity $activity): void\n {\n $team = $activity->user->team;\n $crmProvider = $team->crm->provider;\n $attributes = [];\n\n $rules = [\n 'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,\n 'title' => 'string|max:250',\n 'prospects' => 'required|array',\n 'opportunity_id' => new CrmReference($crmProvider),\n 'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',\n 'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator\n 'summary' => 'max:50000',\n 'nId' => 'exists:notifications,id',\n 'crm_id' => new CrmReference($crmProvider),\n 'entities' => 'array',\n 'is_internal' => 'boolean',\n ];\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));\n\n // Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.\n $entities = $layout->entities()\n ->where('read_only', 0)\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->whereHas('parent', function ($query) use ($activity) {\n if ($activity->isLoggable() === false) {\n $query->where('label', '<>', 'follow-up');\n }\n });\n\n $isInternal = $this->request->input('is_internal', false);\n\n foreach ($entities->get() as $entity) {\n $rules += $this->buildFieldValidator($entity, $isInternal);\n $attributes += $this->buildFieldMessage($entity);\n }\n\n $this->request->validate($rules, [], $attributes);\n }\n\n private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array\n {\n return [\n 'entities.' . $entity->id_string => $entity->getValidator($isInternal),\n ];\n }\n\n /**\n * @param LayoutEntity $entity\n *\n * @return array\n */\n private function buildFieldMessage(LayoutEntity $entity): array\n {\n $label = $entity->label;\n if ($label === null) {\n $label = $entity->field->label;\n }\n\n return [\n 'entities.' . $entity->id_string => $label,\n ];\n }\n\n public function search(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->debugLog(\n $user,\n 'User extracted from request',\n ['user' => $user->getId(), 'tz' => $user->getTimezone()]\n );\n\n $searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());\n\n $this->debugLog(\n $user,\n 'ActivitySearch criteria built',\n ['searchCriteria' => $searchCriteria]\n );\n\n $filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);\n\n $this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);\n\n $this->validateSearch($request, $filterSet);\n\n $this->debugLog($user, 'Request validated');\n\n $searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);\n\n /** @var Collection<Activity> $activities */\n $activities = $searchResponse['results'];\n\n $this->debugLog($user, 'Activities ES response extracted');\n\n $hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(\n $user->getTeamId(),\n TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),\n );\n\n if ($hideInternalMeetingsSetting?->getValue() === '1') {\n $activities = $activities->filter(function (Activity $activity) {\n if ($activity->is_internal && empty($activity->actual_start_time)) {\n return false;\n }\n\n return true;\n });\n }\n\n $this->debugLog($user, 'Internal meetings (?!) filtered');\n\n $this->response->getManager()\n ->parseIncludes([\n 'category',\n 'organizer.group',\n 'prospect',\n 'stage',\n 'opportunity',\n 'stats',\n 'scorecards',\n 'masterTrack',\n 'activeParticipants',\n 'notification',\n ])\n ->setSerializer(new JsonSerializer());\n\n $transformerExcludes = $this->request->input('exclude');\n if ($transformerExcludes) {\n $this->response->getManager()->parseExcludes($transformerExcludes);\n }\n\n $this->debugLog($user, 'Response Manager (?!) applied');\n\n $transformer = new ActivityTransformer();\n $transformer->setConsumer($user);\n\n $this->debugLog($user, 'Activity Transformer added');\n\n $resource = new \\League\\Fractal\\Resource\\Collection($activities, $transformer);\n $page = $searchCriteria->getPageNumber();\n\n $this->debugLog($user, 'Search criteria page number called', ['page' => $page]);\n\n $histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');\n\n $this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);\n\n return $this->response->withArray([\n 'pagination' => [\n 'total' => $searchResponse['totalHits'],\n 'current' => $page,\n 'prev' => max($page - 1, 1),\n 'next' => $page + 1,\n ],\n 'results' => $this->response->getManager()->createData($resource)->toArray(),\n 'histogram' => $histogram,\n ]);\n }\n\n private function debugLog(User $user, string $logMessage, ?array $context = []): void\n {\n // Debug for Learning People Only\n if ($user->getTeamId() !== 260) {\n return;\n }\n\n Log::notice(\n sprintf('[activity-search-controller] %s', $logMessage),\n $context\n );\n }\n\n /** @throws ValidationException */\n private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void\n {\n $rules = [\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ];\n\n if ($prefix !== null && mb_strpos($prefix, '.') !== false) {\n $rules[rtrim($prefix, '.')] = sprintf(\n 'required|array|max:%d',\n $filterSet->count()\n );\n }\n\n $validationRules = $filterSet->getValidationRules($prefix)\n ->merge($rules)\n ->all();\n\n $request->validate($validationRules);\n }\n\n public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $search = $this->updateOrCreateActivitySearch($request);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function updateActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('update', $search);\n\n $this->updateOrCreateActivitySearch($request, $search);\n\n return $this->response->withOk();\n }\n\n private function storeNamedSearchFilters(\n Collection $request,\n Search $search,\n FilterDefinitionCollection $filterSet,\n ?string $prefix = null,\n ): self {\n $arrayTypeProperties = $filterSet\n ->getPropertyTypes([\n FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,\n ])\n ->all();\n\n $supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);\n\n foreach ($supportedRequestProperties as $requestPropertyName) {\n if (! array_has($request, $requestPropertyName)) {\n continue;\n }\n\n /** @var string|string[] $propertyValue */\n $propertyValue = array_get($request, $requestPropertyName);\n $propertyName = $prefix === null\n ? $requestPropertyName\n : mb_substr($requestPropertyName, mb_strlen($prefix));\n\n $isArrayType = array_has($arrayTypeProperties, $propertyName);\n\n if (! $isArrayType) {\n /** @var string $requestPropertyValue */\n\n $search->filters()->updateOrCreate(\n [\n 'filter' => $propertyName,\n ],\n [\n 'value' => $propertyValue,\n ]\n );\n\n continue;\n }\n\n /** @var string[] $requestPropertyValue */\n\n /** @var SearchFilter[]|Collection $existingFilterValues */\n $existingFilterValuesKeyed = $search->filters()\n ->where('filter', $propertyName)\n ->get()\n ->keyBy('id');\n\n // Iterate over values provided as request parameters\n foreach ($propertyValue as $value) {\n /** @var SearchFilter|null $valueFilter */\n $valueFilter = $search->filters()\n ->where(\n [\n 'filter' => $propertyName,\n 'value' => $value,\n ]\n )\n ->first();\n\n if ($valueFilter !== null) {\n // Remove filter value pair from list to be deleted\n $existingFilterValuesKeyed->forget($valueFilter->id);\n } else {\n // Add new filter/value pair\n $search->filters()->updateOrCreate([\n 'filter' => $propertyName,\n 'value' => $value,\n ]);\n }\n }\n\n // Delete filter value pairs for this filter that no longer exist in request parameters\n foreach ($existingFilterValuesKeyed as $existingFilter) {\n $existingFilter->delete();\n }\n }\n\n /** @var Collection<int, SearchFilter> $filtersKeyed */\n $filtersKeyed = $search->filters()->get()->keyBy('filter');\n\n // wipe removed filters from this search\n foreach ($filtersKeyed as $filterName => $filter) {\n if (array_has($request, $prefix . $filterName)) {\n continue;\n }\n\n // Remove all filter values for this filter\n $search->filters()->where('filter', $filterName)->delete();\n }\n\n return $this;\n }\n\n /**\n * @throws AuthorizationException\n */\n public function fetchActivitySearch(\n Search $search,\n Request $request,\n SearchTransformer $searchTransformer,\n ): JsonResponse {\n $this->authorize('view', $search);\n\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection(\n $user->searches()->get(),\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n /**\n * Deletes a saved search\n *\n * @param Request $request\n * @param Search $search\n *\n * @throws Exception\n *\n * @return JsonResponse\n */\n public function deleteActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('delete', $search);\n\n // Orphan any AutomatedReports that use this search\n $search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);\n\n // Delete filters and the search itself\n $search->filters()->delete();\n $search->delete();\n\n return $this->response->withOk();\n }\n\n public function live(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n $user = $this->getUserFromRequest($request);\n\n $this->request->validate([\n 'sort_direction' => 'in:asc,desc',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ]);\n\n $activities = $repository->getLiveCoachingEligibleActivities(\n user: $user,\n lookBackMinutes: self::LOOK_BACK,\n limit: (int) $this->request->input('limit', 25),\n page: (int) $this->request->input('page', 1),\n sortBy: ['actual_start_time', 'scheduled_start_time'],\n sortDirection: (string) $this->request->input('sort_direction', 'asc'),\n );\n\n $this->response\n ->getManager()\n ->parseIncludes(['organizer.group', 'prospect'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($activities, new ActivityTransformer());\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function show(Activity $activity, ActivityService $activityService): JsonResponse\n {\n $this->authorize('show', $activity);\n\n $user = $activity->getUser();\n $team = $user->getTeam();\n\n // Sync the opportunity with the latest data if possible.\n if ($activity->opportunity_id) {\n try {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n if (! $user->isCrmRequired()) {\n $crmService->setUser($team->getOwner());\n } else {\n $crmService->setUser($user);\n }\n\n $crmService->syncOpportunity($activity->opportunity->crm_provider_id);\n } catch (Exception $exception) {\n // Move on.\n }\n }\n\n $activityData = $activityService->getActivityData($this->request->user(), $activity);\n\n return response()->json($activityData);\n }\n\n public function createRecording(Activity $activity)\n {\n $this->authorize('record', $activity);\n\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Tell Twilio to start recording this activity.\n if ($activity->recording_state === Activity::RECORDING_OFF) {\n $job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withCreated();\n }\n\n return $this->response->errorGone('Activity is already recording.');\n }\n\n public function updateRecording(Request $request, Activity $activity)\n {\n $this->authorize('record', $activity);\n\n $request->validate([\n 'preference' => 'boolean',\n 'state' => [\n 'string',\n Rule::in([\n Activity::RECORDING_IN_PROGRESS,\n Activity::RECORDING_PAUSED,\n ]),\n ],\n ]);\n\n if ($request->has('state')) {\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Toggle the recording state between paused and resumed.\n if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {\n $job = (new ToggleRecording($activity, $request->input('state')))\n ->onQueue(Constants::QUEUE_CONFERENCES);\n\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Recording is not toggleable.');\n }\n\n if ($request->has('preference')) {\n $activity->update([\n 'recording_preference' => $request->input('preference') ? 1 : 0,\n ]);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorWrongArgs('Something went wrong');\n }\n\n public function stopRecording(Activity $activity)\n {\n $this->authorize('stopRecord', $activity);\n\n // Tell Twilio to stop recording this activity.\n if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {\n $job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Activity is not recording.');\n }\n\n /**\n * Add activity to this user's favorites playlist\n *\n * @throws AuthorizationException\n */\n public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse\n {\n $this->authorize('favorite', $activity);\n\n $user = $this->getUserFromRequest($this->request);\n $favorite = $activity->wasFavoritedBy($user);\n $name = $activity->activity_title ?? '';\n\n // It needs to check at least one record.\n if (! $favorite) {\n $favoritePlaylist = $user->favoritePlaylist();\n\n $playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(\n $activity,\n $user,\n $favoritePlaylist\n );\n\n if ($playlistActivity !== null) {\n $playlistActivity->update(\n // Just update, don't sort.\n ['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],\n );\n } else {\n $playlistActivity = $activity->playlistActivities()->create([\n 'playlist_id' => $favoritePlaylist->getId(),\n 'user_id' => $user->getId(),\n 'start_time' => 0,\n 'name' => mb_strimwidth($name, 0, 100),\n ]);\n // Sort it on top.\n $playlistActivity->update(\n [\n 'sort' => $playlistActivityRepository->calculateNewSortOrder(\n null,\n $playlistActivity,\n ),\n ],\n );\n }\n\n $playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);\n\n return new JsonResponse([], JsonResponse::HTTP_CREATED);\n }\n\n return new JsonResponse(\n [\n 'error' => [\n 'code' => AbstractResponse::CODE_CONFLICT,\n 'http_code' => JsonResponse::HTTP_CONFLICT,\n 'message' => 'Resource Already Exists',\n ],\n ],\n JsonResponse::HTTP_CONFLICT,\n );\n }\n\n /**\n * Remove activity from this user's favorites playlist\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unfavorite(Activity $activity)\n {\n $user = $this->request->user();\n\n $favorites = $activity->favoritedBy($user);\n\n if ($favorites && $favorites->isEmpty()) {\n return $this->response->errorNotFound('Favorite not found.');\n }\n\n $this->authorize('unfavorite', [$activity, $favorites]);\n\n // When you unfavorite an activity,\n // it should remove all the activities in it, including snippets.\n $isDeleted = $favorites->each(function ($favorite) {\n $favorite->forceDelete();\n });\n\n if ($isDeleted) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not remove favorite.');\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function notify(Activity $activity)\n {\n $this->authorize('notify', $activity);\n\n $user = $this->request->user();\n\n $existingNotification = $activity->availabilityNotifications()\n ->where('user_id', $user->id)\n ->exists();\n\n if ($existingNotification) {\n return $this->response->errorWrongArgs('Notification is already configured.');\n }\n\n $notification = Activity\\AvailabilityNotification::create([\n 'user_id' => $user->id,\n 'activity_id' => $activity->id,\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($notification, new AvailabilityNotificationTransformer());\n }\n\n /**\n * @param Activity $activity\n * @param Activity\\AvailabilityNotification $notification\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unnotify(Activity $activity, Activity\\AvailabilityNotification $notification)\n {\n $this->authorize('unnotify', [$activity, $notification]);\n\n if ($notification->sent_at || $notification->delete()) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not delete notification.');\n }\n\n public function play(Request $request, Activity $activity)\n {\n $this->authorize('stream', $activity);\n\n $request->validate([\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $activity->plays()->create([\n 'user_id' => $user->getId(),\n 'start_time' => $request->input('start_time'),\n ]);\n\n return $this->response->withCreated();\n }\n\n /**\n * @param Activity $activity\n *\n * @return mixed\n */\n public function comment(Activity $activity)\n {\n return $this->newComment($activity);\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @return mixed\n */\n public function replyComment(Activity $activity, Comment $comment)\n {\n return $this->newComment($activity, $comment);\n }\n\n /**\n * @param Activity $activity\n * @param Comment|null $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n protected function newComment(Activity $activity, ?Comment $comment = null)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n 'type' => 'integer|between:0,3',\n 'visibility' => sprintf('nullable|integer|between:1,%d', count(Comment::getVisibilityLevels())),\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n $threadStartId = null;\n if ($comment) {\n $threadStartId = $comment->thread_start_id ?: $comment->id;\n }\n\n try {\n $newComment = Comment::create([\n 'parent_comment_id' => $comment->id ?? null,\n 'thread_start_id' => $threadStartId,\n 'activity_id' => $activity->id,\n 'user_id' => $this->request->user()->id,\n 'comment' => trim($this->request->input('comment')),\n 'start_time' => $this->request->input('start_time', 0),\n 'end_time' => $this->request->input('end_time', 0),\n 'type' => $this->request->input('type', Comment::TYPE_NEUTRAL),\n 'visibility' => $this->request->input('visibility', Comment::VISIBILITY_PUBLIC),\n ]);\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($newComment, new ActivityCommentTransformer());\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not create comment.' . $exception->getMessage());\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function updateComment(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n try {\n $comment->update([\n 'comment' => trim($this->request->input('comment')),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment.');\n }\n }\n\n public function updateCommentVisibility(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'visibility' => sprintf('integer|between:1,%d', count(Comment::getVisibilityLevels())),\n ]);\n\n $visibility = $this->request->input('visibility');\n\n if ($comment->parent !== null) {\n return $this->response->errorWrongArgs('Comment visibility can only be updated on top level comments.');\n }\n\n try {\n $this->activityCommentService->updateCommentVisibility($comment, $visibility);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment\\'s visibility.');\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function deleteComment(Activity $activity, Comment $comment)\n {\n $this->authorize('deleteComment', [$activity, $comment]);\n\n // Delete comment and any children.\n $comment->delete();\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function fetchComments()\n {\n $user = $this->request->user();\n $this->request->validate([\n 'forUserId' => 'uuid:users,team_id,' . $user->team_id,\n 'types' => 'array',\n 'types.*' => 'integer|between:0,3',\n ]);\n $forUser = null;\n\n $types = [Comment::TYPE_NEUTRAL, Comment::TYPE_GAME_CHANGER, Comment::TYPE_POSITIVE];\n $user = $this->request->user();\n if ($this->request->has('forUserId')) {\n $forUser = $user->team->users()->uuid($this->request->input('forUserId'));\n }\n\n $comments = Comment::query()\n ->whereHas('activity', static function (Builder $builder) use ($user, $forUser): void {\n $builder\n // I left feedback on my own activity; or\n ->where('activities.user_id', $user->getId());\n if ($forUser) {\n // I left feedback on any activity for this user.\n $builder->orWhere([\n 'user_id' => $user->getId(),\n 'activities.user_id' => $forUser->getId(),\n ]);\n }\n })\n ->whereIn('type', $this->request->input('types', $types))\n ->orderBy('created_at', 'desc')\n ->get();\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity', 'user'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($comments, new ActivityCommentTransformer());\n }\n\n public function deleteCoachingFeedback(Activity $activity, CoachingFeedback $coachingFeedback)\n {\n $this->authorize('deleteCoachingFeedback', [$activity, $coachingFeedback]);\n $activity = $coachingFeedback->getActivity();\n\n if ($coachingFeedback->delete()) {\n event(new UpdateSingleEntity(\n entityId: $activity->getId(),\n updateTarget: UpdateTargetEnum::ACTIVITY,\n purpose: 'delete-coaching-feedback',\n ));\n\n return $this->response->withOk();\n }\n\n return $this->response->withError('Delete operation failed. Contact support.', 500);\n }\n\n /**\n * Add new or update Coaching feedback\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws \\Illuminate\\Validation\\ValidationException\n *\n * @return mixed\n */\n public function putCoachingFeedback(Request $request, Activity $activity)\n {\n $user = $request->user();\n\n if (! $user instanceof User) {\n abort(403);\n }\n $teamId = $user->getTeamId();\n\n $this->authorize('coach', $activity);\n\n $this->request->validate([\n 'coach_id' => 'required|uuid:users,team_id,' . $teamId,\n 'coachee_id' => 'required|uuid:users,team_id,' . $teamId,\n 'visibility' => ['required', Rule::in(CoachingFeedback::VISIBILITIES)],\n 'coaching_sections.*.uuid' => 'required|uuid:coaching_sections',\n 'coaching_sections.*.score' => ['required', Rule::in(CoachingSectionFeedback::SCORES)],\n 'coaching_sections.*.summary' => 'string|max:10000',\n 'coaching_sections.*.criteria.*.uuid' => 'required|uuid:coaching_section_criteria',\n 'coaching_sections.*.criteria.*.note' => 'required|string|max:10000',\n 'sharedWithUsers' => [\n 'required_if:visibility,' . CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS,\n 'array',\n ],\n 'sharedWithUsers.*' => [\n 'uuid:users,team_id,' . $teamId,\n ],\n ]);\n\n /** @var User $coach */\n $coach = User::uuid($this->request->input('coach_id'));\n /** @var User $coachee */\n $coachee = User::uuid($this->request->input('coachee_id'));\n $coachingSectionFeedbacks = $this->request->input('coaching_sections');\n\n $previousRecord = $this->coachingFeedbackRepository->getOneForActivityByCoacheeAndCoach(\n $coachee->getId(),\n $coach->getId(),\n $activity->getId()\n );\n $recordIsNew = false;\n if ($previousRecord === null) {\n $recordIsNew = true;\n }\n\n if (! $coachee->isSameTeamId($coach)) {\n return $this->response->errorForbidden('User not member of your team.');\n }\n\n if (! is_array($coachingSectionFeedbacks) || count($coachingSectionFeedbacks) < 1) {\n return $this->response->withError('At least one Coaching Framework Section shall be scored.', 422);\n }\n\n if (! $activity->participants()->where('participants.user_id', $coachee->id)->exists()) {\n return $this->response->withError('Coached user did not participate activity.', 422);\n }\n\n $visibility = $this->request->input('visibility');\n\n $shouldSendNotification = $recordIsNew;\n if ($recordIsNew === false && $visibility !== $previousRecord->getVisibility()) {\n $shouldSendNotification = true;\n }\n\n /**\n * Create CoachingFeedback\n *\n * @var CoachingFeedback $coachingFeedback\n */\n $coachingFeedback = $activity->coachingFeedbacks()->updateOrCreate(\n [\n 'coach_id' => $coach->id,\n 'coachee_id' => $coachee->id,\n ],\n [\n 'framework_id' => $activity->category->id,\n 'visibility' => $visibility,\n ]\n );\n\n $sharedUserIds = [];\n if ($visibility === CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS) {\n foreach ($this->request->input('sharedWithUsers') as $sharedWithUserUuid) {\n /** @var User $user */\n $user = User::uuid($sharedWithUserUuid);\n $sharedUserIds[] = $user->getId();\n }\n }\n\n $syncResult = $coachingFeedback->customAccessUsers()->sync($sharedUserIds);\n\n $scores = [];\n\n\n /**\n * Create CoachingSectionsFeedbacks.\n *\n * @var CoachingSectionFeedback $coachingSectionFeedback\n */\n foreach ($coachingSectionFeedbacks as $coachingSectionFeedbackInput) {\n $coachingSection = CoachingSection::uuid($coachingSectionFeedbackInput['uuid']);\n $coachingSectionFeedback = $coachingFeedback->sectionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_id' => $coachingSection->id,\n ],\n [\n 'score' => array_get($coachingSectionFeedbackInput, 'score'),\n 'summary' => array_get($coachingSectionFeedbackInput, 'summary') ?? '',\n ]\n );\n\n $scores[] = array_get($coachingSectionFeedbackInput, 'score');\n\n $criteria = array_get($coachingSectionFeedbackInput, 'criteria');\n if (is_array($criteria) && ! empty($criteria)) {\n foreach ($criteria as $criteriaFeedbackInput) {\n $coachingSectionFeedback->criterionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_criterion_id' => CoachingSectionCriterion::uuid(array_get($criteriaFeedbackInput, 'uuid'))\n ->id,\n ],\n ['note' => array_get($criteriaFeedbackInput, 'note')],\n );\n }\n }\n }\n\n $coachingFeedback->average_score = array_sum($scores) / count($scores);\n\n if ($recordIsNew === false && $coachingFeedback->getAverageScore() !== $previousRecord->getAverageScore()) {\n $shouldSendNotification = true;\n }\n if (! empty($syncResult['attached']) || ! empty($syncResult['detached']) || ! empty($syncResult['updated'])) {\n $shouldSendNotification = true;\n }\n\n $coachingFeedback->save();\n // ensure updated at for coaching feedback on section feedback summary added.\n $coachingFeedback->touch();\n\n if ($shouldSendNotification) {\n event(new Coached($coachingFeedback));\n }\n\n Datadog::increment('jiminny.activity.score.update', 1, ['company' => $activity->user->team->slug]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n $coachingFeedbackTransformer = new CoachingFeedbackTransformer();\n $coachingFeedbackTransformer->setConsumer($this->getUserFromRequest($request));\n\n return $this->response->withItem($coachingFeedback, $coachingFeedbackTransformer);\n }\n\n\n /**\n * Retrieve category criteria for coaching.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachingSections(Activity $activity)\n {\n $this->authorize('coach', $activity);\n\n if ($activity->category === null) {\n return $this->response->errorUnprocessable('Category has not yet been assigned.');\n }\n\n $criteria = $activity\n ->category\n ->coachingSections()\n ->where('is_enabled', 1)\n ->orderBy('sequence', 'asc');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($criteria->get(), new CoachingSectionsTransformer());\n }\n\n /**\n * @throws AuthorizationException\n * @throws ValidationException\n *\n * @return mixed\n */\n public function addToPlaylist(Activity $activity, PlaylistTrackFactoryInterface $playlistTrackFactory)\n {\n $this->request->validate([\n 'playlists' => 'required|array',\n 'playlists.*' => 'uuid:playlists',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'name' => 'required|max:100',\n ]);\n\n $this->authorize('addToPlaylist', [$activity, $this->request->input('playlists')]);\n\n $startTime = $this->request->input('start_time');\n $endTime = $this->request->input('end_time');\n $name = $this->request->input('name');\n /** @var User $user */\n $user = $this->request->user();\n\n // Get playlist by uuid.\n foreach ($this->request->input('playlists') as $playlistId) {\n // Pull out the playlist model.\n $playlist = Playlist::uuid($playlistId);\n\n $playlistTrackFactory->createTrack($playlist, $user, [\n 'name' => $name,\n 'activity' => $activity,\n 'start_time' => $startTime,\n 'end_time' => $endTime,\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function share(Request $request, Activity $activity): JsonResponse\n {\n $this->authorize('share', $activity);\n\n $request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'recipients.*.type' => 'in:user,group',\n 'recipients.*.id' => 'string|max:40',\n 'share' => 'string|max:255',\n ]);\n\n $user = $request->user();\n\n $recipients = $request->get('recipients');\n $users = $this->userService->convertRecipientsToUsers($user, $recipients);\n\n $shareData = [\n 'from_user_id' => $user->id,\n 'note' => $request->input('note'),\n 'start_time' => $request->input('start_time'),\n 'end_time' => $request->input('end_time'),\n ];\n\n // Create a share object against a notification provider channel\n if ($request->input('share')) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'notification_provider_channel' => $request->input('share'),\n ]\n )\n );\n\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n\n // Create a share object against each recipient\n foreach ($users as $recipient) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'to_user_id' => $recipient->id,\n ]\n )\n );\n\n // If parent_share_id has been selected yet\n if (! isset($shareData['parent_share_id'])) {\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachRequest(Activity $activity)\n {\n $this->authorize('coachRequest', $activity);\n\n $this->request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'coachers.*.type' => 'required|in:user',\n 'coachers.*.id' => 'required',\n ]);\n\n $coachers = $this->request->get('coachers');\n $user = $this->request->user();\n $users = $this->userService->convertRecipientsToUsers($user, $coachers);\n\n foreach ($users as $coacher) {\n CoachRequest::create([\n 'user_id' => $coacher->id,\n 'activity_id' => $activity->id,\n 'note' => $this->request->get('note'),\n 'start_time' => $this->request->get('start_time'),\n 'end_time' => $this->request->get('end_time'),\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function createActivityTopicTriggers(Activity $activity, LoggerInterface $logger): HttpFoundation\\JsonResponse\n {\n $this->authorize('analyzeTopicTriggers', $activity);\n\n if (! $activity->hasTranscription()) {\n return new HttpFoundation\\JsonResponse(\n [\n 'error' => 'Transcription not found.',\n ],\n JsonResponse::HTTP_NOT_FOUND\n );\n }\n\n $logger->info(__METHOD__ . ': queued for analysis', [\n 'activity' => $activity->id_string,\n ]);\n\n dispatch(new ActivityAnalytics\\Job\\AnalyzeActivityTopicTriggers($activity));\n\n return new HttpFoundation\\JsonResponse(null, JsonResponse::HTTP_CREATED);\n }\n\n public function fetchActivityTopicTriggers(\n Activity $activity,\n LoggerInterface $logger,\n ActivityTopicTriggerTransformer $transformer\n ): HttpFoundation\\JsonResponse {\n $this->authorize('fetchTopicTriggers', $activity);\n\n $logger->debug(__METHOD__, [\n 'activity' => $activity->id_string,\n ]);\n\n if (! $activity->isProcessed()) {\n return new HttpFoundation\\JsonResponse([]);\n }\n\n $payload = [];\n\n if ($activity->hasTopicTriggers()) {\n $payload = $activity->getTopicTriggersSorted()\n ->map(\n static fn (Activity\\TopicTrigger $activityTopicTrigger): array\n => $transformer->transform($activityTopicTrigger)\n )\n ->values()\n ->all();\n }\n\n return new HttpFoundation\\JsonResponse($payload);\n }\n\n /**\n * @param Activity $activity\n * @param StatsTransformer $statsTransformer\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function stats(Activity $activity, StatsTransformer $statsTransformer)\n {\n $this->authorize('stream', $activity);\n\n if (! $activity->hasTranscription()) {\n return $this->response->errorNotFound('Waveform data is not yet generated.');\n }\n\n $this->response\n ->getManager()\n ->parseIncludes(['wavedata'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($activity, $statsTransformer);\n }\n\n public function destroy(Activity $activity)\n {\n $this->authorize('delete', $activity);\n\n $activity->delete();\n\n \\Log::info('Soft delete activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n\n return $this->response->withNoContent();\n }\n\n public function note(Activity $activity)\n {\n $this->authorize('note', $activity);\n\n $this->request->validate([\n 'note' => 'required|min:1|max:2000',\n 'time' => 'required|numeric|min:0|max:86400',\n ]);\n\n $note = $this->request->input('note');\n $time = $this->request->input('time');\n\n $this->activityService->setActivity($activity);\n $this->activityService->takeNote($this->getUser(), $note, $time);\n\n return $this->response->withCreated();\n }\n\n /**\n * Mark an activity as private.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPrivate(Activity $activity)\n {\n $this->authorize('markAsPrivate', $activity);\n\n if ($activity->is_private === false) {\n $activity->is_private = true;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * Mark an activity as public.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPublic(Activity $activity)\n {\n $this->authorize('markAsPublic', $activity);\n\n if ($activity->is_private) {\n $activity->is_private = false;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws LogicException\n */\n public function fetchCloudFrontS3MediaKeys(Activity $activity, PlaybackService $playbackService): JsonResponse\n {\n $masterTrack = $activity->masterTrack()->first();\n\n if (! $masterTrack instanceof Track) {\n throw new LogicException(sprintf('Master track not found for activity \"%s\"', $activity->getUuid()));\n }\n\n return $this->response->withArray(\n $playbackService->generateCookies(\n $masterTrack,\n $this->request->ip(),\n ),\n );\n }\n\n /**\n * @throws ValidationException\n */\n private function updateOrCreateActivitySearch(Request $request, ?Search $search = null): Search\n {\n $request->validate([\n 'name' => 'required|string|min:2|max:100',\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $searchName = $request->input('name');\n\n if ($search !== null) {\n $search->update([\n 'name' => $searchName,\n ]);\n\n return $search;\n }\n\n $request->validate([\n 'filters' => ['required', 'array', new MultidimensionalArrayMaxCharRule(limit: 255)],\n 'nudges' => 'array|max:' . count(Nudge::MAP_CHANNEL),\n 'nudges.*.channel' => 'required|in:' . implode(',', Nudge::MAP_CHANNEL),\n 'nudges.*.frequency' => 'required|in:' . implode(',', Nudge::MAP_FREQUENCY),\n 'nudges.*.expiresAt' => [\n 'required',\n 'date',\n 'after:today',\n 'before_or_equal:' . now()->addYear()->format('Y-m-d'),\n ],\n ]);\n\n $searchCriteria = Criteria::createFromRequest(\n Collection::make($request->input('filters', []))->all(),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($searchCriteria, $user);\n $this->validateSearch($request, $filterSet, 'filters.');\n\n /** @var Search $search */\n $search = Search::create([\n 'name' => $searchName,\n 'uuid' => Uuid::uuid4()->toString(),\n 'user_id' => $user->getId(),\n ]);\n\n Collection::make($request->input('nudges', []))\n ->each(fn (array $attributes): Nudge => $this->nudgeFactory->createNudge($search, $attributes));\n\n $this->storeNamedSearchFilters(Collection::make($request->all()), $search, $filterSet, 'filters.');\n\n return $search;\n }\n\n private function resolveAccount(\n Team $team,\n Contact $contact,\n ServiceInterface $crmService,\n array $prospects,\n ): ?Account {\n $this->logger->info('Resolving account from contact');\n $account = $contact->getAccount();\n\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS)) {\n $this->logger->info('Team does not have feature to link activity to multiple prospects');\n\n return $account;\n }\n\n $this->logger->info('Resolving account from prospect data');\n $accountData = array_filter(\n $prospects,\n static fn (array $prospectData): bool => $prospectData['type'] === 'account'\n );\n\n if (! empty($accountData)) {\n $this->logger->info('Found account data in prospects');\n $accountData = reset($accountData);\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountData['id'])->first();\n\n if (! $account instanceof Account) {\n $this->logger->info('Account not found in database, syncing from CRM');\n $account = $crmService->syncAccount($accountData['id']);\n }\n }\n\n $this->logger->info('Resolved account', ['account' => $account->getId()]);\n\n return $account;\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-7287184300264252456
|
-8385861013499833196
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use Carbon\Carbon;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\In;
use Illuminate\Validation\ValidationException;
use InvalidArgumentException;
use Jiminny\Component\ActivityAnalytics;
use Jiminny\Component\ActivitySearch;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Queue\Constants;
use Jiminny\Contracts\ES\Events\UpdateSingleEntity;
use Jiminny\Contracts\ES\UpdateTargetEnum;
use Jiminny\Contracts\Nudge\NudgeFactoryInterface;
use Jiminny\Contracts\Playlist\PlaylistTrackFactoryInterface;
use Jiminny\Contracts\Repositories\PlaylistActivityRepository;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Enums\TeamSetting;
use Jiminny\Events\Activities\AiAutomation\ActivityProspectAdded;
use Jiminny\Events\Activities\Coaching\Coached;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Controllers\CommentContextInterface;
use Jiminny\Http\Responses\Api\AbstractResponse;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\ActivityCommentTransformer;
use Jiminny\Http\Transformers\ActivityTopicTriggerTransformer;
use Jiminny\Http\Transformers\ActivityTransformer;
use Jiminny\Http\Transformers\AvailabilityNotificationTransformer;
use Jiminny\Http\Transformers\CoachingFeedbackTransformer;
use Jiminny\Http\Transformers\CoachingSectionsTransformer;
use Jiminny\Http\Transformers\SearchTransformer;
use Jiminny\Http\Transformers\StatsTransformer;
use Jiminny\Jobs\Crm\SaveActivity;
use Jiminny\Jobs\Crm\UpdateStage;
use Jiminny\Jobs\Telephony\StartRecording;
use Jiminny\Jobs\Telephony\StopRecording;
use Jiminny\Jobs\Telephony\ToggleRecording;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\CoachingFeedback;
use Jiminny\Models\CoachingSection;
use Jiminny\Models\CoachingSectionCriterion;
use Jiminny\Models\CoachingSectionFeedback;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\LanguageDialect;
use Jiminny\Models\Lead;
use Jiminny\Models\Nudge;
use Jiminny\Models\PlaybookCategory;
use Jiminny\Models\Playlist;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\Track;
use Jiminny\Models\User;
use Jiminny\Repositories\CoachingFeedbackRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Rules\CrmReference;
use Jiminny\Rules\MultidimensionalArrayMaxCharRule;
use Jiminny\Services\ActivityService;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Services\PlaybackService;
use Jiminny\Services\UserService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
use Ramsey\Uuid\Uuid;
use Sentry;
use Symfony\Component\HttpFoundation;
final class ActivityController extends Controller implements CommentContextInterface
{
// Number of minutes to look back on activities. i.e. a timeout on activity duration.
private const int LOOK_BACK = 180;
public function __construct(
private ProviderRegistry $providerRegistry,
private ActivityService $activityService,
Response $response,
private UserService $userService,
private ActivitySearch\Service\ActivitySearch $activitySearch,
private NudgeFactoryInterface $nudgeFactory,
private ActivityCommentService $activityCommentService,
private LoggerInterface $logger,
private readonly CoachingFeedbackRepository $coachingFeedbackRepository,
private readonly TeamRepository $teamRepository,
) {
parent::__construct($response);
}
public static function getCommentImplementation(): string
{
return Comment::class;
}
public function delete()
{
$this->request->validate([
'*' => 'uuid:activities',
]);
$deletedIds = [];
foreach ($this->request->all() as $activityId) {
$activity = Activity::idOrUuId($activityId);
try {
if ($this->authorize('delete', $activity)) {
$activity->delete();
$deletedIds[] = $activityId;
\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);
}
} catch (AuthorizationException $authorizationException) {
// They didn't have permission.
}
}
return $this->response->withArray($deletedIds);
}
public function update(Request $request, Activity $activity)
{
$this->authorize('updateMetadata', $activity);
$request->validate([
'title' => 'string|max:250',
'category_id' => 'uuid:playbook_categories',
'language' => [
new In(
LanguageDialect::query()
->with('language')
->cursor()
->map(static function (LanguageDialect $languageDialect): string {
return $languageDialect->getLanguageLocale();
})
->all()
),
],
]);
if ($request->has('title')) {
$activity->title = $request->input('title');
}
if ($request->has('category_id')) {
$category = PlaybookCategory::uuid($request->input('category_id'));
if ($category->playbook->team_id !== $request->user()->team_id) {
return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
if ($request->has('language')) {
if (! $activity->isInProgress()) {
return $this->response->withError(
'Activity language can only be set while the meeting is in progress.',
400
);
}
$activity->setLanguageCode($request->input('language'));
}
$activity->save();
return $this->response->withOk();
}
// XXX: This should be merged with the update method.
/**
* @param Activity $activity
*
* @throws AuthorizationException
* @throws SocialAccountTokenInvalidException
*
* @return mixed
*/
public function summarize(Activity $activity): mixed
{
$this->logger->info('[Log Activity] Summarizing activity ', [
'activityId' => $activity->getUuid(),
'payload' => $this->request->all(),
]);
$this->authorize('update', $activity);
$this->logger->info('[Log Activity] Validating summary');
// Validate the payload.
$this->validateSummary($activity);
// All objects must belong to this team.
/** @var User $user */
$user = $this->request->user();
$team = $user->getTeam();
$crmService = $this->providerRegistry->get($team->crm->provider);
try {
$crmUser = $user;
if ($user->isCrmRequired() === false) {
$crmUser = $team->owner;
}
$crmService->setUser($crmUser);
} catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());
}
$rawEntities = $this->request->input('entities');
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid(
$this->request->input('layout_id')
);
// Delay execution of CRM jobs to avoid locking issues.
$jobDelay = 0;
// If we have arrived from a notification, mark it as read.
$notificationId = $this->request->input('nId');
if ($notificationId) {
$notification = $user->unreadNotifications->where('id', $notificationId)->first();
if ($notification) {
$notification->markAsRead();
}
}
$title = $this->request->input('title');
$prospects = $this->request->input('prospects');
$opportunityId = $this->request->input('opportunity_id');
$stageId = $this->request->input('stage_id');
$categoryId = $this->request->input('category_id');
$summary = $this->request->input('summary');
$crmProviderId = $this->request->input('crm_id');
$isInternal = $this->request->input('is_internal') ?? false;
$lead = null;
$category = null;
$account = null;
$contact = null;
$opportunity = null;
$stage = null;
$callStage = null;
foreach ($prospects as $prospectData) {
$objectId = $prospectData['id'];
if ($objectId === null) {
continue;
}
$objectType = $prospectData['type'];
$this->logger->info('debug', ['prospect_data' => $prospectData]);
try {
if ($objectType === null) {
$this->logger->info('no object type');
if ($crmService instanceof SupportsObjectTypeParseInterface) {
$objectType = $crmService->parseObjectType($objectId);
}
}
switch ($objectType) {
case 'lead':
$this->logger->info('Processing lead');
/** @var Lead|null $lead */
$lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();
// Lead does not exist locally, import it.
if ($lead === null) {
$this->logger->info('Lead does not exist locally');
/** @var Lead $lead */
$lead = $crmService->syncLead($objectId);
}
$this->logger->info('Lead found', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
if ($stageId === null) {
$this->logger->info('Stage ID is null');
// If it was not provided, just assume it is the current stage.
$callStage = $lead->stage;
break;
}
$this->logger->info('Looking for stage');
// Determine if they have changed the stage.
/** @var Stage $stage */
$stage = $team->crm->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_LEAD)
->firstOrFail();
$this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);
if ($lead->stage_id && $lead->stage_id !== $stage->id) {
$this->logger->info('Stage has changed');
// Storage current stage on activity.
$callStage = $lead->stage;
// The stage has changed, update in remote CRM.
dispatch(new UpdateStage($activity, $lead, $callStage, $stage));
$this->logger->info(
sprintf(
'[%s] User changing lead stage from %s to %s',
$crmService->getDisplayName(),
$callStage->getName(),
$stage->getName()
),
[
'user' => $user->getUuid(),
'lead' => $lead->getUuid(),
]
);
} else {
$this->logger->info('Stage has not changed');
// Stage remains as current.
$callStage = $stage;
}
break;
case 'account':
$this->logger->info('Processing account');
// If the object is not a lead, it should be an account.
$account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();
// Account does not exist locally, import it.
if ($account === null) {
$this->logger->info('Account does not exist locally');
$account = $crmService->syncAccount($objectId);
}
$this->logger->info('Account found', ['accountId' => $account->id]);
break;
case 'contact':
$this->logger->info('processing contact');
$contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$this->logger->info('contact does not exist locally');
$contact = $crmService->syncContact($objectId);
}
$this->logger->info('resolving account');
$account = $this->resolveAccount($team, $contact, $crmService, $prospects);
break;
}
// If they have specified an opportunity, retrieve this with stage.
if ($opportunityId) {
$this->logger->info('opportunity id is set');
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if ($opportunity === null) {
$this->logger->info('opportunity does not exist locally');
$opportunity = $crmService->syncOpportunity($opportunityId);
}
if ($stageId === null) {
$this->logger->info('stage id is null');
// If it was not provided, just assume it is the current stage.
$callStage = $opportunity->stage ?? null;
} else {
$this->logger->info('looking for stage');
/** @var ?Stage $opportunityStage */
$opportunityStage = $team->crm
->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
// There is a chance we still cannot import this opportunity.
if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {
$this->logger->info('opportunity stage has changed');
// Storage current stage on activity.
$callStage = $opportunity->stage;
dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));
$this->logger->info(
sprintf(
'[%s] User changing opportunity stage from %s to %s',
$crmService->getDisplayName(),
$callStage->name,
$opportunityStage->name
),
[
'userId' => $user->id_string,
'opportunityId' => $opportunity->id_string,
]
);
} else {
$this->logger->info('opportunity stage has not changed');
// Stage remains as current.
$callStage = $opportunityStage;
}
}
}
if ($crmProviderId) {
// Cast $crmProviderId to string otherwise it won't use database index for some records
$linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();
// Check if this activity has already been assigned to a different activity.
if ($linkedActivity && $linkedActivity->id !== $activity->id) {
throw new InvalidArgumentException(
'Sorry, the linked task has already been logged under a different call. '
. 'Please choose another linked task.'
);
}
}
} catch (InvalidArgumentException $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($exception->getMessage());
} catch (Exception $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorInternalError(
'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'
);
}
}
if ($categoryId) {
$category = PlaybookCategory::uuid($categoryId);
if ($category->playbook->team_id !== $team->id) {
throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
$this->logger->info('Prospect data', [
'lead_id' => $lead?->getId(),
'account_id' => $account?->getId(),
'contact_id' => $contact?->getId(),
'opportunity_id' => $opportunity?->getId(),
'stage_id' => $stage?->getId(),
]);
if ($title) {
$activity->title = $title;
}
if ($summary) {
$activity->summary = $summary;
}
if ($crmProviderId) {
$activity->crm_provider_id = $crmProviderId;
}
if ($callStage) {
$this->logger->info('Setting stage id', ['stageId' => $callStage->id]);
$activity->stage_id = $callStage->id;
}
if ($lead) {
$this->logger->info('Setting lead id', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
// If we are changed from an account > lead, unset the account data.
$this->logger->info('Unsetting account id, opportunity id, contact id, value');
$activity->account_id = null;
$activity->opportunity_id = null;
$activity->contact_id = null;
$activity->value = null;
}
if ($account) {
$this->logger->info('Setting account id', ['accountId' => $account->id]);
$activity->account_id = $account->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('unsetting lead id');
$activity->lead_id = null;
// Unset the contact if switching different accounts. Will be set up below if still applicable.
if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {
$this->logger->info('Unsetting contact id');
$activity->contact_id = null;
}
}
if ($opportunity) {
$this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);
$this->logger->info('unsetting lead id');
$activity->opportunity_id = $opportunity->id;
$activity->value = $opportunity->value;
// If we are changed from an lead > account, unset the lead data.
$activity->lead_id = null;
}
if ($contact) {
$this->logger->info('setting contact id', ['contactId' => $contact->id]);
$activity->contact_id = $contact->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('Unsetting lead id');
$activity->lead_id = null;
}
$activity->is_internal = $isInternal;
$activity->save();
$activity->refresh();
$this->logger->notice('Activity saved', [
'activity_id' => $activity->getId(),
'lead_id' => $activity->lead_id,
'account_id' => $activity->account_id,
'contact_id' => $activity->contact_id,
'opportunity_id' => $activity->opportunity_id,
'stage_id' => $activity->stage_id,
'crm_provider_id' => $activity->getCrmProviderId(),
]);
// Store entities as field data on the activity.
$updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);
if ($activity->isLoggable()) {
// Follow-up Task or Event data.
$followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);
$this->logger->info('CRM LOG manual log triggered', [
'activityId' => $activity->getUuid(),
'followupData' => $followupData,
'userId' => $user->getUuid(),
]);
// Store data in the CRM.
// ++add check for crm_required
$job = new SaveActivity($activity, $followupData);
if ($updatedData) {
$job->delay(Carbon::now()->addMinutes($jobDelay));
}
dispatch($job);
// Manually dispatch log for Opportunity or Prospect added
if ($activity->hasOpportunity() || $activity->hasProspect()) {
event(new ActivityProspectAdded(
activity: $activity,
eventSource: 'manually-log-crm-data'
));
}
}
return $this->response->withOk();
}
/**
* Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.
*
* @param ServiceInterface $service
* @param Activity $activity
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array
{
$updatedData = [];
$existingData = $activity->data()->get();
// We need to delete any existing data to overwrite with latest values.
$activity->data()->delete();
$layoutEntities = $layout->entities()
->with('field', 'parent')
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->get();
/** @var LayoutEntity $entity */
foreach ($layoutEntities as $entity) {
// If the user has provided a value for this entity
if (array_key_exists($entity->id_string, $entities)) {
$value = $entities[$entity->id_string];
// Convert raw data into values that the CRM can consume.
if ($value) {
$value = $service->normalizeValue($entity->field->type, $value);
}
// Check the field is part of the activity-summary section.
if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {
// This is the internal database ID, not the external CRM ID.
$objectId = null;
switch ($entity->field->object_type) {
case Field::OBJECT_ACCOUNT:
$objectId = $activity->account_id;
break;
case Field::OBJECT_CONTACT:
$objectId = $activity->contact_id;
break;
case Field::OBJECT_OPPORTUNITY:
$objectId = $activity->opportunity_id;
break;
case Field::OBJECT_LEAD:
$objectId = $activity->lead_id;
break;
case Field::OBJECT_TASK:
case Field::OBJECT_EVENT:
$objectId = $activity->id;
break;
}
if ($objectId) {
/** @var FieldData $data */
$data = $activity->data()->create([
'crm_layout_entity_id' => $entity->id,
'crm_field_id' => $entity->crm_field_id,
'object_type' => $entity->field->object_type,
'object_id' => $objectId,
'value' => $value,
]);
// Never send read-only field data to the CRM.
if ($entity->read_only === false && $entity->is_visible) {
$existingValue = $existingData
->where('crm_layout_entity_id', $entity->id)
->where('crm_field_id', $entity->crm_field_id)
->where('object_type', $entity->field->object_type)
->where('object_id', $objectId)
->first();
// If the field was actually changed, we need to reflect this in the CRM too.
if ($existingValue === null || $existingValue->value !== $value) {
$updatedData[] = $data->id;
}
}
}
}
}
}
return $updatedData;
}
/**
* Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.
*
* @param ServiceInterface $crmService
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array
{
$fieldData = [];
foreach ($entities as $entityId => $value) {
// Only bother with fields that have a value.
if ($value) {
// Extract the entity from the UUID. Check the field is valid and part of the follow-up section.
$entity = $layout->entities()
->uuid($entityId, false)
->whereHas('parent', function ($query) {
$query->where('label', 'follow-up');
})
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->first();
if ($entity) {
// Convert raw data into values that the CRM can consume.
$value = $crmService->normalizeValue($entity->field->type, $value);
// Add the field and value to the payload.
$fieldData += [
$entity->field->crm_provider_id => $value,
];
}
}
}
return $fieldData;
}
/**
* @param Activity $activity
*/
private function validateSummary(Activity $activity): void
{
$team = $activity->user->team;
$crmProvider = $team->crm->provider;
$attributes = [];
$rules = [
'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,
'title' => 'string|max:250',
'prospects' => 'required|array',
'opportunity_id' => new CrmReference($crmProvider),
'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',
'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator
'summary' => 'max:50000',
'nId' => 'exists:notifications,id',
'crm_id' => new CrmReference($crmProvider),
'entities' => 'array',
'is_internal' => 'boolean',
];
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));
// Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.
$entities = $layout->entities()
->where('read_only', 0)
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->whereHas('parent', function ($query) use ($activity) {
if ($activity->isLoggable() === false) {
$query->where('label', '<>', 'follow-up');
}
});
$isInternal = $this->request->input('is_internal', false);
foreach ($entities->get() as $entity) {
$rules += $this->buildFieldValidator($entity, $isInternal);
$attributes += $this->buildFieldMessage($entity);
}
$this->request->validate($rules, [], $attributes);
}
private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array
{
return [
'entities.' . $entity->id_string => $entity->getValidator($isInternal),
];
}
/**
* @param LayoutEntity $entity
*
* @return array
*/
private function buildFieldMessage(LayoutEntity $entity): array
{
$label = $entity->label;
if ($label === null) {
$label = $entity->field->label;
}
return [
'entities.' . $entity->id_string => $label,
];
}
public function search(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->debugLog(
$user,
'User extracted from request',
['user' => $user->getId(), 'tz' => $user->getTimezone()]
);
$searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());
$this->debugLog(
$user,
'ActivitySearch criteria built',
['searchCriteria' => $searchCriteria]
);
$filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);
$this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);
$this->validateSearch($request, $filterSet);
$this->debugLog($user, 'Request validated');
$searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);
/** @var Collection<Activity> $activities */
$activities = $searchResponse['results'];
$this->debugLog($user, 'Activities ES response extracted');
$hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(
$user->getTeamId(),
TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),
);
if ($hideInternalMeetingsSetting?->getValue() === '1') {
$activities = $activities->filter(function (Activity $activity) {
if ($activity->is_internal && empty($activity->actual_start_time)) {
return false;
}
return true;
});
}
$this->debugLog($user, 'Internal meetings (?!) filtered');
$this->response->getManager()
->parseIncludes([
'category',
'organizer.group',
'prospect',
'stage',
'opportunity',
'stats',
'scorecards',
'masterTrack',
'activeParticipants',
'notification',
])
->setSerializer(new JsonSerializer());
$transformerExcludes = $this->request->input('exclude');
if ($transformerExcludes) {
$this->response->getManager()->parseExcludes($transformerExcludes);
}
$this->debugLog($user, 'Response Manager (?!) applied');
$transformer = new ActivityTransformer();
$transformer->setConsumer($user);
$this->debugLog($user, 'Activity Transformer added');
$resource = new \League\Fractal\Resource\Collection($activities, $transformer);
$page = $searchCriteria->getPageNumber();
$this->debugLog($user, 'Search criteria page number called', ['page' => $page]);
$histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');
$this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);
return $this->response->withArray([
'pagination' => [
'total' => $searchResponse['totalHits'],
'current' => $page,
'prev' => max($page - 1, 1),
'next' => $page + 1,
],
'results' => $this->response->getManager()->createData($resource)->toArray(),
'histogram' => $histogram,
]);
}
private function debugLog(User $user, string $logMessage, ?array $context = []): void
{
// Debug for Learning People Only
if ($user->getTeamId() !== 260) {
return;
}
Log::notice(
sprintf('[activity-search-controller] %s', $logMessage),
$context
);
}
/** @throws ValidationException */
private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void
{
$rules = [
'exclude' => 'array',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
];
if ($prefix !== null && mb_strpos($prefix, '.') !== false) {
$rules[rtrim($prefix, '.')] = sprintf(
'required|array|max:%d',
$filterSet->count()
);
}
$validationRules = $filterSet->getValidationRules($prefix)
->merge($rules)
->all();
$request->validate($validationRules);
}
public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$search = $this->updateOrCreateActivitySearch($request);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function updateActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('update', $search);
$this->updateOrCreateActivitySearch($request, $search);
return $this->response->withOk();
}
private function storeNamedSearchFilters(
Collection $request,
Search $search,
FilterDefinitionCollection $filterSet,
?string $prefix = null,
): self {
$arrayTypeProperties = $filterSet
->getPropertyTypes([
FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,
])
->all();
$supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);
foreach ($supportedRequestProperties as $requestPropertyName) {
if (! array_has($request, $requestPropertyName)) {
continue;
}
/** @var string|string[] $propertyValue */
$propertyValue = array_get($request, $requestPropertyName);
$propertyName = $prefix === null
? $requestPropertyName
: mb_substr($requestPropertyName, mb_strlen($prefix));
$isArrayType = array_has($arrayTypeProperties, $propertyName);
if (! $isArrayType) {
/** @var string $requestPropertyValue */
$search->filters()->updateOrCreate(
[
'filter' => $propertyName,
],
[
'value' => $propertyValue,
]
);
continue;
}
/** @var string[] $requestPropertyValue */
/** @var SearchFilter[]|Collection $existingFilterValues */
$existingFilterValuesKeyed = $search->filters()
->where('filter', $propertyName)
->get()
->keyBy('id');
// Iterate over values provided as request parameters
foreach ($propertyValue as $value) {
/** @var SearchFilter|null $valueFilter */
$valueFilter = $search->filters()
->where(
[
'filter' => $propertyName,
'value' => $value,
]
)
->first();
if ($valueFilter !== null) {
// Remove filter value pair from list to be deleted
$existingFilterValuesKeyed->forget($valueFilter->id);
} else {
// Add new filter/value pair
$search->filters()->updateOrCreate([
'filter' => $propertyName,
'value' => $value,
]);
}
}
// Delete filter value pairs for this filter that no longer exist in request parameters
foreach ($existingFilterValuesKeyed as $existingFilter) {
$existingFilter->delete();
}
}
/** @var Collection<int, SearchFilter> $filtersKeyed */
$filtersKeyed = $search->filters()->get()->keyBy('filter');
// wipe removed filters from this search
foreach ($filtersKeyed as $filterName => $filter) {
if (array_has($request, $prefix . $filterName)) {
continue;
}
// Remove all filter values for this filter
$search->filters()->where('filter', $filterName)->delete();
}
return $this;
}
/**
* @throws AuthorizationException
*/
public function fetchActivitySearch(
Search $search,
Request $request,
SearchTransformer $searchTransformer,
): JsonResponse {
$this->authorize('view', $search);
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withCollection(
$user->searches()->get(),
$searchTransformer
->withConsumer($user)
);
}
/**
* Deletes a saved search
*
* @param Request $request
* @param Search $search
*
* @throws Exception
*
* @return JsonResponse
*/
public function deleteActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('delete', $search);
// Orphan any AutomatedReports that use this search
$search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);
// Delete filters and the search itself
$search->filters()->delete();
$search->delete();
return $this->response->withOk();
}
public function live(Request $request, ElasticActivityRepository $repository): JsonResponse
{
$user = $this->getUserFromRequest($request);
$this->request->validate([
'sort_direction' => 'in:asc,desc',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
]);
$activities = $repository->getLiveCoachingEligibleActivities(
user: $user,
lookBackMinutes: self::LOOK_BACK,
limit: (int) $this->request->input('limit', 25),
page: (int) $this->request->input('page', 1),
sortBy: ['actual_start_time', 'scheduled_start_time'],
sortDirection: (string) $this->request->input('sort_direction', 'asc'),
);
$this->response
->getManager()
->parseIncludes(['organizer.group', 'prospect'])
->setSerializer(new JsonSerializer());
return $this->response->withCollection($activities, new ActivityTransformer());
}
/**
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function show(Activity $activity, ActivityService $activityService): JsonResponse
{
$this->authorize('show', $activity);
$user = $activity->getUser();
$team = $user->getTeam();
// Sync the opportunity with the latest data if possible.
if ($activity->opportunity_id) {
try {
$crmService = $this->providerRegistry->get($team->crm->provider);
if (! $user->isCrmRequired()) {
$crmService->setUser($team->getOwner());
} else {
$crmService->setUser($user);
}
$crmService->syncOpportunity($activity->opportunity->crm_provider_id);
} catch (Exception $exception) {
// Move on.
}
}
$activityData = $activityService->getActivityData($this->request->user(), $activity);
return response()->json($activityData);
}
public function createRecording(Activity $activity)
{
$this->authorize('record', $activity);
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Tell Twilio to start recording this activity.
if ($activity->recording_state === Activity::RECORDING_OFF) {
$job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withCreated();
}
return $this->response->errorGone('Activity is already recording.');
}
public function updateRecording(Request $request, Activity $activity)
{
$this->authorize('record', $activity);
$request->validate([
'preference' => 'boolean',
'state' => [
'string',
Rule::in([
Activity::RECORDING_IN_PROGRESS,
Activity::RECORDING_PAUSED,
]),
],
]);
if ($request->has('state')) {
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Toggle the recording state between paused and resumed.
if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {
$job = (new ToggleRecording($activity, $request->input('state')))
->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Recording is not toggleable.');
}
if ($request->has('preference')) {
$activity->update([
'recording_preference' => $request->input('preference') ? 1 : 0,
]);
return $this->response->withOk();
}
return $this->response->errorWrongArgs('Something went wrong');
}
public function stopRecording(Activity $activity)
{
$this->authorize('stopRecord', $activity);
// Tell Twilio to stop recording this activity.
if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {
$job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Activity is not recording.');
}
/**
* Add activity to this user's favorites playlist
*
* @throws AuthorizationException
*/
public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse
{
$this->authorize('favorite', $activity);
$user = $this->getUserFromRequest($this->request);
$favorite = $activity->wasFavoritedBy($user);
$name = $activity->activity_title ?? '';
// It needs to check at least one record.
if (! $favorite) {
$favoritePlaylist = $user->favoritePlaylist();
$playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(
$activity,
$user,
$favoritePlaylist
);
if ($playlistActivity !== null) {
$playlistActivity->update(
// Just update, don't sort.
['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],
);
} else {
$playlistActivity = $activity->playlistActivities()->create([
'playlist_id' => $favoritePlaylist->getId(),
'user_id' => $user->getId(),
'start_time' => 0,
'name' => mb_strimwidth($name, 0, 100),
]);
// Sort it on top.
$playlistActivity->update(
[
'sort' => $playlistActivityRepository->calculateNewSortOrder(
null,
$playlistActivity,
),
],
);
}
$playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);
return new JsonResponse([], JsonResponse::HTTP_CREATED);
}
return new JsonResponse(
[
'error' => [
'code' => AbstractResponse::CODE_CONFLICT,
'http_code' => JsonResponse::HTTP_CONFLICT,
'message' => 'Resource Already Exists',
],
],
JsonResponse::HTTP_CONFLICT,
);
}
/**
* Remove activity from this user's favorites playlist
*
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function unfavorite(Activity $activity)
{
$user = $t...
|
32860
|
NULL
|
NULL
|
NULL
|
|
32863
|
1254
|
30
|
2026-05-13T09:41:40.988243+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665300988_m1.jpg...
|
PhpStorm
|
faVsco.js – ActivityController.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
SlackFile Edit ViewGoHistoryWindowHelpAPPDOCKER₴81 SlackFile Edit ViewGoHistoryWindowHelpAPPDOCKER₴81DEV (docker)₴82APP (-zshtests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleterTest.phptests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesProviderTest.phptests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesUploaderTest.phptests/Unit/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeeches?tests/Unit/Component/Transcription/Diarization/Source/MeetingBotSourceTest.phptests/Unit/Contracts/Services/Calendar/CalendarTraitTest.phptests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.phptests/Unit/Jobs/Activity/Import/ImportTwilioVideoSpeechesJobTest.phptests/Unit/Jobs/Activity/Import/IsActivityReadyForProcessingJobTest.phptests/Unit/Jobs/Calendar/SetupCalendarSyncTest.phptests/Unit/Services/Activity/ParticipantsServiceTest.phptests/Unit/Services/Calendar/Command/ImportParticipantsTest.phptests/Unit/Services/Calendar/GoogleCalendarServiceTest.phptests/Unit/Services/Crm/Close/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTest.phptests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTraitMatchActivitiesTest.phytests/Unit/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTraitOpportunitiesTe:tests/Unit/Services/Crm/Pipedrive/ImportOpportunityMatchActivitiesTest.phptests/Unit/Services/Crm/Salesforce/ServiceTest.phptests/Unit/Services/Mail/0ffice/EmailApiClientTest.phptests/Unit/Services/RecallAI/RecallAIServiceTest.php113 files changed, 4143 insertions(+), 1740 deletions(-)create mode 120000 CLAUDE.mdcreate mode 100644 app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.phpdelete mode 100644 app/Component/ES/ElasticSearchWorkerManager.phpdelete mode 100644 app/Component/ES/Worker/ActivityWorker.phpdelete mode 100644 app/Component/ES/Worker/EntityWorker.phpdelete mode100644 app/Component/ES/Worker/WorkerAmount.phpdelete mode100644 app/Component/ES/Worker/WorkerInterface.phpcreate mode100644 app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.phtcreate mode100644 app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/Assembl:create mode100644 app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNot(create mode 100644 app/Console/Commands/Crm/Backfill0pportunityUserFromAccountCommand.phpdelete mode 100644 app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.phpcreate mode100644 front-end/src/components/shared/modals/EntityPickerModal/__tests__/uscreate mode 100644 tests/Feature/Component/Nudge/Process0rganisationImmediateNudgesJobTe:create mode 100644 tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheck‹delete mode 100644 tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/ActivityWorkerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/EntityWorkerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/WorkerAmountTest.phpcreate mode 100644 tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCrcreate mode 100644 tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.phpLukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ I|HomeDMsActivityFilesLaterMore(aol• Support Daily - in 2 h 19 m100% <78•Wed 13 May 12:41:40ED→Describe what you are looking forJiminny ...cunoartylau# engineering# general# jiminny-bg# platform-tickets# product_launches#random# releases# sofia-office# support# thank-yous# the_people_of jimi...° Direct messages& Nikolay Ivanovdo James Graham. Stoyan Tanev. Galya Dimitrova. Steliyan GeorgievPetko KashinskiP. Aneliya Angelovaã. Stefka Stoyanova•. Vasil Vasilev •!Lukas Kovalik y...AppsJira CloudToastNikolay Ivanov6 0MessagesAdd canvas@ Files+Lukas Kovalik 11.Today ~мен все ме праща наhttps://app.vanta.com/c/jiminny.com/employee/onboardingNikolay Ivanov 11:01 AMХм, Джейс дали не може да ти помогне?Lukas Kovalik 11:01 AMще питам James, предполагам че нямам правада мерсиNikolay Ivanov 11:01 AMмдаМОЛЯLukas Kovalik 12:13 PMНики сори, още един въпрос имамкогато ги правеше ти FE ли оправяима vulnerabilities no npmNikolay Ivanov 12:28 PMнетях ги оставямLukas Kovalik 12:29 PMаз погледнах твоя тикет и там друго нямашесамо FEкак стигна до WorkerMessage Nikolay Ivanov...
|
NULL
|
1841537372112977156
|
NULL
|
idle
|
ocr
|
NULL
|
SlackFile Edit ViewGoHistoryWindowHelpAPPDOCKER₴81 SlackFile Edit ViewGoHistoryWindowHelpAPPDOCKER₴81DEV (docker)₴82APP (-zshtests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleterTest.phptests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesProviderTest.phptests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesUploaderTest.phptests/Unit/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeeches?tests/Unit/Component/Transcription/Diarization/Source/MeetingBotSourceTest.phptests/Unit/Contracts/Services/Calendar/CalendarTraitTest.phptests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.phptests/Unit/Jobs/Activity/Import/ImportTwilioVideoSpeechesJobTest.phptests/Unit/Jobs/Activity/Import/IsActivityReadyForProcessingJobTest.phptests/Unit/Jobs/Calendar/SetupCalendarSyncTest.phptests/Unit/Services/Activity/ParticipantsServiceTest.phptests/Unit/Services/Calendar/Command/ImportParticipantsTest.phptests/Unit/Services/Calendar/GoogleCalendarServiceTest.phptests/Unit/Services/Crm/Close/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTest.phptests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTraitMatchActivitiesTest.phytests/Unit/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTraitOpportunitiesTe:tests/Unit/Services/Crm/Pipedrive/ImportOpportunityMatchActivitiesTest.phptests/Unit/Services/Crm/Salesforce/ServiceTest.phptests/Unit/Services/Mail/0ffice/EmailApiClientTest.phptests/Unit/Services/RecallAI/RecallAIServiceTest.php113 files changed, 4143 insertions(+), 1740 deletions(-)create mode 120000 CLAUDE.mdcreate mode 100644 app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.phpdelete mode 100644 app/Component/ES/ElasticSearchWorkerManager.phpdelete mode 100644 app/Component/ES/Worker/ActivityWorker.phpdelete mode 100644 app/Component/ES/Worker/EntityWorker.phpdelete mode100644 app/Component/ES/Worker/WorkerAmount.phpdelete mode100644 app/Component/ES/Worker/WorkerInterface.phpcreate mode100644 app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.phtcreate mode100644 app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/Assembl:create mode100644 app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNot(create mode 100644 app/Console/Commands/Crm/Backfill0pportunityUserFromAccountCommand.phpdelete mode 100644 app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.phpcreate mode100644 front-end/src/components/shared/modals/EntityPickerModal/__tests__/uscreate mode 100644 tests/Feature/Component/Nudge/Process0rganisationImmediateNudgesJobTe:create mode 100644 tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheck‹delete mode 100644 tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/ActivityWorkerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/EntityWorkerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/WorkerAmountTest.phpcreate mode 100644 tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCrcreate mode 100644 tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.phpLukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ I|HomeDMsActivityFilesLaterMore(aol• Support Daily - in 2 h 19 m100% <78•Wed 13 May 12:41:40ED→Describe what you are looking forJiminny ...cunoartylau# engineering# general# jiminny-bg# platform-tickets# product_launches#random# releases# sofia-office# support# thank-yous# the_people_of jimi...° Direct messages& Nikolay Ivanovdo James Graham. Stoyan Tanev. Galya Dimitrova. Steliyan GeorgievPetko KashinskiP. Aneliya Angelovaã. Stefka Stoyanova•. Vasil Vasilev •!Lukas Kovalik y...AppsJira CloudToastNikolay Ivanov6 0MessagesAdd canvas@ Files+Lukas Kovalik 11.Today ~мен все ме праща наhttps://app.vanta.com/c/jiminny.com/employee/onboardingNikolay Ivanov 11:01 AMХм, Джейс дали не може да ти помогне?Lukas Kovalik 11:01 AMще питам James, предполагам че нямам правада мерсиNikolay Ivanov 11:01 AMмдаМОЛЯLukas Kovalik 12:13 PMНики сори, още един въпрос имамкогато ги правеше ти FE ли оправяима vulnerabilities no npmNikolay Ivanov 12:28 PMнетях ги оставямLukas Kovalik 12:29 PMаз погледнах твоя тикет и там друго нямашесамо FEкак стигна до WorkerMessage Nikolay Ivanov...
|
32861
|
NULL
|
NULL
|
NULL
|
|
32864
|
1255
|
40
|
2026-05-13T09:41:42.619019+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665302619_m2.jpg...
|
PhpStorm
|
faVsco.js – ActivityController.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhostormProiect vVIeWINavicareCodeLaravelKeractorT PhostormProiect vVIeWINavicareCodeLaravelKeractorTOOISWindowFV faVsco.js"9 master~(C ActivityController.pnp|aravel.l0gA SF (jiminny@localhost]4 HS_local [jiminny@localhost]& console (PROD] X A console [EU]D Teaminsights, m Themesv D UserAutomatedRep -007final class ActivityController extends Controller implements CommentContextInterfaceA console [STAGING]v Dv2c) ACuviLyvzconuroAskAnythingCorLL0/(C) AskJiminnyRepc© DealsV2Controll 410%(C) OnDemandV2Cc€ PlavlistControlleC) PlavlistSharecorC PlavlistTrackCor111131114(C) UoloadControlleC) [EMAIL]) AiCrmNotesControl(c) Rasecontroller nhn@ ClientTokenControl 1157(e) CrmController.pnp11158© DealLevelPromptsC 115$c) DealRiskcontroller.@ InctantMeetinaCont 116111164C) Languagecontrolle© LayoutManagemen 1163Ca) livoCoodControllor1164 |9© MeetingsController 1192© MessageController. 1193 l >C MotadataControllor L214© MobileSettingsCont 1212 (g >© MomentController.r 125gc) Nudgecontroller.phNumberAllocatorCc 12/e11271OraanizationMembi 1212C) OraanizationRetentC) OraanizationSvnce@ PartnerController.o1276 1g) PlavbackController1133480 PlavlictController pl 1335g ScimController.nhn9) SidekickController , 13379a) SoftnhoneControlle© SsoController.php(e) CnbccrintionGontrae ToamAiAutomationt6) ToamAiContovtCar0 ToamControllor nhr 1343 (@9 >public function ListActivitySearch(Request Srequest, SearchTransformer SsearchTransformer): JsonResponses: 569— 571* Deletes a saved search— 573* @param Request $request* apanam Search $search575* achrows except1or* drecurn Jsonkesponse-57%578579— 580pubLic tunccion deleteActivicysearch kequest srequest, search ssearch: Jsonkesponse.582oubunc tunction uivelrequest srequest, clastcactIvirvkedosirory srepostrory: usonkesponse....* dparam Activitu Sactivitu*Gthrows_AuthorizationExcent.ion589* Greturn mixedpublic function show(Activity Sactivity, ActivityService $activityService): JsonResponse{...}public function createRecordingActivity Sactivity)i...h597593594public function updateRecording(Request Srequest, Activity $activity)1...h~ 596public function stopRecording(Activity Sactivity)(...}* Add activity to this user's favorites playlist_ 601=602* athrows AuthorizationException604public function favorite(Activity Sactivitv. PlavlistActivitvRepository SolavlistActivitvRepositorv): J501605606=607* Remove activitu from this user's favorites plaulisti60S•Goarom Actvatu sactvitu*athrowsAuthorizationExcent.ion* Greturn mixednublic function unfavorite Activitv Sactivitv)-Tx: AutovCONCAT(u.id, CASE WHEN U.id = t.owner_id THEN ' (owner)' ELSE'' END) AS user_id,sa.*t.owner_id FROM social_accounts saNolN usens u on u.id e sa.sociablle i.diJOIN teams t .n<->l: on t.id = u.team_icWHERE u.team_id = 581 and sa.provider = 'salesforce';SELECT * FROM automated_report_results order by id desc;select * from features;select * from team_features where feature_id = 40;select * from teams where id = 556:select * from automated_reports:where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044"pat", "podcast"]SELECT * FROM automated report_ results WHERE uuid to bin( '822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid:select * from automated_report_results order by za desc;SELECT * FROM automated report resultsWHEkE 10 =17141select * from automated report results WHERE report id = 54:select * from opportunities where 1d = 75943494SELE * FROM teams WHERE name LIKE "%Les%': # 711, 692. 16067 - Timinnvintearationdlesmils.comselect * from playbooks where team id = 711: # event 226147SELEd * FROM Davbook catedonies WHERE Dlavbook 10 e 55151SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_typeSELECT * EROM eom fields WHERE 1d = 226147÷SELECT * EROM eom field values WHERE com field 1d = 226147.SELECT * FROM crm_configurations WHERE id = 692;SEISCTCONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '• END) AS user_id,nemailiSa.xt.owner id FROM social accounts saJOIN users u on u.id = sa.sociable idJOIN teams t 1..n<->1: on t.id = u.team_idWHERE U.team id = 711 and sa.provider = 'salesforce':SELECT * FROM crm profiles co JOIN users u 1..n<->1: on u.id = co.user id WHERE u.team_id = 711:select * from leads:select * from calendars:SELECTSo jiminny4041440 X.04 AS0 hl• suppon Dally • In Zn 15m100% S2• Wed 13 May 12:41:42AskJiminnyReportActivityServiceTest vTrial Owner Role Senoices should only be - Recorder, Recorder & Voice, Analysithis option shouldn't appear when editing an organisation+0 ..I'II review the current flow for the trial creation and owner role assianment. Let me create a oian and investigate the1) Find Create Team / trial creation logic in backendUnderstand current owner role assianment flowLocate Import Opportunities Sync Period field locationSind frontend Create Team comnonentiReview current role assignment when owner signs inhought for 1sSearched Create TeamlcreateTeam in ~fiiminnvlabolSearched owner.*role|ownerRole in ~/jiminny/appSearched Imoort Opportunities Svnc Periodlimoort "opportunities "svnc in ~/iminnvlaodsearched controller.onp and pertormed 1 otner quenyAnalyzed app/nutp/controttersSearched Recorder"rolelrole *Recorder in ~/iminnvlaorInought tor isThought for 2s >1/5 tasks done21 Understand current owner role assianment flowSearched class UserinvitationDTO in ~fiminny/appCoarchod pol e pecopnepipole analyctipole pecOpnep AND VOICE in cfliminnulonnAsk anvthina (84L)"Code SWF-1.6WN Windsurf Toams 1120-1UTF.8Po 4 spaces...
|
NULL
|
1616305956126243712
|
NULL
|
idle
|
ocr
|
NULL
|
PhostormProiect vVIeWINavicareCodeLaravelKeractorT PhostormProiect vVIeWINavicareCodeLaravelKeractorTOOISWindowFV faVsco.js"9 master~(C ActivityController.pnp|aravel.l0gA SF (jiminny@localhost]4 HS_local [jiminny@localhost]& console (PROD] X A console [EU]D Teaminsights, m Themesv D UserAutomatedRep -007final class ActivityController extends Controller implements CommentContextInterfaceA console [STAGING]v Dv2c) ACuviLyvzconuroAskAnythingCorLL0/(C) AskJiminnyRepc© DealsV2Controll 410%(C) OnDemandV2Cc€ PlavlistControlleC) PlavlistSharecorC PlavlistTrackCor111131114(C) UoloadControlleC) [EMAIL]) AiCrmNotesControl(c) Rasecontroller nhn@ ClientTokenControl 1157(e) CrmController.pnp11158© DealLevelPromptsC 115$c) DealRiskcontroller.@ InctantMeetinaCont 116111164C) Languagecontrolle© LayoutManagemen 1163Ca) livoCoodControllor1164 |9© MeetingsController 1192© MessageController. 1193 l >C MotadataControllor L214© MobileSettingsCont 1212 (g >© MomentController.r 125gc) Nudgecontroller.phNumberAllocatorCc 12/e11271OraanizationMembi 1212C) OraanizationRetentC) OraanizationSvnce@ PartnerController.o1276 1g) PlavbackController1133480 PlavlictController pl 1335g ScimController.nhn9) SidekickController , 13379a) SoftnhoneControlle© SsoController.php(e) CnbccrintionGontrae ToamAiAutomationt6) ToamAiContovtCar0 ToamControllor nhr 1343 (@9 >public function ListActivitySearch(Request Srequest, SearchTransformer SsearchTransformer): JsonResponses: 569— 571* Deletes a saved search— 573* @param Request $request* apanam Search $search575* achrows except1or* drecurn Jsonkesponse-57%578579— 580pubLic tunccion deleteActivicysearch kequest srequest, search ssearch: Jsonkesponse.582oubunc tunction uivelrequest srequest, clastcactIvirvkedosirory srepostrory: usonkesponse....* dparam Activitu Sactivitu*Gthrows_AuthorizationExcent.ion589* Greturn mixedpublic function show(Activity Sactivity, ActivityService $activityService): JsonResponse{...}public function createRecordingActivity Sactivity)i...h597593594public function updateRecording(Request Srequest, Activity $activity)1...h~ 596public function stopRecording(Activity Sactivity)(...}* Add activity to this user's favorites playlist_ 601=602* athrows AuthorizationException604public function favorite(Activity Sactivitv. PlavlistActivitvRepository SolavlistActivitvRepositorv): J501605606=607* Remove activitu from this user's favorites plaulisti60S•Goarom Actvatu sactvitu*athrowsAuthorizationExcent.ion* Greturn mixednublic function unfavorite Activitv Sactivitv)-Tx: AutovCONCAT(u.id, CASE WHEN U.id = t.owner_id THEN ' (owner)' ELSE'' END) AS user_id,sa.*t.owner_id FROM social_accounts saNolN usens u on u.id e sa.sociablle i.diJOIN teams t .n<->l: on t.id = u.team_icWHERE u.team_id = 581 and sa.provider = 'salesforce';SELECT * FROM automated_report_results order by id desc;select * from features;select * from team_features where feature_id = 40;select * from teams where id = 556:select * from automated_reports:where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044"pat", "podcast"]SELECT * FROM automated report_ results WHERE uuid to bin( '822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid:select * from automated_report_results order by za desc;SELECT * FROM automated report resultsWHEkE 10 =17141select * from automated report results WHERE report id = 54:select * from opportunities where 1d = 75943494SELE * FROM teams WHERE name LIKE "%Les%': # 711, 692. 16067 - Timinnvintearationdlesmils.comselect * from playbooks where team id = 711: # event 226147SELEd * FROM Davbook catedonies WHERE Dlavbook 10 e 55151SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_typeSELECT * EROM eom fields WHERE 1d = 226147÷SELECT * EROM eom field values WHERE com field 1d = 226147.SELECT * FROM crm_configurations WHERE id = 692;SEISCTCONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '• END) AS user_id,nemailiSa.xt.owner id FROM social accounts saJOIN users u on u.id = sa.sociable idJOIN teams t 1..n<->1: on t.id = u.team_idWHERE U.team id = 711 and sa.provider = 'salesforce':SELECT * FROM crm profiles co JOIN users u 1..n<->1: on u.id = co.user id WHERE u.team_id = 711:select * from leads:select * from calendars:SELECTSo jiminny4041440 X.04 AS0 hl• suppon Dally • In Zn 15m100% S2• Wed 13 May 12:41:42AskJiminnyReportActivityServiceTest vTrial Owner Role Senoices should only be - Recorder, Recorder & Voice, Analysithis option shouldn't appear when editing an organisation+0 ..I'II review the current flow for the trial creation and owner role assianment. Let me create a oian and investigate the1) Find Create Team / trial creation logic in backendUnderstand current owner role assianment flowLocate Import Opportunities Sync Period field locationSind frontend Create Team comnonentiReview current role assignment when owner signs inhought for 1sSearched Create TeamlcreateTeam in ~fiiminnvlabolSearched owner.*role|ownerRole in ~/jiminny/appSearched Imoort Opportunities Svnc Periodlimoort "opportunities "svnc in ~/iminnvlaodsearched controller.onp and pertormed 1 otner quenyAnalyzed app/nutp/controttersSearched Recorder"rolelrole *Recorder in ~/iminnvlaorInought tor isThought for 2s >1/5 tasks done21 Understand current owner role assianment flowSearched class UserinvitationDTO in ~fiminny/appCoarchod pol e pecopnepipole analyctipole pecOpnep AND VOICE in cfliminnulonnAsk anvthina (84L)"Code SWF-1.6WN Windsurf Toams 1120-1UTF.8Po 4 spaces...
|
32860
|
NULL
|
NULL
|
NULL
|
|
32865
|
1254
|
31
|
2026-05-13T09:42:13.455852+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665333455_m1.jpg...
|
PhpStorm
|
faVsco.js – ActivityController.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use Carbon\Carbon;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\In;
use Illuminate\Validation\ValidationException;
use InvalidArgumentException;
use Jiminny\Component\ActivityAnalytics;
use Jiminny\Component\ActivitySearch;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Queue\Constants;
use Jiminny\Contracts\ES\Events\UpdateSingleEntity;
use Jiminny\Contracts\ES\UpdateTargetEnum;
use Jiminny\Contracts\Nudge\NudgeFactoryInterface;
use Jiminny\Contracts\Playlist\PlaylistTrackFactoryInterface;
use Jiminny\Contracts\Repositories\PlaylistActivityRepository;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Enums\TeamSetting;
use Jiminny\Events\Activities\AiAutomation\ActivityProspectAdded;
use Jiminny\Events\Activities\Coaching\Coached;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Controllers\CommentContextInterface;
use Jiminny\Http\Responses\Api\AbstractResponse;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\ActivityCommentTransformer;
use Jiminny\Http\Transformers\ActivityTopicTriggerTransformer;
use Jiminny\Http\Transformers\ActivityTransformer;
use Jiminny\Http\Transformers\AvailabilityNotificationTransformer;
use Jiminny\Http\Transformers\CoachingFeedbackTransformer;
use Jiminny\Http\Transformers\CoachingSectionsTransformer;
use Jiminny\Http\Transformers\SearchTransformer;
use Jiminny\Http\Transformers\StatsTransformer;
use Jiminny\Jobs\Crm\SaveActivity;
use Jiminny\Jobs\Crm\UpdateStage;
use Jiminny\Jobs\Telephony\StartRecording;
use Jiminny\Jobs\Telephony\StopRecording;
use Jiminny\Jobs\Telephony\ToggleRecording;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\CoachingFeedback;
use Jiminny\Models\CoachingSection;
use Jiminny\Models\CoachingSectionCriterion;
use Jiminny\Models\CoachingSectionFeedback;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\LanguageDialect;
use Jiminny\Models\Lead;
use Jiminny\Models\Nudge;
use Jiminny\Models\PlaybookCategory;
use Jiminny\Models\Playlist;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\Track;
use Jiminny\Models\User;
use Jiminny\Repositories\CoachingFeedbackRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Rules\CrmReference;
use Jiminny\Rules\MultidimensionalArrayMaxCharRule;
use Jiminny\Services\ActivityService;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Services\PlaybackService;
use Jiminny\Services\UserService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
use Ramsey\Uuid\Uuid;
use Sentry;
use Symfony\Component\HttpFoundation;
final class ActivityController extends Controller implements CommentContextInterface
{
// Number of minutes to look back on activities. i.e. a timeout on activity duration.
private const int LOOK_BACK = 180;
public function __construct(
private ProviderRegistry $providerRegistry,
private ActivityService $activityService,
Response $response,
private UserService $userService,
private ActivitySearch\Service\ActivitySearch $activitySearch,
private NudgeFactoryInterface $nudgeFactory,
private ActivityCommentService $activityCommentService,
private LoggerInterface $logger,
private readonly CoachingFeedbackRepository $coachingFeedbackRepository,
private readonly TeamRepository $teamRepository,
) {
parent::__construct($response);
}
public static function getCommentImplementation(): string
{
return Comment::class;
}
public function delete()
{
$this->request->validate([
'*' => 'uuid:activities',
]);
$deletedIds = [];
foreach ($this->request->all() as $activityId) {
$activity = Activity::idOrUuId($activityId);
try {
if ($this->authorize('delete', $activity)) {
$activity->delete();
$deletedIds[] = $activityId;
\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);
}
} catch (AuthorizationException $authorizationException) {
// They didn't have permission.
}
}
return $this->response->withArray($deletedIds);
}
public function update(Request $request, Activity $activity)
{
$this->authorize('updateMetadata', $activity);
$request->validate([
'title' => 'string|max:250',
'category_id' => 'uuid:playbook_categories',
'language' => [
new In(
LanguageDialect::query()
->with('language')
->cursor()
->map(static function (LanguageDialect $languageDialect): string {
return $languageDialect->getLanguageLocale();
})
->all()
),
],
]);
if ($request->has('title')) {
$activity->title = $request->input('title');
}
if ($request->has('category_id')) {
$category = PlaybookCategory::uuid($request->input('category_id'));
if ($category->playbook->team_id !== $request->user()->team_id) {
return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
if ($request->has('language')) {
if (! $activity->isInProgress()) {
return $this->response->withError(
'Activity language can only be set while the meeting is in progress.',
400
);
}
$activity->setLanguageCode($request->input('language'));
}
$activity->save();
return $this->response->withOk();
}
// XXX: This should be merged with the update method.
/**
* @param Activity $activity
*
* @throws AuthorizationException
* @throws SocialAccountTokenInvalidException
*
* @return mixed
*/
public function summarize(Activity $activity): mixed
{
$this->logger->info('[Log Activity] Summarizing activity ', [
'activityId' => $activity->getUuid(),
'payload' => $this->request->all(),
]);
$this->authorize('update', $activity);
$this->logger->info('[Log Activity] Validating summary');
// Validate the payload.
$this->validateSummary($activity);
// All objects must belong to this team.
/** @var User $user */
$user = $this->request->user();
$team = $user->getTeam();
$crmService = $this->providerRegistry->get($team->crm->provider);
try {
$crmUser = $user;
if ($user->isCrmRequired() === false) {
$crmUser = $team->owner;
}
$crmService->setUser($crmUser);
} catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());
}
$rawEntities = $this->request->input('entities');
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid(
$this->request->input('layout_id')
);
// Delay execution of CRM jobs to avoid locking issues.
$jobDelay = 0;
// If we have arrived from a notification, mark it as read.
$notificationId = $this->request->input('nId');
if ($notificationId) {
$notification = $user->unreadNotifications->where('id', $notificationId)->first();
if ($notification) {
$notification->markAsRead();
}
}
$title = $this->request->input('title');
$prospects = $this->request->input('prospects');
$opportunityId = $this->request->input('opportunity_id');
$stageId = $this->request->input('stage_id');
$categoryId = $this->request->input('category_id');
$summary = $this->request->input('summary');
$crmProviderId = $this->request->input('crm_id');
$isInternal = $this->request->input('is_internal') ?? false;
$lead = null;
$category = null;
$account = null;
$contact = null;
$opportunity = null;
$stage = null;
$callStage = null;
foreach ($prospects as $prospectData) {
$objectId = $prospectData['id'];
if ($objectId === null) {
continue;
}
$objectType = $prospectData['type'];
$this->logger->info('debug', ['prospect_data' => $prospectData]);
try {
if ($objectType === null) {
$this->logger->info('no object type');
if ($crmService instanceof SupportsObjectTypeParseInterface) {
$objectType = $crmService->parseObjectType($objectId);
}
}
switch ($objectType) {
case 'lead':
$this->logger->info('Processing lead');
/** @var Lead|null $lead */
$lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();
// Lead does not exist locally, import it.
if ($lead === null) {
$this->logger->info('Lead does not exist locally');
/** @var Lead $lead */
$lead = $crmService->syncLead($objectId);
}
$this->logger->info('Lead found', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
if ($stageId === null) {
$this->logger->info('Stage ID is null');
// If it was not provided, just assume it is the current stage.
$callStage = $lead->stage;
break;
}
$this->logger->info('Looking for stage');
// Determine if they have changed the stage.
/** @var Stage $stage */
$stage = $team->crm->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_LEAD)
->firstOrFail();
$this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);
if ($lead->stage_id && $lead->stage_id !== $stage->id) {
$this->logger->info('Stage has changed');
// Storage current stage on activity.
$callStage = $lead->stage;
// The stage has changed, update in remote CRM.
dispatch(new UpdateStage($activity, $lead, $callStage, $stage));
$this->logger->info(
sprintf(
'[%s] User changing lead stage from %s to %s',
$crmService->getDisplayName(),
$callStage->getName(),
$stage->getName()
),
[
'user' => $user->getUuid(),
'lead' => $lead->getUuid(),
]
);
} else {
$this->logger->info('Stage has not changed');
// Stage remains as current.
$callStage = $stage;
}
break;
case 'account':
$this->logger->info('Processing account');
// If the object is not a lead, it should be an account.
$account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();
// Account does not exist locally, import it.
if ($account === null) {
$this->logger->info('Account does not exist locally');
$account = $crmService->syncAccount($objectId);
}
$this->logger->info('Account found', ['accountId' => $account->id]);
break;
case 'contact':
$this->logger->info('processing contact');
$contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$this->logger->info('contact does not exist locally');
$contact = $crmService->syncContact($objectId);
}
$this->logger->info('resolving account');
$account = $this->resolveAccount($team, $contact, $crmService, $prospects);
break;
}
// If they have specified an opportunity, retrieve this with stage.
if ($opportunityId) {
$this->logger->info('opportunity id is set');
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if ($opportunity === null) {
$this->logger->info('opportunity does not exist locally');
$opportunity = $crmService->syncOpportunity($opportunityId);
}
if ($stageId === null) {
$this->logger->info('stage id is null');
// If it was not provided, just assume it is the current stage.
$callStage = $opportunity->stage ?? null;
} else {
$this->logger->info('looking for stage');
/** @var ?Stage $opportunityStage */
$opportunityStage = $team->crm
->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
// There is a chance we still cannot import this opportunity.
if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {
$this->logger->info('opportunity stage has changed');
// Storage current stage on activity.
$callStage = $opportunity->stage;
dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));
$this->logger->info(
sprintf(
'[%s] User changing opportunity stage from %s to %s',
$crmService->getDisplayName(),
$callStage->name,
$opportunityStage->name
),
[
'userId' => $user->id_string,
'opportunityId' => $opportunity->id_string,
]
);
} else {
$this->logger->info('opportunity stage has not changed');
// Stage remains as current.
$callStage = $opportunityStage;
}
}
}
if ($crmProviderId) {
// Cast $crmProviderId to string otherwise it won't use database index for some records
$linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();
// Check if this activity has already been assigned to a different activity.
if ($linkedActivity && $linkedActivity->id !== $activity->id) {
throw new InvalidArgumentException(
'Sorry, the linked task has already been logged under a different call. '
. 'Please choose another linked task.'
);
}
}
} catch (InvalidArgumentException $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($exception->getMessage());
} catch (Exception $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorInternalError(
'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'
);
}
}
if ($categoryId) {
$category = PlaybookCategory::uuid($categoryId);
if ($category->playbook->team_id !== $team->id) {
throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
$this->logger->info('Prospect data', [
'lead_id' => $lead?->getId(),
'account_id' => $account?->getId(),
'contact_id' => $contact?->getId(),
'opportunity_id' => $opportunity?->getId(),
'stage_id' => $stage?->getId(),
]);
if ($title) {
$activity->title = $title;
}
if ($summary) {
$activity->summary = $summary;
}
if ($crmProviderId) {
$activity->crm_provider_id = $crmProviderId;
}
if ($callStage) {
$this->logger->info('Setting stage id', ['stageId' => $callStage->id]);
$activity->stage_id = $callStage->id;
}
if ($lead) {
$this->logger->info('Setting lead id', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
// If we are changed from an account > lead, unset the account data.
$this->logger->info('Unsetting account id, opportunity id, contact id, value');
$activity->account_id = null;
$activity->opportunity_id = null;
$activity->contact_id = null;
$activity->value = null;
}
if ($account) {
$this->logger->info('Setting account id', ['accountId' => $account->id]);
$activity->account_id = $account->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('unsetting lead id');
$activity->lead_id = null;
// Unset the contact if switching different accounts. Will be set up below if still applicable.
if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {
$this->logger->info('Unsetting contact id');
$activity->contact_id = null;
}
}
if ($opportunity) {
$this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);
$this->logger->info('unsetting lead id');
$activity->opportunity_id = $opportunity->id;
$activity->value = $opportunity->value;
// If we are changed from an lead > account, unset the lead data.
$activity->lead_id = null;
}
if ($contact) {
$this->logger->info('setting contact id', ['contactId' => $contact->id]);
$activity->contact_id = $contact->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('Unsetting lead id');
$activity->lead_id = null;
}
$activity->is_internal = $isInternal;
$activity->save();
$activity->refresh();
$this->logger->notice('Activity saved', [
'activity_id' => $activity->getId(),
'lead_id' => $activity->lead_id,
'account_id' => $activity->account_id,
'contact_id' => $activity->contact_id,
'opportunity_id' => $activity->opportunity_id,
'stage_id' => $activity->stage_id,
'crm_provider_id' => $activity->getCrmProviderId(),
]);
// Store entities as field data on the activity.
$updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);
if ($activity->isLoggable()) {
// Follow-up Task or Event data.
$followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);
$this->logger->info('CRM LOG manual log triggered', [
'activityId' => $activity->getUuid(),
'followupData' => $followupData,
'userId' => $user->getUuid(),
]);
// Store data in the CRM.
// ++add check for crm_required
$job = new SaveActivity($activity, $followupData);
if ($updatedData) {
$job->delay(Carbon::now()->addMinutes($jobDelay));
}
dispatch($job);
// Manually dispatch log for Opportunity or Prospect added
if ($activity->hasOpportunity() || $activity->hasProspect()) {
event(new ActivityProspectAdded(
activity: $activity,
eventSource: 'manually-log-crm-data'
));
}
}
return $this->response->withOk();
}
/**
* Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.
*
* @param ServiceInterface $service
* @param Activity $activity
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array
{
$updatedData = [];
$existingData = $activity->data()->get();
// We need to delete any existing data to overwrite with latest values.
$activity->data()->delete();
$layoutEntities = $layout->entities()
->with('field', 'parent')
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->get();
/** @var LayoutEntity $entity */
foreach ($layoutEntities as $entity) {
// If the user has provided a value for this entity
if (array_key_exists($entity->id_string, $entities)) {
$value = $entities[$entity->id_string];
// Convert raw data into values that the CRM can consume.
if ($value) {
$value = $service->normalizeValue($entity->field->type, $value);
}
// Check the field is part of the activity-summary section.
if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {
// This is the internal database ID, not the external CRM ID.
$objectId = null;
switch ($entity->field->object_type) {
case Field::OBJECT_ACCOUNT:
$objectId = $activity->account_id;
break;
case Field::OBJECT_CONTACT:
$objectId = $activity->contact_id;
break;
case Field::OBJECT_OPPORTUNITY:
$objectId = $activity->opportunity_id;
break;
case Field::OBJECT_LEAD:
$objectId = $activity->lead_id;
break;
case Field::OBJECT_TASK:
case Field::OBJECT_EVENT:
$objectId = $activity->id;
break;
}
if ($objectId) {
/** @var FieldData $data */
$data = $activity->data()->create([
'crm_layout_entity_id' => $entity->id,
'crm_field_id' => $entity->crm_field_id,
'object_type' => $entity->field->object_type,
'object_id' => $objectId,
'value' => $value,
]);
// Never send read-only field data to the CRM.
if ($entity->read_only === false && $entity->is_visible) {
$existingValue = $existingData
->where('crm_layout_entity_id', $entity->id)
->where('crm_field_id', $entity->crm_field_id)
->where('object_type', $entity->field->object_type)
->where('object_id', $objectId)
->first();
// If the field was actually changed, we need to reflect this in the CRM too.
if ($existingValue === null || $existingValue->value !== $value) {
$updatedData[] = $data->id;
}
}
}
}
}
}
return $updatedData;
}
/**
* Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.
*
* @param ServiceInterface $crmService
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array
{
$fieldData = [];
foreach ($entities as $entityId => $value) {
// Only bother with fields that have a value.
if ($value) {
// Extract the entity from the UUID. Check the field is valid and part of the follow-up section.
$entity = $layout->entities()
->uuid($entityId, false)
->whereHas('parent', function ($query) {
$query->where('label', 'follow-up');
})
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->first();
if ($entity) {
// Convert raw data into values that the CRM can consume.
$value = $crmService->normalizeValue($entity->field->type, $value);
// Add the field and value to the payload.
$fieldData += [
$entity->field->crm_provider_id => $value,
];
}
}
}
return $fieldData;
}
/**
* @param Activity $activity
*/
private function validateSummary(Activity $activity): void
{
$team = $activity->user->team;
$crmProvider = $team->crm->provider;
$attributes = [];
$rules = [
'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,
'title' => 'string|max:250',
'prospects' => 'required|array',
'opportunity_id' => new CrmReference($crmProvider),
'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',
'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator
'summary' => 'max:50000',
'nId' => 'exists:notifications,id',
'crm_id' => new CrmReference($crmProvider),
'entities' => 'array',
'is_internal' => 'boolean',
];
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));
// Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.
$entities = $layout->entities()
->where('read_only', 0)
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->whereHas('parent', function ($query) use ($activity) {
if ($activity->isLoggable() === false) {
$query->where('label', '<>', 'follow-up');
}
});
$isInternal = $this->request->input('is_internal', false);
foreach ($entities->get() as $entity) {
$rules += $this->buildFieldValidator($entity, $isInternal);
$attributes += $this->buildFieldMessage($entity);
}
$this->request->validate($rules, [], $attributes);
}
private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array
{
return [
'entities.' . $entity->id_string => $entity->getValidator($isInternal),
];
}
/**
* @param LayoutEntity $entity
*
* @return array
*/
private function buildFieldMessage(LayoutEntity $entity): array
{
$label = $entity->label;
if ($label === null) {
$label = $entity->field->label;
}
return [
'entities.' . $entity->id_string => $label,
];
}
public function search(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->debugLog(
$user,
'User extracted from request',
['user' => $user->getId(), 'tz' => $user->getTimezone()]
);
$searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());
$this->debugLog(
$user,
'ActivitySearch criteria built',
['searchCriteria' => $searchCriteria]
);
$filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);
$this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);
$this->validateSearch($request, $filterSet);
$this->debugLog($user, 'Request validated');
$searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);
/** @var Collection<Activity> $activities */
$activities = $searchResponse['results'];
$this->debugLog($user, 'Activities ES response extracted');
$hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(
$user->getTeamId(),
TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),
);
if ($hideInternalMeetingsSetting?->getValue() === '1') {
$activities = $activities->filter(function (Activity $activity) {
if ($activity->is_internal && empty($activity->actual_start_time)) {
return false;
}
return true;
});
}
$this->debugLog($user, 'Internal meetings (?!) filtered');
$this->response->getManager()
->parseIncludes([
'category',
'organizer.group',
'prospect',
'stage',
'opportunity',
'stats',
'scorecards',
'masterTrack',
'activeParticipants',
'notification',
])
->setSerializer(new JsonSerializer());
$transformerExcludes = $this->request->input('exclude');
if ($transformerExcludes) {
$this->response->getManager()->parseExcludes($transformerExcludes);
}
$this->debugLog($user, 'Response Manager (?!) applied');
$transformer = new ActivityTransformer();
$transformer->setConsumer($user);
$this->debugLog($user, 'Activity Transformer added');
$resource = new \League\Fractal\Resource\Collection($activities, $transformer);
$page = $searchCriteria->getPageNumber();
$this->debugLog($user, 'Search criteria page number called', ['page' => $page]);
$histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');
$this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);
return $this->response->withArray([
'pagination' => [
'total' => $searchResponse['totalHits'],
'current' => $page,
'prev' => max($page - 1, 1),
'next' => $page + 1,
],
'results' => $this->response->getManager()->createData($resource)->toArray(),
'histogram' => $histogram,
]);
}
private function debugLog(User $user, string $logMessage, ?array $context = []): void
{
// Debug for Learning People Only
if ($user->getTeamId() !== 260) {
return;
}
Log::notice(
sprintf('[activity-search-controller] %s', $logMessage),
$context
);
}
/** @throws ValidationException */
private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void
{
$rules = [
'exclude' => 'array',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
];
if ($prefix !== null && mb_strpos($prefix, '.') !== false) {
$rules[rtrim($prefix, '.')] = sprintf(
'required|array|max:%d',
$filterSet->count()
);
}
$validationRules = $filterSet->getValidationRules($prefix)
->merge($rules)
->all();
$request->validate($validationRules);
}
public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$search = $this->updateOrCreateActivitySearch($request);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function updateActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('update', $search);
$this->updateOrCreateActivitySearch($request, $search);
return $this->response->withOk();
}
private function storeNamedSearchFilters(
Collection $request,
Search $search,
FilterDefinitionCollection $filterSet,
?string $prefix = null,
): self {
$arrayTypeProperties = $filterSet
->getPropertyTypes([
FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,
])
->all();
$supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);
foreach ($supportedRequestProperties as $requestPropertyName) {
if (! array_has($request, $requestPropertyName)) {
continue;
}
/** @var string|string[] $propertyValue */
$propertyValue = array_get($request, $requestPropertyName);
$propertyName = $prefix === null
? $requestPropertyName
: mb_substr($requestPropertyName, mb_strlen($prefix));
$isArrayType = array_has($arrayTypeProperties, $propertyName);
if (! $isArrayType) {
/** @var string $requestPropertyValue */
$search->filters()->updateOrCreate(
[
'filter' => $propertyName,
],
[
'value' => $propertyValue,
]
);
continue;
}
/** @var string[] $requestPropertyValue */
/** @var SearchFilter[]|Collection $existingFilterValues */
$existingFilterValuesKeyed = $search->filters()
->where('filter', $propertyName)
->get()
->keyBy('id');
// Iterate over values provided as request parameters
foreach ($propertyValue as $value) {
/** @var SearchFilter|null $valueFilter */
$valueFilter = $search->filters()
->where(
[
'filter' => $propertyName,
'value' => $value,
]
)
->first();
if ($valueFilter !== null) {
// Remove filter value pair from list to be deleted
$existingFilterValuesKeyed->forget($valueFilter->id);
} else {
// Add new filter/value pair
$search->filters()->updateOrCreate([
'filter' => $propertyName,
'value' => $value,
]);
}
}
// Delete filter value pairs for this filter that no longer exist in request parameters
foreach ($existingFilterValuesKeyed as $existingFilter) {
$existingFilter->delete();
}
}
/** @var Collection<int, SearchFilter> $filtersKeyed */
$filtersKeyed = $search->filters()->get()->keyBy('filter');
// wipe removed filters from this search
foreach ($filtersKeyed as $filterName => $filter) {
if (array_has($request, $prefix . $filterName)) {
continue;
}
// Remove all filter values for this filter
$search->filters()->where('filter', $filterName)->delete();
}
return $this;
}
/**
* @throws AuthorizationException
*/
public function fetchActivitySearch(
Search $search,
Request $request,
SearchTransformer $searchTransformer,
): JsonResponse {
$this->authorize('view', $search);
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withCollection(
$user->searches()->get(),
$searchTransformer
->withConsumer($user)
);
}
/**
* Deletes a saved search
*
* @param Request $request
* @param Search $search
*
* @throws Exception
*
* @return JsonResponse
*/
public function deleteActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('delete', $search);
// Orphan any AutomatedReports that use this search
$search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);
// Delete filters and the search itself
$search->filters()->delete();
$search->delete();
return $this->response->withOk();
}
public function live(Request $request, ElasticActivityRepository $repository): JsonResponse
{
$user = $this->getUserFromRequest($request);
$this->request->validate([
'sort_direction' => 'in:asc,desc',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
]);
$activities = $repository->getLiveCoachingEligibleActivities(
user: $user,
lookBackMinutes: self::LOOK_BACK,
limit: (int) $this->request->input('limit', 25),
page: (int) $this->request->input('page', 1),
sortBy: ['actual_start_time', 'scheduled_start_time'],
sortDirection: (string) $this->request->input('sort_direction', 'asc'),
);
$this->response
->getManager()
->parseIncludes(['organizer.group', 'prospect'])
->setSerializer(new JsonSerializer());
return $this->response->withCollection($activities, new ActivityTransformer());
}
/**
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function show(Activity $activity, ActivityService $activityService): JsonResponse
{
$this->authorize('show', $activity);
$user = $activity->getUser();
$team = $user->getTeam();
// Sync the opportunity with the latest data if possible.
if ($activity->opportunity_id) {
try {
$crmService = $this->providerRegistry->get($team->crm->provider);
if (! $user->isCrmRequired()) {
$crmService->setUser($team->getOwner());
} else {
$crmService->setUser($user);
}
$crmService->syncOpportunity($activity->opportunity->crm_provider_id);
} catch (Exception $exception) {
// Move on.
}
}
$activityData = $activityService->getActivityData($this->request->user(), $activity);
return response()->json($activityData);
}
public function createRecording(Activity $activity)
{
$this->authorize('record', $activity);
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Tell Twilio to start recording this activity.
if ($activity->recording_state === Activity::RECORDING_OFF) {
$job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withCreated();
}
return $this->response->errorGone('Activity is already recording.');
}
public function updateRecording(Request $request, Activity $activity)
{
$this->authorize('record', $activity);
$request->validate([
'preference' => 'boolean',
'state' => [
'string',
Rule::in([
Activity::RECORDING_IN_PROGRESS,
Activity::RECORDING_PAUSED,
]),
],
]);
if ($request->has('state')) {
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Toggle the recording state between paused and resumed.
if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {
$job = (new ToggleRecording($activity, $request->input('state')))
->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Recording is not toggleable.');
}
if ($request->has('preference')) {
$activity->update([
'recording_preference' => $request->input('preference') ? 1 : 0,
]);
return $this->response->withOk();
}
return $this->response->errorWrongArgs('Something went wrong');
}
public function stopRecording(Activity $activity)
{
$this->authorize('stopRecord', $activity);
// Tell Twilio to stop recording this activity.
if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {
$job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Activity is not recording.');
}
/**
* Add activity to this user's favorites playlist
*
* @throws AuthorizationException
*/
public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse
{
$this->authorize('favorite', $activity);
$user = $this->getUserFromRequest($this->request);
$favorite = $activity->wasFavoritedBy($user);
$name = $activity->activity_title ?? '';
// It needs to check at least one record.
if (! $favorite) {
$favoritePlaylist = $user->favoritePlaylist();
$playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(
$activity,
$user,
$favoritePlaylist
);
if ($playlistActivity !== null) {
$playlistActivity->update(
// Just update, don't sort.
['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],
);
} else {
$playlistActivity = $activity->playlistActivities()->create([
'playlist_id' => $favoritePlaylist->getId(),
'user_id' => $user->getId(),
'start_time' => 0,
'name' => mb_strimwidth($name, 0, 100),
]);
// Sort it on top.
$playlistActivity->update(
[
'sort' => $playlistActivityRepository->calculateNewSortOrder(
null,
$playlistActivity,
),
],
);
}
$playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);
return new JsonResponse([], JsonResponse::HTTP_CREATED);
}
return new JsonResponse(
[
'error' => [
'code' => AbstractResponse::CODE_CONFLICT,
'http_code' => JsonResponse::HTTP_CONFLICT,
'message' => 'Resource Already Exists',
],
],
JsonResponse::HTTP_CONFLICT,
);
}
/**
* Remove activity from this user's favorites playlist
*
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function unfavorite(Activity $activity)
{
$user = $t...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"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":"Analyzing…","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 Carbon\\Carbon;\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Exception;\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Validation\\Rule;\nuse Illuminate\\Validation\\Rules\\In;\nuse Illuminate\\Validation\\ValidationException;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ActivityAnalytics;\nuse Jiminny\\Component\\ActivitySearch;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Contracts\\ES\\Events\\UpdateSingleEntity;\nuse Jiminny\\Contracts\\ES\\UpdateTargetEnum;\nuse Jiminny\\Contracts\\Nudge\\NudgeFactoryInterface;\nuse Jiminny\\Contracts\\Playlist\\PlaylistTrackFactoryInterface;\nuse Jiminny\\Contracts\\Repositories\\PlaylistActivityRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Enums\\TeamSetting;\nuse Jiminny\\Events\\Activities\\AiAutomation\\ActivityProspectAdded;\nuse Jiminny\\Events\\Activities\\Coaching\\Coached;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Controllers\\CommentContextInterface;\nuse Jiminny\\Http\\Responses\\Api\\AbstractResponse;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\ActivityCommentTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTopicTriggerTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTransformer;\nuse Jiminny\\Http\\Transformers\\AvailabilityNotificationTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingFeedbackTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingSectionsTransformer;\nuse Jiminny\\Http\\Transformers\\SearchTransformer;\nuse Jiminny\\Http\\Transformers\\StatsTransformer;\nuse Jiminny\\Jobs\\Crm\\SaveActivity;\nuse Jiminny\\Jobs\\Crm\\UpdateStage;\nuse Jiminny\\Jobs\\Telephony\\StartRecording;\nuse Jiminny\\Jobs\\Telephony\\StopRecording;\nuse Jiminny\\Jobs\\Telephony\\ToggleRecording;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\CoachingFeedback;\nuse Jiminny\\Models\\CoachingSection;\nuse Jiminny\\Models\\CoachingSectionCriterion;\nuse Jiminny\\Models\\CoachingSectionFeedback;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\LanguageDialect;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Nudge;\nuse Jiminny\\Models\\PlaybookCategory;\nuse Jiminny\\Models\\Playlist;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\Track;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\CoachingFeedbackRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Rules\\MultidimensionalArrayMaxCharRule;\nuse Jiminny\\Services\\ActivityService;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Services\\PlaybackService;\nuse Jiminny\\Services\\UserService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\nuse Ramsey\\Uuid\\Uuid;\nuse Sentry;\nuse Symfony\\Component\\HttpFoundation;\n\nfinal class ActivityController extends Controller implements CommentContextInterface\n{\n // Number of minutes to look back on activities. i.e. a timeout on activity duration.\n private const int LOOK_BACK = 180;\n\n public function __construct(\n private ProviderRegistry $providerRegistry,\n private ActivityService $activityService,\n Response $response,\n private UserService $userService,\n private ActivitySearch\\Service\\ActivitySearch $activitySearch,\n private NudgeFactoryInterface $nudgeFactory,\n private ActivityCommentService $activityCommentService,\n private LoggerInterface $logger,\n private readonly CoachingFeedbackRepository $coachingFeedbackRepository,\n private readonly TeamRepository $teamRepository,\n ) {\n parent::__construct($response);\n }\n\n public static function getCommentImplementation(): string\n {\n return Comment::class;\n }\n\n public function delete()\n {\n $this->request->validate([\n '*' => 'uuid:activities',\n ]);\n\n $deletedIds = [];\n foreach ($this->request->all() as $activityId) {\n $activity = Activity::idOrUuId($activityId);\n\n try {\n if ($this->authorize('delete', $activity)) {\n $activity->delete();\n $deletedIds[] = $activityId;\n\n \\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n }\n } catch (AuthorizationException $authorizationException) {\n // They didn't have permission.\n }\n }\n\n return $this->response->withArray($deletedIds);\n }\n\n public function update(Request $request, Activity $activity)\n {\n $this->authorize('updateMetadata', $activity);\n\n $request->validate([\n 'title' => 'string|max:250',\n 'category_id' => 'uuid:playbook_categories',\n 'language' => [\n new In(\n LanguageDialect::query()\n ->with('language')\n ->cursor()\n ->map(static function (LanguageDialect $languageDialect): string {\n return $languageDialect->getLanguageLocale();\n })\n ->all()\n ),\n ],\n ]);\n\n if ($request->has('title')) {\n $activity->title = $request->input('title');\n }\n\n if ($request->has('category_id')) {\n $category = PlaybookCategory::uuid($request->input('category_id'));\n\n if ($category->playbook->team_id !== $request->user()->team_id) {\n return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n if ($request->has('language')) {\n if (! $activity->isInProgress()) {\n return $this->response->withError(\n 'Activity language can only be set while the meeting is in progress.',\n 400\n );\n }\n\n $activity->setLanguageCode($request->input('language'));\n }\n\n $activity->save();\n\n return $this->response->withOk();\n }\n\n // XXX: This should be merged with the update method.\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws SocialAccountTokenInvalidException\n *\n * @return mixed\n */\n public function summarize(Activity $activity): mixed\n {\n $this->logger->info('[Log Activity] Summarizing activity ', [\n 'activityId' => $activity->getUuid(),\n 'payload' => $this->request->all(),\n ]);\n $this->authorize('update', $activity);\n\n $this->logger->info('[Log Activity] Validating summary');\n // Validate the payload.\n $this->validateSummary($activity);\n\n // All objects must belong to this team.\n /** @var User $user */\n $user = $this->request->user();\n $team = $user->getTeam();\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n try {\n $crmUser = $user;\n if ($user->isCrmRequired() === false) {\n $crmUser = $team->owner;\n }\n $crmService->setUser($crmUser);\n } catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());\n }\n\n $rawEntities = $this->request->input('entities');\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid(\n $this->request->input('layout_id')\n );\n\n // Delay execution of CRM jobs to avoid locking issues.\n $jobDelay = 0;\n\n // If we have arrived from a notification, mark it as read.\n $notificationId = $this->request->input('nId');\n if ($notificationId) {\n $notification = $user->unreadNotifications->where('id', $notificationId)->first();\n\n if ($notification) {\n $notification->markAsRead();\n }\n }\n\n $title = $this->request->input('title');\n $prospects = $this->request->input('prospects');\n $opportunityId = $this->request->input('opportunity_id');\n $stageId = $this->request->input('stage_id');\n $categoryId = $this->request->input('category_id');\n $summary = $this->request->input('summary');\n $crmProviderId = $this->request->input('crm_id');\n $isInternal = $this->request->input('is_internal') ?? false;\n\n $lead = null;\n $category = null;\n $account = null;\n $contact = null;\n $opportunity = null;\n $stage = null;\n $callStage = null;\n\n foreach ($prospects as $prospectData) {\n $objectId = $prospectData['id'];\n\n if ($objectId === null) {\n continue;\n }\n\n $objectType = $prospectData['type'];\n $this->logger->info('debug', ['prospect_data' => $prospectData]);\n\n try {\n if ($objectType === null) {\n $this->logger->info('no object type');\n if ($crmService instanceof SupportsObjectTypeParseInterface) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n }\n\n switch ($objectType) {\n case 'lead':\n $this->logger->info('Processing lead');\n /** @var Lead|null $lead */\n $lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();\n\n // Lead does not exist locally, import it.\n if ($lead === null) {\n $this->logger->info('Lead does not exist locally');\n /** @var Lead $lead */\n $lead = $crmService->syncLead($objectId);\n }\n\n $this->logger->info('Lead found', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n if ($stageId === null) {\n $this->logger->info('Stage ID is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $lead->stage;\n\n break;\n }\n\n $this->logger->info('Looking for stage');\n // Determine if they have changed the stage.\n /** @var Stage $stage */\n $stage = $team->crm->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_LEAD)\n ->firstOrFail();\n\n $this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);\n if ($lead->stage_id && $lead->stage_id !== $stage->id) {\n $this->logger->info('Stage has changed');\n // Storage current stage on activity.\n $callStage = $lead->stage;\n\n // The stage has changed, update in remote CRM.\n dispatch(new UpdateStage($activity, $lead, $callStage, $stage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing lead stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->getName(),\n $stage->getName()\n ),\n [\n 'user' => $user->getUuid(),\n 'lead' => $lead->getUuid(),\n ]\n );\n } else {\n $this->logger->info('Stage has not changed');\n // Stage remains as current.\n $callStage = $stage;\n }\n\n break;\n\n case 'account':\n $this->logger->info('Processing account');\n // If the object is not a lead, it should be an account.\n $account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();\n\n // Account does not exist locally, import it.\n if ($account === null) {\n $this->logger->info('Account does not exist locally');\n $account = $crmService->syncAccount($objectId);\n }\n\n $this->logger->info('Account found', ['accountId' => $account->id]);\n\n break;\n case 'contact':\n $this->logger->info('processing contact');\n $contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $this->logger->info('contact does not exist locally');\n $contact = $crmService->syncContact($objectId);\n }\n\n $this->logger->info('resolving account');\n $account = $this->resolveAccount($team, $contact, $crmService, $prospects);\n\n break;\n }\n\n // If they have specified an opportunity, retrieve this with stage.\n if ($opportunityId) {\n $this->logger->info('opportunity id is set');\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if ($opportunity === null) {\n $this->logger->info('opportunity does not exist locally');\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n if ($stageId === null) {\n $this->logger->info('stage id is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $opportunity->stage ?? null;\n } else {\n $this->logger->info('looking for stage');\n /** @var ?Stage $opportunityStage */\n $opportunityStage = $team->crm\n ->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n // There is a chance we still cannot import this opportunity.\n if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {\n $this->logger->info('opportunity stage has changed');\n // Storage current stage on activity.\n $callStage = $opportunity->stage;\n\n dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing opportunity stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->name,\n $opportunityStage->name\n ),\n [\n 'userId' => $user->id_string,\n 'opportunityId' => $opportunity->id_string,\n ]\n );\n } else {\n $this->logger->info('opportunity stage has not changed');\n // Stage remains as current.\n $callStage = $opportunityStage;\n }\n }\n }\n\n if ($crmProviderId) {\n // Cast $crmProviderId to string otherwise it won't use database index for some records\n $linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();\n\n // Check if this activity has already been assigned to a different activity.\n if ($linkedActivity && $linkedActivity->id !== $activity->id) {\n throw new InvalidArgumentException(\n 'Sorry, the linked task has already been logged under a different call. '\n . 'Please choose another linked task.'\n );\n }\n }\n } catch (InvalidArgumentException $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($exception->getMessage());\n } catch (Exception $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorInternalError(\n 'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'\n );\n }\n }\n\n if ($categoryId) {\n $category = PlaybookCategory::uuid($categoryId);\n\n if ($category->playbook->team_id !== $team->id) {\n throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n $this->logger->info('Prospect data', [\n 'lead_id' => $lead?->getId(),\n 'account_id' => $account?->getId(),\n 'contact_id' => $contact?->getId(),\n 'opportunity_id' => $opportunity?->getId(),\n 'stage_id' => $stage?->getId(),\n ]);\n\n if ($title) {\n $activity->title = $title;\n }\n\n if ($summary) {\n $activity->summary = $summary;\n }\n\n if ($crmProviderId) {\n $activity->crm_provider_id = $crmProviderId;\n }\n\n if ($callStage) {\n $this->logger->info('Setting stage id', ['stageId' => $callStage->id]);\n $activity->stage_id = $callStage->id;\n }\n\n if ($lead) {\n $this->logger->info('Setting lead id', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n // If we are changed from an account > lead, unset the account data.\n $this->logger->info('Unsetting account id, opportunity id, contact id, value');\n $activity->account_id = null;\n $activity->opportunity_id = null;\n $activity->contact_id = null;\n $activity->value = null;\n }\n\n if ($account) {\n $this->logger->info('Setting account id', ['accountId' => $account->id]);\n $activity->account_id = $account->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('unsetting lead id');\n $activity->lead_id = null;\n\n // Unset the contact if switching different accounts. Will be set up below if still applicable.\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {\n $this->logger->info('Unsetting contact id');\n $activity->contact_id = null;\n }\n }\n\n if ($opportunity) {\n $this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);\n $this->logger->info('unsetting lead id');\n $activity->opportunity_id = $opportunity->id;\n $activity->value = $opportunity->value;\n\n // If we are changed from an lead > account, unset the lead data.\n $activity->lead_id = null;\n }\n\n if ($contact) {\n $this->logger->info('setting contact id', ['contactId' => $contact->id]);\n $activity->contact_id = $contact->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('Unsetting lead id');\n $activity->lead_id = null;\n }\n\n $activity->is_internal = $isInternal;\n $activity->save();\n $activity->refresh();\n\n $this->logger->notice('Activity saved', [\n 'activity_id' => $activity->getId(),\n 'lead_id' => $activity->lead_id,\n 'account_id' => $activity->account_id,\n 'contact_id' => $activity->contact_id,\n 'opportunity_id' => $activity->opportunity_id,\n 'stage_id' => $activity->stage_id,\n 'crm_provider_id' => $activity->getCrmProviderId(),\n ]);\n\n // Store entities as field data on the activity.\n $updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);\n\n if ($activity->isLoggable()) {\n // Follow-up Task or Event data.\n $followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);\n\n $this->logger->info('CRM LOG manual log triggered', [\n 'activityId' => $activity->getUuid(),\n 'followupData' => $followupData,\n 'userId' => $user->getUuid(),\n ]);\n\n // Store data in the CRM.\n // ++add check for crm_required\n $job = new SaveActivity($activity, $followupData);\n\n if ($updatedData) {\n $job->delay(Carbon::now()->addMinutes($jobDelay));\n }\n\n dispatch($job);\n\n // Manually dispatch log for Opportunity or Prospect added\n if ($activity->hasOpportunity() || $activity->hasProspect()) {\n event(new ActivityProspectAdded(\n activity: $activity,\n eventSource: 'manually-log-crm-data'\n ));\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.\n *\n * @param ServiceInterface $service\n * @param Activity $activity\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array\n {\n $updatedData = [];\n $existingData = $activity->data()->get();\n\n // We need to delete any existing data to overwrite with latest values.\n $activity->data()->delete();\n\n $layoutEntities = $layout->entities()\n ->with('field', 'parent')\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->get();\n\n /** @var LayoutEntity $entity */\n foreach ($layoutEntities as $entity) {\n // If the user has provided a value for this entity\n if (array_key_exists($entity->id_string, $entities)) {\n $value = $entities[$entity->id_string];\n\n // Convert raw data into values that the CRM can consume.\n if ($value) {\n $value = $service->normalizeValue($entity->field->type, $value);\n }\n\n // Check the field is part of the activity-summary section.\n if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {\n // This is the internal database ID, not the external CRM ID.\n $objectId = null;\n\n switch ($entity->field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $objectId = $activity->account_id;\n\n break;\n\n case Field::OBJECT_CONTACT:\n $objectId = $activity->contact_id;\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n $objectId = $activity->opportunity_id;\n\n break;\n\n case Field::OBJECT_LEAD:\n $objectId = $activity->lead_id;\n\n break;\n\n case Field::OBJECT_TASK:\n case Field::OBJECT_EVENT:\n $objectId = $activity->id;\n\n break;\n }\n\n if ($objectId) {\n /** @var FieldData $data */\n $data = $activity->data()->create([\n 'crm_layout_entity_id' => $entity->id,\n 'crm_field_id' => $entity->crm_field_id,\n 'object_type' => $entity->field->object_type,\n 'object_id' => $objectId,\n 'value' => $value,\n ]);\n\n // Never send read-only field data to the CRM.\n if ($entity->read_only === false && $entity->is_visible) {\n $existingValue = $existingData\n ->where('crm_layout_entity_id', $entity->id)\n ->where('crm_field_id', $entity->crm_field_id)\n ->where('object_type', $entity->field->object_type)\n ->where('object_id', $objectId)\n ->first();\n\n // If the field was actually changed, we need to reflect this in the CRM too.\n if ($existingValue === null || $existingValue->value !== $value) {\n $updatedData[] = $data->id;\n }\n }\n }\n }\n }\n }\n\n return $updatedData;\n }\n\n /**\n * Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.\n *\n * @param ServiceInterface $crmService\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array\n {\n $fieldData = [];\n foreach ($entities as $entityId => $value) {\n // Only bother with fields that have a value.\n if ($value) {\n // Extract the entity from the UUID. Check the field is valid and part of the follow-up section.\n $entity = $layout->entities()\n ->uuid($entityId, false)\n ->whereHas('parent', function ($query) {\n $query->where('label', 'follow-up');\n })\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->first();\n\n if ($entity) {\n // Convert raw data into values that the CRM can consume.\n $value = $crmService->normalizeValue($entity->field->type, $value);\n\n // Add the field and value to the payload.\n $fieldData += [\n $entity->field->crm_provider_id => $value,\n ];\n }\n }\n }\n\n return $fieldData;\n }\n\n /**\n * @param Activity $activity\n */\n private function validateSummary(Activity $activity): void\n {\n $team = $activity->user->team;\n $crmProvider = $team->crm->provider;\n $attributes = [];\n\n $rules = [\n 'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,\n 'title' => 'string|max:250',\n 'prospects' => 'required|array',\n 'opportunity_id' => new CrmReference($crmProvider),\n 'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',\n 'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator\n 'summary' => 'max:50000',\n 'nId' => 'exists:notifications,id',\n 'crm_id' => new CrmReference($crmProvider),\n 'entities' => 'array',\n 'is_internal' => 'boolean',\n ];\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));\n\n // Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.\n $entities = $layout->entities()\n ->where('read_only', 0)\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->whereHas('parent', function ($query) use ($activity) {\n if ($activity->isLoggable() === false) {\n $query->where('label', '<>', 'follow-up');\n }\n });\n\n $isInternal = $this->request->input('is_internal', false);\n\n foreach ($entities->get() as $entity) {\n $rules += $this->buildFieldValidator($entity, $isInternal);\n $attributes += $this->buildFieldMessage($entity);\n }\n\n $this->request->validate($rules, [], $attributes);\n }\n\n private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array\n {\n return [\n 'entities.' . $entity->id_string => $entity->getValidator($isInternal),\n ];\n }\n\n /**\n * @param LayoutEntity $entity\n *\n * @return array\n */\n private function buildFieldMessage(LayoutEntity $entity): array\n {\n $label = $entity->label;\n if ($label === null) {\n $label = $entity->field->label;\n }\n\n return [\n 'entities.' . $entity->id_string => $label,\n ];\n }\n\n public function search(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->debugLog(\n $user,\n 'User extracted from request',\n ['user' => $user->getId(), 'tz' => $user->getTimezone()]\n );\n\n $searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());\n\n $this->debugLog(\n $user,\n 'ActivitySearch criteria built',\n ['searchCriteria' => $searchCriteria]\n );\n\n $filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);\n\n $this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);\n\n $this->validateSearch($request, $filterSet);\n\n $this->debugLog($user, 'Request validated');\n\n $searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);\n\n /** @var Collection<Activity> $activities */\n $activities = $searchResponse['results'];\n\n $this->debugLog($user, 'Activities ES response extracted');\n\n $hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(\n $user->getTeamId(),\n TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),\n );\n\n if ($hideInternalMeetingsSetting?->getValue() === '1') {\n $activities = $activities->filter(function (Activity $activity) {\n if ($activity->is_internal && empty($activity->actual_start_time)) {\n return false;\n }\n\n return true;\n });\n }\n\n $this->debugLog($user, 'Internal meetings (?!) filtered');\n\n $this->response->getManager()\n ->parseIncludes([\n 'category',\n 'organizer.group',\n 'prospect',\n 'stage',\n 'opportunity',\n 'stats',\n 'scorecards',\n 'masterTrack',\n 'activeParticipants',\n 'notification',\n ])\n ->setSerializer(new JsonSerializer());\n\n $transformerExcludes = $this->request->input('exclude');\n if ($transformerExcludes) {\n $this->response->getManager()->parseExcludes($transformerExcludes);\n }\n\n $this->debugLog($user, 'Response Manager (?!) applied');\n\n $transformer = new ActivityTransformer();\n $transformer->setConsumer($user);\n\n $this->debugLog($user, 'Activity Transformer added');\n\n $resource = new \\League\\Fractal\\Resource\\Collection($activities, $transformer);\n $page = $searchCriteria->getPageNumber();\n\n $this->debugLog($user, 'Search criteria page number called', ['page' => $page]);\n\n $histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');\n\n $this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);\n\n return $this->response->withArray([\n 'pagination' => [\n 'total' => $searchResponse['totalHits'],\n 'current' => $page,\n 'prev' => max($page - 1, 1),\n 'next' => $page + 1,\n ],\n 'results' => $this->response->getManager()->createData($resource)->toArray(),\n 'histogram' => $histogram,\n ]);\n }\n\n private function debugLog(User $user, string $logMessage, ?array $context = []): void\n {\n // Debug for Learning People Only\n if ($user->getTeamId() !== 260) {\n return;\n }\n\n Log::notice(\n sprintf('[activity-search-controller] %s', $logMessage),\n $context\n );\n }\n\n /** @throws ValidationException */\n private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void\n {\n $rules = [\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ];\n\n if ($prefix !== null && mb_strpos($prefix, '.') !== false) {\n $rules[rtrim($prefix, '.')] = sprintf(\n 'required|array|max:%d',\n $filterSet->count()\n );\n }\n\n $validationRules = $filterSet->getValidationRules($prefix)\n ->merge($rules)\n ->all();\n\n $request->validate($validationRules);\n }\n\n public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $search = $this->updateOrCreateActivitySearch($request);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function updateActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('update', $search);\n\n $this->updateOrCreateActivitySearch($request, $search);\n\n return $this->response->withOk();\n }\n\n private function storeNamedSearchFilters(\n Collection $request,\n Search $search,\n FilterDefinitionCollection $filterSet,\n ?string $prefix = null,\n ): self {\n $arrayTypeProperties = $filterSet\n ->getPropertyTypes([\n FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,\n ])\n ->all();\n\n $supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);\n\n foreach ($supportedRequestProperties as $requestPropertyName) {\n if (! array_has($request, $requestPropertyName)) {\n continue;\n }\n\n /** @var string|string[] $propertyValue */\n $propertyValue = array_get($request, $requestPropertyName);\n $propertyName = $prefix === null\n ? $requestPropertyName\n : mb_substr($requestPropertyName, mb_strlen($prefix));\n\n $isArrayType = array_has($arrayTypeProperties, $propertyName);\n\n if (! $isArrayType) {\n /** @var string $requestPropertyValue */\n\n $search->filters()->updateOrCreate(\n [\n 'filter' => $propertyName,\n ],\n [\n 'value' => $propertyValue,\n ]\n );\n\n continue;\n }\n\n /** @var string[] $requestPropertyValue */\n\n /** @var SearchFilter[]|Collection $existingFilterValues */\n $existingFilterValuesKeyed = $search->filters()\n ->where('filter', $propertyName)\n ->get()\n ->keyBy('id');\n\n // Iterate over values provided as request parameters\n foreach ($propertyValue as $value) {\n /** @var SearchFilter|null $valueFilter */\n $valueFilter = $search->filters()\n ->where(\n [\n 'filter' => $propertyName,\n 'value' => $value,\n ]\n )\n ->first();\n\n if ($valueFilter !== null) {\n // Remove filter value pair from list to be deleted\n $existingFilterValuesKeyed->forget($valueFilter->id);\n } else {\n // Add new filter/value pair\n $search->filters()->updateOrCreate([\n 'filter' => $propertyName,\n 'value' => $value,\n ]);\n }\n }\n\n // Delete filter value pairs for this filter that no longer exist in request parameters\n foreach ($existingFilterValuesKeyed as $existingFilter) {\n $existingFilter->delete();\n }\n }\n\n /** @var Collection<int, SearchFilter> $filtersKeyed */\n $filtersKeyed = $search->filters()->get()->keyBy('filter');\n\n // wipe removed filters from this search\n foreach ($filtersKeyed as $filterName => $filter) {\n if (array_has($request, $prefix . $filterName)) {\n continue;\n }\n\n // Remove all filter values for this filter\n $search->filters()->where('filter', $filterName)->delete();\n }\n\n return $this;\n }\n\n /**\n * @throws AuthorizationException\n */\n public function fetchActivitySearch(\n Search $search,\n Request $request,\n SearchTransformer $searchTransformer,\n ): JsonResponse {\n $this->authorize('view', $search);\n\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection(\n $user->searches()->get(),\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n /**\n * Deletes a saved search\n *\n * @param Request $request\n * @param Search $search\n *\n * @throws Exception\n *\n * @return JsonResponse\n */\n public function deleteActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('delete', $search);\n\n // Orphan any AutomatedReports that use this search\n $search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);\n\n // Delete filters and the search itself\n $search->filters()->delete();\n $search->delete();\n\n return $this->response->withOk();\n }\n\n public function live(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n $user = $this->getUserFromRequest($request);\n\n $this->request->validate([\n 'sort_direction' => 'in:asc,desc',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ]);\n\n $activities = $repository->getLiveCoachingEligibleActivities(\n user: $user,\n lookBackMinutes: self::LOOK_BACK,\n limit: (int) $this->request->input('limit', 25),\n page: (int) $this->request->input('page', 1),\n sortBy: ['actual_start_time', 'scheduled_start_time'],\n sortDirection: (string) $this->request->input('sort_direction', 'asc'),\n );\n\n $this->response\n ->getManager()\n ->parseIncludes(['organizer.group', 'prospect'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($activities, new ActivityTransformer());\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function show(Activity $activity, ActivityService $activityService): JsonResponse\n {\n $this->authorize('show', $activity);\n\n $user = $activity->getUser();\n $team = $user->getTeam();\n\n // Sync the opportunity with the latest data if possible.\n if ($activity->opportunity_id) {\n try {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n if (! $user->isCrmRequired()) {\n $crmService->setUser($team->getOwner());\n } else {\n $crmService->setUser($user);\n }\n\n $crmService->syncOpportunity($activity->opportunity->crm_provider_id);\n } catch (Exception $exception) {\n // Move on.\n }\n }\n\n $activityData = $activityService->getActivityData($this->request->user(), $activity);\n\n return response()->json($activityData);\n }\n\n public function createRecording(Activity $activity)\n {\n $this->authorize('record', $activity);\n\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Tell Twilio to start recording this activity.\n if ($activity->recording_state === Activity::RECORDING_OFF) {\n $job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withCreated();\n }\n\n return $this->response->errorGone('Activity is already recording.');\n }\n\n public function updateRecording(Request $request, Activity $activity)\n {\n $this->authorize('record', $activity);\n\n $request->validate([\n 'preference' => 'boolean',\n 'state' => [\n 'string',\n Rule::in([\n Activity::RECORDING_IN_PROGRESS,\n Activity::RECORDING_PAUSED,\n ]),\n ],\n ]);\n\n if ($request->has('state')) {\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Toggle the recording state between paused and resumed.\n if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {\n $job = (new ToggleRecording($activity, $request->input('state')))\n ->onQueue(Constants::QUEUE_CONFERENCES);\n\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Recording is not toggleable.');\n }\n\n if ($request->has('preference')) {\n $activity->update([\n 'recording_preference' => $request->input('preference') ? 1 : 0,\n ]);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorWrongArgs('Something went wrong');\n }\n\n public function stopRecording(Activity $activity)\n {\n $this->authorize('stopRecord', $activity);\n\n // Tell Twilio to stop recording this activity.\n if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {\n $job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Activity is not recording.');\n }\n\n /**\n * Add activity to this user's favorites playlist\n *\n * @throws AuthorizationException\n */\n public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse\n {\n $this->authorize('favorite', $activity);\n\n $user = $this->getUserFromRequest($this->request);\n $favorite = $activity->wasFavoritedBy($user);\n $name = $activity->activity_title ?? '';\n\n // It needs to check at least one record.\n if (! $favorite) {\n $favoritePlaylist = $user->favoritePlaylist();\n\n $playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(\n $activity,\n $user,\n $favoritePlaylist\n );\n\n if ($playlistActivity !== null) {\n $playlistActivity->update(\n // Just update, don't sort.\n ['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],\n );\n } else {\n $playlistActivity = $activity->playlistActivities()->create([\n 'playlist_id' => $favoritePlaylist->getId(),\n 'user_id' => $user->getId(),\n 'start_time' => 0,\n 'name' => mb_strimwidth($name, 0, 100),\n ]);\n // Sort it on top.\n $playlistActivity->update(\n [\n 'sort' => $playlistActivityRepository->calculateNewSortOrder(\n null,\n $playlistActivity,\n ),\n ],\n );\n }\n\n $playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);\n\n return new JsonResponse([], JsonResponse::HTTP_CREATED);\n }\n\n return new JsonResponse(\n [\n 'error' => [\n 'code' => AbstractResponse::CODE_CONFLICT,\n 'http_code' => JsonResponse::HTTP_CONFLICT,\n 'message' => 'Resource Already Exists',\n ],\n ],\n JsonResponse::HTTP_CONFLICT,\n );\n }\n\n /**\n * Remove activity from this user's favorites playlist\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unfavorite(Activity $activity)\n {\n $user = $this->request->user();\n\n $favorites = $activity->favoritedBy($user);\n\n if ($favorites && $favorites->isEmpty()) {\n return $this->response->errorNotFound('Favorite not found.');\n }\n\n $this->authorize('unfavorite', [$activity, $favorites]);\n\n // When you unfavorite an activity,\n // it should remove all the activities in it, including snippets.\n $isDeleted = $favorites->each(function ($favorite) {\n $favorite->forceDelete();\n });\n\n if ($isDeleted) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not remove favorite.');\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function notify(Activity $activity)\n {\n $this->authorize('notify', $activity);\n\n $user = $this->request->user();\n\n $existingNotification = $activity->availabilityNotifications()\n ->where('user_id', $user->id)\n ->exists();\n\n if ($existingNotification) {\n return $this->response->errorWrongArgs('Notification is already configured.');\n }\n\n $notification = Activity\\AvailabilityNotification::create([\n 'user_id' => $user->id,\n 'activity_id' => $activity->id,\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($notification, new AvailabilityNotificationTransformer());\n }\n\n /**\n * @param Activity $activity\n * @param Activity\\AvailabilityNotification $notification\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unnotify(Activity $activity, Activity\\AvailabilityNotification $notification)\n {\n $this->authorize('unnotify', [$activity, $notification]);\n\n if ($notification->sent_at || $notification->delete()) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not delete notification.');\n }\n\n public function play(Request $request, Activity $activity)\n {\n $this->authorize('stream', $activity);\n\n $request->validate([\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $activity->plays()->create([\n 'user_id' => $user->getId(),\n 'start_time' => $request->input('start_time'),\n ]);\n\n return $this->response->withCreated();\n }\n\n /**\n * @param Activity $activity\n *\n * @return mixed\n */\n public function comment(Activity $activity)\n {\n return $this->newComment($activity);\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @return mixed\n */\n public function replyComment(Activity $activity, Comment $comment)\n {\n return $this->newComment($activity, $comment);\n }\n\n /**\n * @param Activity $activity\n * @param Comment|null $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n protected function newComment(Activity $activity, ?Comment $comment = null)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n 'type' => 'integer|between:0,3',\n 'visibility' => sprintf('nullable|integer|between:1,%d', count(Comment::getVisibilityLevels())),\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n $threadStartId = null;\n if ($comment) {\n $threadStartId = $comment->thread_start_id ?: $comment->id;\n }\n\n try {\n $newComment = Comment::create([\n 'parent_comment_id' => $comment->id ?? null,\n 'thread_start_id' => $threadStartId,\n 'activity_id' => $activity->id,\n 'user_id' => $this->request->user()->id,\n 'comment' => trim($this->request->input('comment')),\n 'start_time' => $this->request->input('start_time', 0),\n 'end_time' => $this->request->input('end_time', 0),\n 'type' => $this->request->input('type', Comment::TYPE_NEUTRAL),\n 'visibility' => $this->request->input('visibility', Comment::VISIBILITY_PUBLIC),\n ]);\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($newComment, new ActivityCommentTransformer());\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not create comment.' . $exception->getMessage());\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function updateComment(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n try {\n $comment->update([\n 'comment' => trim($this->request->input('comment')),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment.');\n }\n }\n\n public function updateCommentVisibility(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'visibility' => sprintf('integer|between:1,%d', count(Comment::getVisibilityLevels())),\n ]);\n\n $visibility = $this->request->input('visibility');\n\n if ($comment->parent !== null) {\n return $this->response->errorWrongArgs('Comment visibility can only be updated on top level comments.');\n }\n\n try {\n $this->activityCommentService->updateCommentVisibility($comment, $visibility);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment\\'s visibility.');\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function deleteComment(Activity $activity, Comment $comment)\n {\n $this->authorize('deleteComment', [$activity, $comment]);\n\n // Delete comment and any children.\n $comment->delete();\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function fetchComments()\n {\n $user = $this->request->user();\n $this->request->validate([\n 'forUserId' => 'uuid:users,team_id,' . $user->team_id,\n 'types' => 'array',\n 'types.*' => 'integer|between:0,3',\n ]);\n $forUser = null;\n\n $types = [Comment::TYPE_NEUTRAL, Comment::TYPE_GAME_CHANGER, Comment::TYPE_POSITIVE];\n $user = $this->request->user();\n if ($this->request->has('forUserId')) {\n $forUser = $user->team->users()->uuid($this->request->input('forUserId'));\n }\n\n $comments = Comment::query()\n ->whereHas('activity', static function (Builder $builder) use ($user, $forUser): void {\n $builder\n // I left feedback on my own activity; or\n ->where('activities.user_id', $user->getId());\n if ($forUser) {\n // I left feedback on any activity for this user.\n $builder->orWhere([\n 'user_id' => $user->getId(),\n 'activities.user_id' => $forUser->getId(),\n ]);\n }\n })\n ->whereIn('type', $this->request->input('types', $types))\n ->orderBy('created_at', 'desc')\n ->get();\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity', 'user'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($comments, new ActivityCommentTransformer());\n }\n\n public function deleteCoachingFeedback(Activity $activity, CoachingFeedback $coachingFeedback)\n {\n $this->authorize('deleteCoachingFeedback', [$activity, $coachingFeedback]);\n $activity = $coachingFeedback->getActivity();\n\n if ($coachingFeedback->delete()) {\n event(new UpdateSingleEntity(\n entityId: $activity->getId(),\n updateTarget: UpdateTargetEnum::ACTIVITY,\n purpose: 'delete-coaching-feedback',\n ));\n\n return $this->response->withOk();\n }\n\n return $this->response->withError('Delete operation failed. Contact support.', 500);\n }\n\n /**\n * Add new or update Coaching feedback\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws \\Illuminate\\Validation\\ValidationException\n *\n * @return mixed\n */\n public function putCoachingFeedback(Request $request, Activity $activity)\n {\n $user = $request->user();\n\n if (! $user instanceof User) {\n abort(403);\n }\n $teamId = $user->getTeamId();\n\n $this->authorize('coach', $activity);\n\n $this->request->validate([\n 'coach_id' => 'required|uuid:users,team_id,' . $teamId,\n 'coachee_id' => 'required|uuid:users,team_id,' . $teamId,\n 'visibility' => ['required', Rule::in(CoachingFeedback::VISIBILITIES)],\n 'coaching_sections.*.uuid' => 'required|uuid:coaching_sections',\n 'coaching_sections.*.score' => ['required', Rule::in(CoachingSectionFeedback::SCORES)],\n 'coaching_sections.*.summary' => 'string|max:10000',\n 'coaching_sections.*.criteria.*.uuid' => 'required|uuid:coaching_section_criteria',\n 'coaching_sections.*.criteria.*.note' => 'required|string|max:10000',\n 'sharedWithUsers' => [\n 'required_if:visibility,' . CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS,\n 'array',\n ],\n 'sharedWithUsers.*' => [\n 'uuid:users,team_id,' . $teamId,\n ],\n ]);\n\n /** @var User $coach */\n $coach = User::uuid($this->request->input('coach_id'));\n /** @var User $coachee */\n $coachee = User::uuid($this->request->input('coachee_id'));\n $coachingSectionFeedbacks = $this->request->input('coaching_sections');\n\n $previousRecord = $this->coachingFeedbackRepository->getOneForActivityByCoacheeAndCoach(\n $coachee->getId(),\n $coach->getId(),\n $activity->getId()\n );\n $recordIsNew = false;\n if ($previousRecord === null) {\n $recordIsNew = true;\n }\n\n if (! $coachee->isSameTeamId($coach)) {\n return $this->response->errorForbidden('User not member of your team.');\n }\n\n if (! is_array($coachingSectionFeedbacks) || count($coachingSectionFeedbacks) < 1) {\n return $this->response->withError('At least one Coaching Framework Section shall be scored.', 422);\n }\n\n if (! $activity->participants()->where('participants.user_id', $coachee->id)->exists()) {\n return $this->response->withError('Coached user did not participate activity.', 422);\n }\n\n $visibility = $this->request->input('visibility');\n\n $shouldSendNotification = $recordIsNew;\n if ($recordIsNew === false && $visibility !== $previousRecord->getVisibility()) {\n $shouldSendNotification = true;\n }\n\n /**\n * Create CoachingFeedback\n *\n * @var CoachingFeedback $coachingFeedback\n */\n $coachingFeedback = $activity->coachingFeedbacks()->updateOrCreate(\n [\n 'coach_id' => $coach->id,\n 'coachee_id' => $coachee->id,\n ],\n [\n 'framework_id' => $activity->category->id,\n 'visibility' => $visibility,\n ]\n );\n\n $sharedUserIds = [];\n if ($visibility === CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS) {\n foreach ($this->request->input('sharedWithUsers') as $sharedWithUserUuid) {\n /** @var User $user */\n $user = User::uuid($sharedWithUserUuid);\n $sharedUserIds[] = $user->getId();\n }\n }\n\n $syncResult = $coachingFeedback->customAccessUsers()->sync($sharedUserIds);\n\n $scores = [];\n\n\n /**\n * Create CoachingSectionsFeedbacks.\n *\n * @var CoachingSectionFeedback $coachingSectionFeedback\n */\n foreach ($coachingSectionFeedbacks as $coachingSectionFeedbackInput) {\n $coachingSection = CoachingSection::uuid($coachingSectionFeedbackInput['uuid']);\n $coachingSectionFeedback = $coachingFeedback->sectionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_id' => $coachingSection->id,\n ],\n [\n 'score' => array_get($coachingSectionFeedbackInput, 'score'),\n 'summary' => array_get($coachingSectionFeedbackInput, 'summary') ?? '',\n ]\n );\n\n $scores[] = array_get($coachingSectionFeedbackInput, 'score');\n\n $criteria = array_get($coachingSectionFeedbackInput, 'criteria');\n if (is_array($criteria) && ! empty($criteria)) {\n foreach ($criteria as $criteriaFeedbackInput) {\n $coachingSectionFeedback->criterionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_criterion_id' => CoachingSectionCriterion::uuid(array_get($criteriaFeedbackInput, 'uuid'))\n ->id,\n ],\n ['note' => array_get($criteriaFeedbackInput, 'note')],\n );\n }\n }\n }\n\n $coachingFeedback->average_score = array_sum($scores) / count($scores);\n\n if ($recordIsNew === false && $coachingFeedback->getAverageScore() !== $previousRecord->getAverageScore()) {\n $shouldSendNotification = true;\n }\n if (! empty($syncResult['attached']) || ! empty($syncResult['detached']) || ! empty($syncResult['updated'])) {\n $shouldSendNotification = true;\n }\n\n $coachingFeedback->save();\n // ensure updated at for coaching feedback on section feedback summary added.\n $coachingFeedback->touch();\n\n if ($shouldSendNotification) {\n event(new Coached($coachingFeedback));\n }\n\n Datadog::increment('jiminny.activity.score.update', 1, ['company' => $activity->user->team->slug]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n $coachingFeedbackTransformer = new CoachingFeedbackTransformer();\n $coachingFeedbackTransformer->setConsumer($this->getUserFromRequest($request));\n\n return $this->response->withItem($coachingFeedback, $coachingFeedbackTransformer);\n }\n\n\n /**\n * Retrieve category criteria for coaching.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachingSections(Activity $activity)\n {\n $this->authorize('coach', $activity);\n\n if ($activity->category === null) {\n return $this->response->errorUnprocessable('Category has not yet been assigned.');\n }\n\n $criteria = $activity\n ->category\n ->coachingSections()\n ->where('is_enabled', 1)\n ->orderBy('sequence', 'asc');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($criteria->get(), new CoachingSectionsTransformer());\n }\n\n /**\n * @throws AuthorizationException\n * @throws ValidationException\n *\n * @return mixed\n */\n public function addToPlaylist(Activity $activity, PlaylistTrackFactoryInterface $playlistTrackFactory)\n {\n $this->request->validate([\n 'playlists' => 'required|array',\n 'playlists.*' => 'uuid:playlists',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'name' => 'required|max:100',\n ]);\n\n $this->authorize('addToPlaylist', [$activity, $this->request->input('playlists')]);\n\n $startTime = $this->request->input('start_time');\n $endTime = $this->request->input('end_time');\n $name = $this->request->input('name');\n /** @var User $user */\n $user = $this->request->user();\n\n // Get playlist by uuid.\n foreach ($this->request->input('playlists') as $playlistId) {\n // Pull out the playlist model.\n $playlist = Playlist::uuid($playlistId);\n\n $playlistTrackFactory->createTrack($playlist, $user, [\n 'name' => $name,\n 'activity' => $activity,\n 'start_time' => $startTime,\n 'end_time' => $endTime,\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function share(Request $request, Activity $activity): JsonResponse\n {\n $this->authorize('share', $activity);\n\n $request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'recipients.*.type' => 'in:user,group',\n 'recipients.*.id' => 'string|max:40',\n 'share' => 'string|max:255',\n ]);\n\n $user = $request->user();\n\n $recipients = $request->get('recipients');\n $users = $this->userService->convertRecipientsToUsers($user, $recipients);\n\n $shareData = [\n 'from_user_id' => $user->id,\n 'note' => $request->input('note'),\n 'start_time' => $request->input('start_time'),\n 'end_time' => $request->input('end_time'),\n ];\n\n // Create a share object against a notification provider channel\n if ($request->input('share')) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'notification_provider_channel' => $request->input('share'),\n ]\n )\n );\n\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n\n // Create a share object against each recipient\n foreach ($users as $recipient) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'to_user_id' => $recipient->id,\n ]\n )\n );\n\n // If parent_share_id has been selected yet\n if (! isset($shareData['parent_share_id'])) {\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachRequest(Activity $activity)\n {\n $this->authorize('coachRequest', $activity);\n\n $this->request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'coachers.*.type' => 'required|in:user',\n 'coachers.*.id' => 'required',\n ]);\n\n $coachers = $this->request->get('coachers');\n $user = $this->request->user();\n $users = $this->userService->convertRecipientsToUsers($user, $coachers);\n\n foreach ($users as $coacher) {\n CoachRequest::create([\n 'user_id' => $coacher->id,\n 'activity_id' => $activity->id,\n 'note' => $this->request->get('note'),\n 'start_time' => $this->request->get('start_time'),\n 'end_time' => $this->request->get('end_time'),\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function createActivityTopicTriggers(Activity $activity, LoggerInterface $logger): HttpFoundation\\JsonResponse\n {\n $this->authorize('analyzeTopicTriggers', $activity);\n\n if (! $activity->hasTranscription()) {\n return new HttpFoundation\\JsonResponse(\n [\n 'error' => 'Transcription not found.',\n ],\n JsonResponse::HTTP_NOT_FOUND\n );\n }\n\n $logger->info(__METHOD__ . ': queued for analysis', [\n 'activity' => $activity->id_string,\n ]);\n\n dispatch(new ActivityAnalytics\\Job\\AnalyzeActivityTopicTriggers($activity));\n\n return new HttpFoundation\\JsonResponse(null, JsonResponse::HTTP_CREATED);\n }\n\n public function fetchActivityTopicTriggers(\n Activity $activity,\n LoggerInterface $logger,\n ActivityTopicTriggerTransformer $transformer\n ): HttpFoundation\\JsonResponse {\n $this->authorize('fetchTopicTriggers', $activity);\n\n $logger->debug(__METHOD__, [\n 'activity' => $activity->id_string,\n ]);\n\n if (! $activity->isProcessed()) {\n return new HttpFoundation\\JsonResponse([]);\n }\n\n $payload = [];\n\n if ($activity->hasTopicTriggers()) {\n $payload = $activity->getTopicTriggersSorted()\n ->map(\n static fn (Activity\\TopicTrigger $activityTopicTrigger): array\n => $transformer->transform($activityTopicTrigger)\n )\n ->values()\n ->all();\n }\n\n return new HttpFoundation\\JsonResponse($payload);\n }\n\n /**\n * @param Activity $activity\n * @param StatsTransformer $statsTransformer\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function stats(Activity $activity, StatsTransformer $statsTransformer)\n {\n $this->authorize('stream', $activity);\n\n if (! $activity->hasTranscription()) {\n return $this->response->errorNotFound('Waveform data is not yet generated.');\n }\n\n $this->response\n ->getManager()\n ->parseIncludes(['wavedata'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($activity, $statsTransformer);\n }\n\n public function destroy(Activity $activity)\n {\n $this->authorize('delete', $activity);\n\n $activity->delete();\n\n \\Log::info('Soft delete activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n\n return $this->response->withNoContent();\n }\n\n public function note(Activity $activity)\n {\n $this->authorize('note', $activity);\n\n $this->request->validate([\n 'note' => 'required|min:1|max:2000',\n 'time' => 'required|numeric|min:0|max:86400',\n ]);\n\n $note = $this->request->input('note');\n $time = $this->request->input('time');\n\n $this->activityService->setActivity($activity);\n $this->activityService->takeNote($this->getUser(), $note, $time);\n\n return $this->response->withCreated();\n }\n\n /**\n * Mark an activity as private.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPrivate(Activity $activity)\n {\n $this->authorize('markAsPrivate', $activity);\n\n if ($activity->is_private === false) {\n $activity->is_private = true;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * Mark an activity as public.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPublic(Activity $activity)\n {\n $this->authorize('markAsPublic', $activity);\n\n if ($activity->is_private) {\n $activity->is_private = false;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws LogicException\n */\n public function fetchCloudFrontS3MediaKeys(Activity $activity, PlaybackService $playbackService): JsonResponse\n {\n $masterTrack = $activity->masterTrack()->first();\n\n if (! $masterTrack instanceof Track) {\n throw new LogicException(sprintf('Master track not found for activity \"%s\"', $activity->getUuid()));\n }\n\n return $this->response->withArray(\n $playbackService->generateCookies(\n $masterTrack,\n $this->request->ip(),\n ),\n );\n }\n\n /**\n * @throws ValidationException\n */\n private function updateOrCreateActivitySearch(Request $request, ?Search $search = null): Search\n {\n $request->validate([\n 'name' => 'required|string|min:2|max:100',\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $searchName = $request->input('name');\n\n if ($search !== null) {\n $search->update([\n 'name' => $searchName,\n ]);\n\n return $search;\n }\n\n $request->validate([\n 'filters' => ['required', 'array', new MultidimensionalArrayMaxCharRule(limit: 255)],\n 'nudges' => 'array|max:' . count(Nudge::MAP_CHANNEL),\n 'nudges.*.channel' => 'required|in:' . implode(',', Nudge::MAP_CHANNEL),\n 'nudges.*.frequency' => 'required|in:' . implode(',', Nudge::MAP_FREQUENCY),\n 'nudges.*.expiresAt' => [\n 'required',\n 'date',\n 'after:today',\n 'before_or_equal:' . now()->addYear()->format('Y-m-d'),\n ],\n ]);\n\n $searchCriteria = Criteria::createFromRequest(\n Collection::make($request->input('filters', []))->all(),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($searchCriteria, $user);\n $this->validateSearch($request, $filterSet, 'filters.');\n\n /** @var Search $search */\n $search = Search::create([\n 'name' => $searchName,\n 'uuid' => Uuid::uuid4()->toString(),\n 'user_id' => $user->getId(),\n ]);\n\n Collection::make($request->input('nudges', []))\n ->each(fn (array $attributes): Nudge => $this->nudgeFactory->createNudge($search, $attributes));\n\n $this->storeNamedSearchFilters(Collection::make($request->all()), $search, $filterSet, 'filters.');\n\n return $search;\n }\n\n private function resolveAccount(\n Team $team,\n Contact $contact,\n ServiceInterface $crmService,\n array $prospects,\n ): ?Account {\n $this->logger->info('Resolving account from contact');\n $account = $contact->getAccount();\n\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS)) {\n $this->logger->info('Team does not have feature to link activity to multiple prospects');\n\n return $account;\n }\n\n $this->logger->info('Resolving account from prospect data');\n $accountData = array_filter(\n $prospects,\n static fn (array $prospectData): bool => $prospectData['type'] === 'account'\n );\n\n if (! empty($accountData)) {\n $this->logger->info('Found account data in prospects');\n $accountData = reset($accountData);\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountData['id'])->first();\n\n if (! $account instanceof Account) {\n $this->logger->info('Account not found in database, syncing from CRM');\n $account = $crmService->syncAccount($accountData['id']);\n }\n }\n\n $this->logger->info('Resolved account', ['account' => $account->getId()]);\n\n return $account;\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Http\\Controllers\\API;\n\nuse Carbon\\Carbon;\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Exception;\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Validation\\Rule;\nuse Illuminate\\Validation\\Rules\\In;\nuse Illuminate\\Validation\\ValidationException;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ActivityAnalytics;\nuse Jiminny\\Component\\ActivitySearch;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Contracts\\ES\\Events\\UpdateSingleEntity;\nuse Jiminny\\Contracts\\ES\\UpdateTargetEnum;\nuse Jiminny\\Contracts\\Nudge\\NudgeFactoryInterface;\nuse Jiminny\\Contracts\\Playlist\\PlaylistTrackFactoryInterface;\nuse Jiminny\\Contracts\\Repositories\\PlaylistActivityRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Enums\\TeamSetting;\nuse Jiminny\\Events\\Activities\\AiAutomation\\ActivityProspectAdded;\nuse Jiminny\\Events\\Activities\\Coaching\\Coached;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Controllers\\CommentContextInterface;\nuse Jiminny\\Http\\Responses\\Api\\AbstractResponse;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\ActivityCommentTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTopicTriggerTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTransformer;\nuse Jiminny\\Http\\Transformers\\AvailabilityNotificationTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingFeedbackTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingSectionsTransformer;\nuse Jiminny\\Http\\Transformers\\SearchTransformer;\nuse Jiminny\\Http\\Transformers\\StatsTransformer;\nuse Jiminny\\Jobs\\Crm\\SaveActivity;\nuse Jiminny\\Jobs\\Crm\\UpdateStage;\nuse Jiminny\\Jobs\\Telephony\\StartRecording;\nuse Jiminny\\Jobs\\Telephony\\StopRecording;\nuse Jiminny\\Jobs\\Telephony\\ToggleRecording;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\CoachingFeedback;\nuse Jiminny\\Models\\CoachingSection;\nuse Jiminny\\Models\\CoachingSectionCriterion;\nuse Jiminny\\Models\\CoachingSectionFeedback;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\LanguageDialect;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Nudge;\nuse Jiminny\\Models\\PlaybookCategory;\nuse Jiminny\\Models\\Playlist;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\Track;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\CoachingFeedbackRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Rules\\MultidimensionalArrayMaxCharRule;\nuse Jiminny\\Services\\ActivityService;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Services\\PlaybackService;\nuse Jiminny\\Services\\UserService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\nuse Ramsey\\Uuid\\Uuid;\nuse Sentry;\nuse Symfony\\Component\\HttpFoundation;\n\nfinal class ActivityController extends Controller implements CommentContextInterface\n{\n // Number of minutes to look back on activities. i.e. a timeout on activity duration.\n private const int LOOK_BACK = 180;\n\n public function __construct(\n private ProviderRegistry $providerRegistry,\n private ActivityService $activityService,\n Response $response,\n private UserService $userService,\n private ActivitySearch\\Service\\ActivitySearch $activitySearch,\n private NudgeFactoryInterface $nudgeFactory,\n private ActivityCommentService $activityCommentService,\n private LoggerInterface $logger,\n private readonly CoachingFeedbackRepository $coachingFeedbackRepository,\n private readonly TeamRepository $teamRepository,\n ) {\n parent::__construct($response);\n }\n\n public static function getCommentImplementation(): string\n {\n return Comment::class;\n }\n\n public function delete()\n {\n $this->request->validate([\n '*' => 'uuid:activities',\n ]);\n\n $deletedIds = [];\n foreach ($this->request->all() as $activityId) {\n $activity = Activity::idOrUuId($activityId);\n\n try {\n if ($this->authorize('delete', $activity)) {\n $activity->delete();\n $deletedIds[] = $activityId;\n\n \\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n }\n } catch (AuthorizationException $authorizationException) {\n // They didn't have permission.\n }\n }\n\n return $this->response->withArray($deletedIds);\n }\n\n public function update(Request $request, Activity $activity)\n {\n $this->authorize('updateMetadata', $activity);\n\n $request->validate([\n 'title' => 'string|max:250',\n 'category_id' => 'uuid:playbook_categories',\n 'language' => [\n new In(\n LanguageDialect::query()\n ->with('language')\n ->cursor()\n ->map(static function (LanguageDialect $languageDialect): string {\n return $languageDialect->getLanguageLocale();\n })\n ->all()\n ),\n ],\n ]);\n\n if ($request->has('title')) {\n $activity->title = $request->input('title');\n }\n\n if ($request->has('category_id')) {\n $category = PlaybookCategory::uuid($request->input('category_id'));\n\n if ($category->playbook->team_id !== $request->user()->team_id) {\n return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n if ($request->has('language')) {\n if (! $activity->isInProgress()) {\n return $this->response->withError(\n 'Activity language can only be set while the meeting is in progress.',\n 400\n );\n }\n\n $activity->setLanguageCode($request->input('language'));\n }\n\n $activity->save();\n\n return $this->response->withOk();\n }\n\n // XXX: This should be merged with the update method.\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws SocialAccountTokenInvalidException\n *\n * @return mixed\n */\n public function summarize(Activity $activity): mixed\n {\n $this->logger->info('[Log Activity] Summarizing activity ', [\n 'activityId' => $activity->getUuid(),\n 'payload' => $this->request->all(),\n ]);\n $this->authorize('update', $activity);\n\n $this->logger->info('[Log Activity] Validating summary');\n // Validate the payload.\n $this->validateSummary($activity);\n\n // All objects must belong to this team.\n /** @var User $user */\n $user = $this->request->user();\n $team = $user->getTeam();\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n try {\n $crmUser = $user;\n if ($user->isCrmRequired() === false) {\n $crmUser = $team->owner;\n }\n $crmService->setUser($crmUser);\n } catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());\n }\n\n $rawEntities = $this->request->input('entities');\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid(\n $this->request->input('layout_id')\n );\n\n // Delay execution of CRM jobs to avoid locking issues.\n $jobDelay = 0;\n\n // If we have arrived from a notification, mark it as read.\n $notificationId = $this->request->input('nId');\n if ($notificationId) {\n $notification = $user->unreadNotifications->where('id', $notificationId)->first();\n\n if ($notification) {\n $notification->markAsRead();\n }\n }\n\n $title = $this->request->input('title');\n $prospects = $this->request->input('prospects');\n $opportunityId = $this->request->input('opportunity_id');\n $stageId = $this->request->input('stage_id');\n $categoryId = $this->request->input('category_id');\n $summary = $this->request->input('summary');\n $crmProviderId = $this->request->input('crm_id');\n $isInternal = $this->request->input('is_internal') ?? false;\n\n $lead = null;\n $category = null;\n $account = null;\n $contact = null;\n $opportunity = null;\n $stage = null;\n $callStage = null;\n\n foreach ($prospects as $prospectData) {\n $objectId = $prospectData['id'];\n\n if ($objectId === null) {\n continue;\n }\n\n $objectType = $prospectData['type'];\n $this->logger->info('debug', ['prospect_data' => $prospectData]);\n\n try {\n if ($objectType === null) {\n $this->logger->info('no object type');\n if ($crmService instanceof SupportsObjectTypeParseInterface) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n }\n\n switch ($objectType) {\n case 'lead':\n $this->logger->info('Processing lead');\n /** @var Lead|null $lead */\n $lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();\n\n // Lead does not exist locally, import it.\n if ($lead === null) {\n $this->logger->info('Lead does not exist locally');\n /** @var Lead $lead */\n $lead = $crmService->syncLead($objectId);\n }\n\n $this->logger->info('Lead found', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n if ($stageId === null) {\n $this->logger->info('Stage ID is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $lead->stage;\n\n break;\n }\n\n $this->logger->info('Looking for stage');\n // Determine if they have changed the stage.\n /** @var Stage $stage */\n $stage = $team->crm->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_LEAD)\n ->firstOrFail();\n\n $this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);\n if ($lead->stage_id && $lead->stage_id !== $stage->id) {\n $this->logger->info('Stage has changed');\n // Storage current stage on activity.\n $callStage = $lead->stage;\n\n // The stage has changed, update in remote CRM.\n dispatch(new UpdateStage($activity, $lead, $callStage, $stage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing lead stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->getName(),\n $stage->getName()\n ),\n [\n 'user' => $user->getUuid(),\n 'lead' => $lead->getUuid(),\n ]\n );\n } else {\n $this->logger->info('Stage has not changed');\n // Stage remains as current.\n $callStage = $stage;\n }\n\n break;\n\n case 'account':\n $this->logger->info('Processing account');\n // If the object is not a lead, it should be an account.\n $account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();\n\n // Account does not exist locally, import it.\n if ($account === null) {\n $this->logger->info('Account does not exist locally');\n $account = $crmService->syncAccount($objectId);\n }\n\n $this->logger->info('Account found', ['accountId' => $account->id]);\n\n break;\n case 'contact':\n $this->logger->info('processing contact');\n $contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $this->logger->info('contact does not exist locally');\n $contact = $crmService->syncContact($objectId);\n }\n\n $this->logger->info('resolving account');\n $account = $this->resolveAccount($team, $contact, $crmService, $prospects);\n\n break;\n }\n\n // If they have specified an opportunity, retrieve this with stage.\n if ($opportunityId) {\n $this->logger->info('opportunity id is set');\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if ($opportunity === null) {\n $this->logger->info('opportunity does not exist locally');\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n if ($stageId === null) {\n $this->logger->info('stage id is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $opportunity->stage ?? null;\n } else {\n $this->logger->info('looking for stage');\n /** @var ?Stage $opportunityStage */\n $opportunityStage = $team->crm\n ->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n // There is a chance we still cannot import this opportunity.\n if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {\n $this->logger->info('opportunity stage has changed');\n // Storage current stage on activity.\n $callStage = $opportunity->stage;\n\n dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing opportunity stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->name,\n $opportunityStage->name\n ),\n [\n 'userId' => $user->id_string,\n 'opportunityId' => $opportunity->id_string,\n ]\n );\n } else {\n $this->logger->info('opportunity stage has not changed');\n // Stage remains as current.\n $callStage = $opportunityStage;\n }\n }\n }\n\n if ($crmProviderId) {\n // Cast $crmProviderId to string otherwise it won't use database index for some records\n $linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();\n\n // Check if this activity has already been assigned to a different activity.\n if ($linkedActivity && $linkedActivity->id !== $activity->id) {\n throw new InvalidArgumentException(\n 'Sorry, the linked task has already been logged under a different call. '\n . 'Please choose another linked task.'\n );\n }\n }\n } catch (InvalidArgumentException $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($exception->getMessage());\n } catch (Exception $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorInternalError(\n 'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'\n );\n }\n }\n\n if ($categoryId) {\n $category = PlaybookCategory::uuid($categoryId);\n\n if ($category->playbook->team_id !== $team->id) {\n throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n $this->logger->info('Prospect data', [\n 'lead_id' => $lead?->getId(),\n 'account_id' => $account?->getId(),\n 'contact_id' => $contact?->getId(),\n 'opportunity_id' => $opportunity?->getId(),\n 'stage_id' => $stage?->getId(),\n ]);\n\n if ($title) {\n $activity->title = $title;\n }\n\n if ($summary) {\n $activity->summary = $summary;\n }\n\n if ($crmProviderId) {\n $activity->crm_provider_id = $crmProviderId;\n }\n\n if ($callStage) {\n $this->logger->info('Setting stage id', ['stageId' => $callStage->id]);\n $activity->stage_id = $callStage->id;\n }\n\n if ($lead) {\n $this->logger->info('Setting lead id', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n // If we are changed from an account > lead, unset the account data.\n $this->logger->info('Unsetting account id, opportunity id, contact id, value');\n $activity->account_id = null;\n $activity->opportunity_id = null;\n $activity->contact_id = null;\n $activity->value = null;\n }\n\n if ($account) {\n $this->logger->info('Setting account id', ['accountId' => $account->id]);\n $activity->account_id = $account->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('unsetting lead id');\n $activity->lead_id = null;\n\n // Unset the contact if switching different accounts. Will be set up below if still applicable.\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {\n $this->logger->info('Unsetting contact id');\n $activity->contact_id = null;\n }\n }\n\n if ($opportunity) {\n $this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);\n $this->logger->info('unsetting lead id');\n $activity->opportunity_id = $opportunity->id;\n $activity->value = $opportunity->value;\n\n // If we are changed from an lead > account, unset the lead data.\n $activity->lead_id = null;\n }\n\n if ($contact) {\n $this->logger->info('setting contact id', ['contactId' => $contact->id]);\n $activity->contact_id = $contact->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('Unsetting lead id');\n $activity->lead_id = null;\n }\n\n $activity->is_internal = $isInternal;\n $activity->save();\n $activity->refresh();\n\n $this->logger->notice('Activity saved', [\n 'activity_id' => $activity->getId(),\n 'lead_id' => $activity->lead_id,\n 'account_id' => $activity->account_id,\n 'contact_id' => $activity->contact_id,\n 'opportunity_id' => $activity->opportunity_id,\n 'stage_id' => $activity->stage_id,\n 'crm_provider_id' => $activity->getCrmProviderId(),\n ]);\n\n // Store entities as field data on the activity.\n $updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);\n\n if ($activity->isLoggable()) {\n // Follow-up Task or Event data.\n $followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);\n\n $this->logger->info('CRM LOG manual log triggered', [\n 'activityId' => $activity->getUuid(),\n 'followupData' => $followupData,\n 'userId' => $user->getUuid(),\n ]);\n\n // Store data in the CRM.\n // ++add check for crm_required\n $job = new SaveActivity($activity, $followupData);\n\n if ($updatedData) {\n $job->delay(Carbon::now()->addMinutes($jobDelay));\n }\n\n dispatch($job);\n\n // Manually dispatch log for Opportunity or Prospect added\n if ($activity->hasOpportunity() || $activity->hasProspect()) {\n event(new ActivityProspectAdded(\n activity: $activity,\n eventSource: 'manually-log-crm-data'\n ));\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.\n *\n * @param ServiceInterface $service\n * @param Activity $activity\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array\n {\n $updatedData = [];\n $existingData = $activity->data()->get();\n\n // We need to delete any existing data to overwrite with latest values.\n $activity->data()->delete();\n\n $layoutEntities = $layout->entities()\n ->with('field', 'parent')\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->get();\n\n /** @var LayoutEntity $entity */\n foreach ($layoutEntities as $entity) {\n // If the user has provided a value for this entity\n if (array_key_exists($entity->id_string, $entities)) {\n $value = $entities[$entity->id_string];\n\n // Convert raw data into values that the CRM can consume.\n if ($value) {\n $value = $service->normalizeValue($entity->field->type, $value);\n }\n\n // Check the field is part of the activity-summary section.\n if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {\n // This is the internal database ID, not the external CRM ID.\n $objectId = null;\n\n switch ($entity->field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $objectId = $activity->account_id;\n\n break;\n\n case Field::OBJECT_CONTACT:\n $objectId = $activity->contact_id;\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n $objectId = $activity->opportunity_id;\n\n break;\n\n case Field::OBJECT_LEAD:\n $objectId = $activity->lead_id;\n\n break;\n\n case Field::OBJECT_TASK:\n case Field::OBJECT_EVENT:\n $objectId = $activity->id;\n\n break;\n }\n\n if ($objectId) {\n /** @var FieldData $data */\n $data = $activity->data()->create([\n 'crm_layout_entity_id' => $entity->id,\n 'crm_field_id' => $entity->crm_field_id,\n 'object_type' => $entity->field->object_type,\n 'object_id' => $objectId,\n 'value' => $value,\n ]);\n\n // Never send read-only field data to the CRM.\n if ($entity->read_only === false && $entity->is_visible) {\n $existingValue = $existingData\n ->where('crm_layout_entity_id', $entity->id)\n ->where('crm_field_id', $entity->crm_field_id)\n ->where('object_type', $entity->field->object_type)\n ->where('object_id', $objectId)\n ->first();\n\n // If the field was actually changed, we need to reflect this in the CRM too.\n if ($existingValue === null || $existingValue->value !== $value) {\n $updatedData[] = $data->id;\n }\n }\n }\n }\n }\n }\n\n return $updatedData;\n }\n\n /**\n * Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.\n *\n * @param ServiceInterface $crmService\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array\n {\n $fieldData = [];\n foreach ($entities as $entityId => $value) {\n // Only bother with fields that have a value.\n if ($value) {\n // Extract the entity from the UUID. Check the field is valid and part of the follow-up section.\n $entity = $layout->entities()\n ->uuid($entityId, false)\n ->whereHas('parent', function ($query) {\n $query->where('label', 'follow-up');\n })\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->first();\n\n if ($entity) {\n // Convert raw data into values that the CRM can consume.\n $value = $crmService->normalizeValue($entity->field->type, $value);\n\n // Add the field and value to the payload.\n $fieldData += [\n $entity->field->crm_provider_id => $value,\n ];\n }\n }\n }\n\n return $fieldData;\n }\n\n /**\n * @param Activity $activity\n */\n private function validateSummary(Activity $activity): void\n {\n $team = $activity->user->team;\n $crmProvider = $team->crm->provider;\n $attributes = [];\n\n $rules = [\n 'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,\n 'title' => 'string|max:250',\n 'prospects' => 'required|array',\n 'opportunity_id' => new CrmReference($crmProvider),\n 'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',\n 'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator\n 'summary' => 'max:50000',\n 'nId' => 'exists:notifications,id',\n 'crm_id' => new CrmReference($crmProvider),\n 'entities' => 'array',\n 'is_internal' => 'boolean',\n ];\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));\n\n // Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.\n $entities = $layout->entities()\n ->where('read_only', 0)\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->whereHas('parent', function ($query) use ($activity) {\n if ($activity->isLoggable() === false) {\n $query->where('label', '<>', 'follow-up');\n }\n });\n\n $isInternal = $this->request->input('is_internal', false);\n\n foreach ($entities->get() as $entity) {\n $rules += $this->buildFieldValidator($entity, $isInternal);\n $attributes += $this->buildFieldMessage($entity);\n }\n\n $this->request->validate($rules, [], $attributes);\n }\n\n private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array\n {\n return [\n 'entities.' . $entity->id_string => $entity->getValidator($isInternal),\n ];\n }\n\n /**\n * @param LayoutEntity $entity\n *\n * @return array\n */\n private function buildFieldMessage(LayoutEntity $entity): array\n {\n $label = $entity->label;\n if ($label === null) {\n $label = $entity->field->label;\n }\n\n return [\n 'entities.' . $entity->id_string => $label,\n ];\n }\n\n public function search(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->debugLog(\n $user,\n 'User extracted from request',\n ['user' => $user->getId(), 'tz' => $user->getTimezone()]\n );\n\n $searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());\n\n $this->debugLog(\n $user,\n 'ActivitySearch criteria built',\n ['searchCriteria' => $searchCriteria]\n );\n\n $filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);\n\n $this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);\n\n $this->validateSearch($request, $filterSet);\n\n $this->debugLog($user, 'Request validated');\n\n $searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);\n\n /** @var Collection<Activity> $activities */\n $activities = $searchResponse['results'];\n\n $this->debugLog($user, 'Activities ES response extracted');\n\n $hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(\n $user->getTeamId(),\n TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),\n );\n\n if ($hideInternalMeetingsSetting?->getValue() === '1') {\n $activities = $activities->filter(function (Activity $activity) {\n if ($activity->is_internal && empty($activity->actual_start_time)) {\n return false;\n }\n\n return true;\n });\n }\n\n $this->debugLog($user, 'Internal meetings (?!) filtered');\n\n $this->response->getManager()\n ->parseIncludes([\n 'category',\n 'organizer.group',\n 'prospect',\n 'stage',\n 'opportunity',\n 'stats',\n 'scorecards',\n 'masterTrack',\n 'activeParticipants',\n 'notification',\n ])\n ->setSerializer(new JsonSerializer());\n\n $transformerExcludes = $this->request->input('exclude');\n if ($transformerExcludes) {\n $this->response->getManager()->parseExcludes($transformerExcludes);\n }\n\n $this->debugLog($user, 'Response Manager (?!) applied');\n\n $transformer = new ActivityTransformer();\n $transformer->setConsumer($user);\n\n $this->debugLog($user, 'Activity Transformer added');\n\n $resource = new \\League\\Fractal\\Resource\\Collection($activities, $transformer);\n $page = $searchCriteria->getPageNumber();\n\n $this->debugLog($user, 'Search criteria page number called', ['page' => $page]);\n\n $histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');\n\n $this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);\n\n return $this->response->withArray([\n 'pagination' => [\n 'total' => $searchResponse['totalHits'],\n 'current' => $page,\n 'prev' => max($page - 1, 1),\n 'next' => $page + 1,\n ],\n 'results' => $this->response->getManager()->createData($resource)->toArray(),\n 'histogram' => $histogram,\n ]);\n }\n\n private function debugLog(User $user, string $logMessage, ?array $context = []): void\n {\n // Debug for Learning People Only\n if ($user->getTeamId() !== 260) {\n return;\n }\n\n Log::notice(\n sprintf('[activity-search-controller] %s', $logMessage),\n $context\n );\n }\n\n /** @throws ValidationException */\n private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void\n {\n $rules = [\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ];\n\n if ($prefix !== null && mb_strpos($prefix, '.') !== false) {\n $rules[rtrim($prefix, '.')] = sprintf(\n 'required|array|max:%d',\n $filterSet->count()\n );\n }\n\n $validationRules = $filterSet->getValidationRules($prefix)\n ->merge($rules)\n ->all();\n\n $request->validate($validationRules);\n }\n\n public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $search = $this->updateOrCreateActivitySearch($request);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function updateActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('update', $search);\n\n $this->updateOrCreateActivitySearch($request, $search);\n\n return $this->response->withOk();\n }\n\n private function storeNamedSearchFilters(\n Collection $request,\n Search $search,\n FilterDefinitionCollection $filterSet,\n ?string $prefix = null,\n ): self {\n $arrayTypeProperties = $filterSet\n ->getPropertyTypes([\n FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,\n ])\n ->all();\n\n $supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);\n\n foreach ($supportedRequestProperties as $requestPropertyName) {\n if (! array_has($request, $requestPropertyName)) {\n continue;\n }\n\n /** @var string|string[] $propertyValue */\n $propertyValue = array_get($request, $requestPropertyName);\n $propertyName = $prefix === null\n ? $requestPropertyName\n : mb_substr($requestPropertyName, mb_strlen($prefix));\n\n $isArrayType = array_has($arrayTypeProperties, $propertyName);\n\n if (! $isArrayType) {\n /** @var string $requestPropertyValue */\n\n $search->filters()->updateOrCreate(\n [\n 'filter' => $propertyName,\n ],\n [\n 'value' => $propertyValue,\n ]\n );\n\n continue;\n }\n\n /** @var string[] $requestPropertyValue */\n\n /** @var SearchFilter[]|Collection $existingFilterValues */\n $existingFilterValuesKeyed = $search->filters()\n ->where('filter', $propertyName)\n ->get()\n ->keyBy('id');\n\n // Iterate over values provided as request parameters\n foreach ($propertyValue as $value) {\n /** @var SearchFilter|null $valueFilter */\n $valueFilter = $search->filters()\n ->where(\n [\n 'filter' => $propertyName,\n 'value' => $value,\n ]\n )\n ->first();\n\n if ($valueFilter !== null) {\n // Remove filter value pair from list to be deleted\n $existingFilterValuesKeyed->forget($valueFilter->id);\n } else {\n // Add new filter/value pair\n $search->filters()->updateOrCreate([\n 'filter' => $propertyName,\n 'value' => $value,\n ]);\n }\n }\n\n // Delete filter value pairs for this filter that no longer exist in request parameters\n foreach ($existingFilterValuesKeyed as $existingFilter) {\n $existingFilter->delete();\n }\n }\n\n /** @var Collection<int, SearchFilter> $filtersKeyed */\n $filtersKeyed = $search->filters()->get()->keyBy('filter');\n\n // wipe removed filters from this search\n foreach ($filtersKeyed as $filterName => $filter) {\n if (array_has($request, $prefix . $filterName)) {\n continue;\n }\n\n // Remove all filter values for this filter\n $search->filters()->where('filter', $filterName)->delete();\n }\n\n return $this;\n }\n\n /**\n * @throws AuthorizationException\n */\n public function fetchActivitySearch(\n Search $search,\n Request $request,\n SearchTransformer $searchTransformer,\n ): JsonResponse {\n $this->authorize('view', $search);\n\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection(\n $user->searches()->get(),\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n /**\n * Deletes a saved search\n *\n * @param Request $request\n * @param Search $search\n *\n * @throws Exception\n *\n * @return JsonResponse\n */\n public function deleteActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('delete', $search);\n\n // Orphan any AutomatedReports that use this search\n $search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);\n\n // Delete filters and the search itself\n $search->filters()->delete();\n $search->delete();\n\n return $this->response->withOk();\n }\n\n public function live(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n $user = $this->getUserFromRequest($request);\n\n $this->request->validate([\n 'sort_direction' => 'in:asc,desc',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ]);\n\n $activities = $repository->getLiveCoachingEligibleActivities(\n user: $user,\n lookBackMinutes: self::LOOK_BACK,\n limit: (int) $this->request->input('limit', 25),\n page: (int) $this->request->input('page', 1),\n sortBy: ['actual_start_time', 'scheduled_start_time'],\n sortDirection: (string) $this->request->input('sort_direction', 'asc'),\n );\n\n $this->response\n ->getManager()\n ->parseIncludes(['organizer.group', 'prospect'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($activities, new ActivityTransformer());\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function show(Activity $activity, ActivityService $activityService): JsonResponse\n {\n $this->authorize('show', $activity);\n\n $user = $activity->getUser();\n $team = $user->getTeam();\n\n // Sync the opportunity with the latest data if possible.\n if ($activity->opportunity_id) {\n try {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n if (! $user->isCrmRequired()) {\n $crmService->setUser($team->getOwner());\n } else {\n $crmService->setUser($user);\n }\n\n $crmService->syncOpportunity($activity->opportunity->crm_provider_id);\n } catch (Exception $exception) {\n // Move on.\n }\n }\n\n $activityData = $activityService->getActivityData($this->request->user(), $activity);\n\n return response()->json($activityData);\n }\n\n public function createRecording(Activity $activity)\n {\n $this->authorize('record', $activity);\n\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Tell Twilio to start recording this activity.\n if ($activity->recording_state === Activity::RECORDING_OFF) {\n $job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withCreated();\n }\n\n return $this->response->errorGone('Activity is already recording.');\n }\n\n public function updateRecording(Request $request, Activity $activity)\n {\n $this->authorize('record', $activity);\n\n $request->validate([\n 'preference' => 'boolean',\n 'state' => [\n 'string',\n Rule::in([\n Activity::RECORDING_IN_PROGRESS,\n Activity::RECORDING_PAUSED,\n ]),\n ],\n ]);\n\n if ($request->has('state')) {\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Toggle the recording state between paused and resumed.\n if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {\n $job = (new ToggleRecording($activity, $request->input('state')))\n ->onQueue(Constants::QUEUE_CONFERENCES);\n\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Recording is not toggleable.');\n }\n\n if ($request->has('preference')) {\n $activity->update([\n 'recording_preference' => $request->input('preference') ? 1 : 0,\n ]);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorWrongArgs('Something went wrong');\n }\n\n public function stopRecording(Activity $activity)\n {\n $this->authorize('stopRecord', $activity);\n\n // Tell Twilio to stop recording this activity.\n if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {\n $job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Activity is not recording.');\n }\n\n /**\n * Add activity to this user's favorites playlist\n *\n * @throws AuthorizationException\n */\n public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse\n {\n $this->authorize('favorite', $activity);\n\n $user = $this->getUserFromRequest($this->request);\n $favorite = $activity->wasFavoritedBy($user);\n $name = $activity->activity_title ?? '';\n\n // It needs to check at least one record.\n if (! $favorite) {\n $favoritePlaylist = $user->favoritePlaylist();\n\n $playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(\n $activity,\n $user,\n $favoritePlaylist\n );\n\n if ($playlistActivity !== null) {\n $playlistActivity->update(\n // Just update, don't sort.\n ['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],\n );\n } else {\n $playlistActivity = $activity->playlistActivities()->create([\n 'playlist_id' => $favoritePlaylist->getId(),\n 'user_id' => $user->getId(),\n 'start_time' => 0,\n 'name' => mb_strimwidth($name, 0, 100),\n ]);\n // Sort it on top.\n $playlistActivity->update(\n [\n 'sort' => $playlistActivityRepository->calculateNewSortOrder(\n null,\n $playlistActivity,\n ),\n ],\n );\n }\n\n $playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);\n\n return new JsonResponse([], JsonResponse::HTTP_CREATED);\n }\n\n return new JsonResponse(\n [\n 'error' => [\n 'code' => AbstractResponse::CODE_CONFLICT,\n 'http_code' => JsonResponse::HTTP_CONFLICT,\n 'message' => 'Resource Already Exists',\n ],\n ],\n JsonResponse::HTTP_CONFLICT,\n );\n }\n\n /**\n * Remove activity from this user's favorites playlist\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unfavorite(Activity $activity)\n {\n $user = $this->request->user();\n\n $favorites = $activity->favoritedBy($user);\n\n if ($favorites && $favorites->isEmpty()) {\n return $this->response->errorNotFound('Favorite not found.');\n }\n\n $this->authorize('unfavorite', [$activity, $favorites]);\n\n // When you unfavorite an activity,\n // it should remove all the activities in it, including snippets.\n $isDeleted = $favorites->each(function ($favorite) {\n $favorite->forceDelete();\n });\n\n if ($isDeleted) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not remove favorite.');\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function notify(Activity $activity)\n {\n $this->authorize('notify', $activity);\n\n $user = $this->request->user();\n\n $existingNotification = $activity->availabilityNotifications()\n ->where('user_id', $user->id)\n ->exists();\n\n if ($existingNotification) {\n return $this->response->errorWrongArgs('Notification is already configured.');\n }\n\n $notification = Activity\\AvailabilityNotification::create([\n 'user_id' => $user->id,\n 'activity_id' => $activity->id,\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($notification, new AvailabilityNotificationTransformer());\n }\n\n /**\n * @param Activity $activity\n * @param Activity\\AvailabilityNotification $notification\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unnotify(Activity $activity, Activity\\AvailabilityNotification $notification)\n {\n $this->authorize('unnotify', [$activity, $notification]);\n\n if ($notification->sent_at || $notification->delete()) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not delete notification.');\n }\n\n public function play(Request $request, Activity $activity)\n {\n $this->authorize('stream', $activity);\n\n $request->validate([\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $activity->plays()->create([\n 'user_id' => $user->getId(),\n 'start_time' => $request->input('start_time'),\n ]);\n\n return $this->response->withCreated();\n }\n\n /**\n * @param Activity $activity\n *\n * @return mixed\n */\n public function comment(Activity $activity)\n {\n return $this->newComment($activity);\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @return mixed\n */\n public function replyComment(Activity $activity, Comment $comment)\n {\n return $this->newComment($activity, $comment);\n }\n\n /**\n * @param Activity $activity\n * @param Comment|null $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n protected function newComment(Activity $activity, ?Comment $comment = null)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n 'type' => 'integer|between:0,3',\n 'visibility' => sprintf('nullable|integer|between:1,%d', count(Comment::getVisibilityLevels())),\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n $threadStartId = null;\n if ($comment) {\n $threadStartId = $comment->thread_start_id ?: $comment->id;\n }\n\n try {\n $newComment = Comment::create([\n 'parent_comment_id' => $comment->id ?? null,\n 'thread_start_id' => $threadStartId,\n 'activity_id' => $activity->id,\n 'user_id' => $this->request->user()->id,\n 'comment' => trim($this->request->input('comment')),\n 'start_time' => $this->request->input('start_time', 0),\n 'end_time' => $this->request->input('end_time', 0),\n 'type' => $this->request->input('type', Comment::TYPE_NEUTRAL),\n 'visibility' => $this->request->input('visibility', Comment::VISIBILITY_PUBLIC),\n ]);\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($newComment, new ActivityCommentTransformer());\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not create comment.' . $exception->getMessage());\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function updateComment(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n try {\n $comment->update([\n 'comment' => trim($this->request->input('comment')),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment.');\n }\n }\n\n public function updateCommentVisibility(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'visibility' => sprintf('integer|between:1,%d', count(Comment::getVisibilityLevels())),\n ]);\n\n $visibility = $this->request->input('visibility');\n\n if ($comment->parent !== null) {\n return $this->response->errorWrongArgs('Comment visibility can only be updated on top level comments.');\n }\n\n try {\n $this->activityCommentService->updateCommentVisibility($comment, $visibility);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment\\'s visibility.');\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function deleteComment(Activity $activity, Comment $comment)\n {\n $this->authorize('deleteComment', [$activity, $comment]);\n\n // Delete comment and any children.\n $comment->delete();\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function fetchComments()\n {\n $user = $this->request->user();\n $this->request->validate([\n 'forUserId' => 'uuid:users,team_id,' . $user->team_id,\n 'types' => 'array',\n 'types.*' => 'integer|between:0,3',\n ]);\n $forUser = null;\n\n $types = [Comment::TYPE_NEUTRAL, Comment::TYPE_GAME_CHANGER, Comment::TYPE_POSITIVE];\n $user = $this->request->user();\n if ($this->request->has('forUserId')) {\n $forUser = $user->team->users()->uuid($this->request->input('forUserId'));\n }\n\n $comments = Comment::query()\n ->whereHas('activity', static function (Builder $builder) use ($user, $forUser): void {\n $builder\n // I left feedback on my own activity; or\n ->where('activities.user_id', $user->getId());\n if ($forUser) {\n // I left feedback on any activity for this user.\n $builder->orWhere([\n 'user_id' => $user->getId(),\n 'activities.user_id' => $forUser->getId(),\n ]);\n }\n })\n ->whereIn('type', $this->request->input('types', $types))\n ->orderBy('created_at', 'desc')\n ->get();\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity', 'user'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($comments, new ActivityCommentTransformer());\n }\n\n public function deleteCoachingFeedback(Activity $activity, CoachingFeedback $coachingFeedback)\n {\n $this->authorize('deleteCoachingFeedback', [$activity, $coachingFeedback]);\n $activity = $coachingFeedback->getActivity();\n\n if ($coachingFeedback->delete()) {\n event(new UpdateSingleEntity(\n entityId: $activity->getId(),\n updateTarget: UpdateTargetEnum::ACTIVITY,\n purpose: 'delete-coaching-feedback',\n ));\n\n return $this->response->withOk();\n }\n\n return $this->response->withError('Delete operation failed. Contact support.', 500);\n }\n\n /**\n * Add new or update Coaching feedback\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws \\Illuminate\\Validation\\ValidationException\n *\n * @return mixed\n */\n public function putCoachingFeedback(Request $request, Activity $activity)\n {\n $user = $request->user();\n\n if (! $user instanceof User) {\n abort(403);\n }\n $teamId = $user->getTeamId();\n\n $this->authorize('coach', $activity);\n\n $this->request->validate([\n 'coach_id' => 'required|uuid:users,team_id,' . $teamId,\n 'coachee_id' => 'required|uuid:users,team_id,' . $teamId,\n 'visibility' => ['required', Rule::in(CoachingFeedback::VISIBILITIES)],\n 'coaching_sections.*.uuid' => 'required|uuid:coaching_sections',\n 'coaching_sections.*.score' => ['required', Rule::in(CoachingSectionFeedback::SCORES)],\n 'coaching_sections.*.summary' => 'string|max:10000',\n 'coaching_sections.*.criteria.*.uuid' => 'required|uuid:coaching_section_criteria',\n 'coaching_sections.*.criteria.*.note' => 'required|string|max:10000',\n 'sharedWithUsers' => [\n 'required_if:visibility,' . CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS,\n 'array',\n ],\n 'sharedWithUsers.*' => [\n 'uuid:users,team_id,' . $teamId,\n ],\n ]);\n\n /** @var User $coach */\n $coach = User::uuid($this->request->input('coach_id'));\n /** @var User $coachee */\n $coachee = User::uuid($this->request->input('coachee_id'));\n $coachingSectionFeedbacks = $this->request->input('coaching_sections');\n\n $previousRecord = $this->coachingFeedbackRepository->getOneForActivityByCoacheeAndCoach(\n $coachee->getId(),\n $coach->getId(),\n $activity->getId()\n );\n $recordIsNew = false;\n if ($previousRecord === null) {\n $recordIsNew = true;\n }\n\n if (! $coachee->isSameTeamId($coach)) {\n return $this->response->errorForbidden('User not member of your team.');\n }\n\n if (! is_array($coachingSectionFeedbacks) || count($coachingSectionFeedbacks) < 1) {\n return $this->response->withError('At least one Coaching Framework Section shall be scored.', 422);\n }\n\n if (! $activity->participants()->where('participants.user_id', $coachee->id)->exists()) {\n return $this->response->withError('Coached user did not participate activity.', 422);\n }\n\n $visibility = $this->request->input('visibility');\n\n $shouldSendNotification = $recordIsNew;\n if ($recordIsNew === false && $visibility !== $previousRecord->getVisibility()) {\n $shouldSendNotification = true;\n }\n\n /**\n * Create CoachingFeedback\n *\n * @var CoachingFeedback $coachingFeedback\n */\n $coachingFeedback = $activity->coachingFeedbacks()->updateOrCreate(\n [\n 'coach_id' => $coach->id,\n 'coachee_id' => $coachee->id,\n ],\n [\n 'framework_id' => $activity->category->id,\n 'visibility' => $visibility,\n ]\n );\n\n $sharedUserIds = [];\n if ($visibility === CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS) {\n foreach ($this->request->input('sharedWithUsers') as $sharedWithUserUuid) {\n /** @var User $user */\n $user = User::uuid($sharedWithUserUuid);\n $sharedUserIds[] = $user->getId();\n }\n }\n\n $syncResult = $coachingFeedback->customAccessUsers()->sync($sharedUserIds);\n\n $scores = [];\n\n\n /**\n * Create CoachingSectionsFeedbacks.\n *\n * @var CoachingSectionFeedback $coachingSectionFeedback\n */\n foreach ($coachingSectionFeedbacks as $coachingSectionFeedbackInput) {\n $coachingSection = CoachingSection::uuid($coachingSectionFeedbackInput['uuid']);\n $coachingSectionFeedback = $coachingFeedback->sectionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_id' => $coachingSection->id,\n ],\n [\n 'score' => array_get($coachingSectionFeedbackInput, 'score'),\n 'summary' => array_get($coachingSectionFeedbackInput, 'summary') ?? '',\n ]\n );\n\n $scores[] = array_get($coachingSectionFeedbackInput, 'score');\n\n $criteria = array_get($coachingSectionFeedbackInput, 'criteria');\n if (is_array($criteria) && ! empty($criteria)) {\n foreach ($criteria as $criteriaFeedbackInput) {\n $coachingSectionFeedback->criterionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_criterion_id' => CoachingSectionCriterion::uuid(array_get($criteriaFeedbackInput, 'uuid'))\n ->id,\n ],\n ['note' => array_get($criteriaFeedbackInput, 'note')],\n );\n }\n }\n }\n\n $coachingFeedback->average_score = array_sum($scores) / count($scores);\n\n if ($recordIsNew === false && $coachingFeedback->getAverageScore() !== $previousRecord->getAverageScore()) {\n $shouldSendNotification = true;\n }\n if (! empty($syncResult['attached']) || ! empty($syncResult['detached']) || ! empty($syncResult['updated'])) {\n $shouldSendNotification = true;\n }\n\n $coachingFeedback->save();\n // ensure updated at for coaching feedback on section feedback summary added.\n $coachingFeedback->touch();\n\n if ($shouldSendNotification) {\n event(new Coached($coachingFeedback));\n }\n\n Datadog::increment('jiminny.activity.score.update', 1, ['company' => $activity->user->team->slug]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n $coachingFeedbackTransformer = new CoachingFeedbackTransformer();\n $coachingFeedbackTransformer->setConsumer($this->getUserFromRequest($request));\n\n return $this->response->withItem($coachingFeedback, $coachingFeedbackTransformer);\n }\n\n\n /**\n * Retrieve category criteria for coaching.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachingSections(Activity $activity)\n {\n $this->authorize('coach', $activity);\n\n if ($activity->category === null) {\n return $this->response->errorUnprocessable('Category has not yet been assigned.');\n }\n\n $criteria = $activity\n ->category\n ->coachingSections()\n ->where('is_enabled', 1)\n ->orderBy('sequence', 'asc');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($criteria->get(), new CoachingSectionsTransformer());\n }\n\n /**\n * @throws AuthorizationException\n * @throws ValidationException\n *\n * @return mixed\n */\n public function addToPlaylist(Activity $activity, PlaylistTrackFactoryInterface $playlistTrackFactory)\n {\n $this->request->validate([\n 'playlists' => 'required|array',\n 'playlists.*' => 'uuid:playlists',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'name' => 'required|max:100',\n ]);\n\n $this->authorize('addToPlaylist', [$activity, $this->request->input('playlists')]);\n\n $startTime = $this->request->input('start_time');\n $endTime = $this->request->input('end_time');\n $name = $this->request->input('name');\n /** @var User $user */\n $user = $this->request->user();\n\n // Get playlist by uuid.\n foreach ($this->request->input('playlists') as $playlistId) {\n // Pull out the playlist model.\n $playlist = Playlist::uuid($playlistId);\n\n $playlistTrackFactory->createTrack($playlist, $user, [\n 'name' => $name,\n 'activity' => $activity,\n 'start_time' => $startTime,\n 'end_time' => $endTime,\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function share(Request $request, Activity $activity): JsonResponse\n {\n $this->authorize('share', $activity);\n\n $request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'recipients.*.type' => 'in:user,group',\n 'recipients.*.id' => 'string|max:40',\n 'share' => 'string|max:255',\n ]);\n\n $user = $request->user();\n\n $recipients = $request->get('recipients');\n $users = $this->userService->convertRecipientsToUsers($user, $recipients);\n\n $shareData = [\n 'from_user_id' => $user->id,\n 'note' => $request->input('note'),\n 'start_time' => $request->input('start_time'),\n 'end_time' => $request->input('end_time'),\n ];\n\n // Create a share object against a notification provider channel\n if ($request->input('share')) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'notification_provider_channel' => $request->input('share'),\n ]\n )\n );\n\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n\n // Create a share object against each recipient\n foreach ($users as $recipient) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'to_user_id' => $recipient->id,\n ]\n )\n );\n\n // If parent_share_id has been selected yet\n if (! isset($shareData['parent_share_id'])) {\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachRequest(Activity $activity)\n {\n $this->authorize('coachRequest', $activity);\n\n $this->request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'coachers.*.type' => 'required|in:user',\n 'coachers.*.id' => 'required',\n ]);\n\n $coachers = $this->request->get('coachers');\n $user = $this->request->user();\n $users = $this->userService->convertRecipientsToUsers($user, $coachers);\n\n foreach ($users as $coacher) {\n CoachRequest::create([\n 'user_id' => $coacher->id,\n 'activity_id' => $activity->id,\n 'note' => $this->request->get('note'),\n 'start_time' => $this->request->get('start_time'),\n 'end_time' => $this->request->get('end_time'),\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function createActivityTopicTriggers(Activity $activity, LoggerInterface $logger): HttpFoundation\\JsonResponse\n {\n $this->authorize('analyzeTopicTriggers', $activity);\n\n if (! $activity->hasTranscription()) {\n return new HttpFoundation\\JsonResponse(\n [\n 'error' => 'Transcription not found.',\n ],\n JsonResponse::HTTP_NOT_FOUND\n );\n }\n\n $logger->info(__METHOD__ . ': queued for analysis', [\n 'activity' => $activity->id_string,\n ]);\n\n dispatch(new ActivityAnalytics\\Job\\AnalyzeActivityTopicTriggers($activity));\n\n return new HttpFoundation\\JsonResponse(null, JsonResponse::HTTP_CREATED);\n }\n\n public function fetchActivityTopicTriggers(\n Activity $activity,\n LoggerInterface $logger,\n ActivityTopicTriggerTransformer $transformer\n ): HttpFoundation\\JsonResponse {\n $this->authorize('fetchTopicTriggers', $activity);\n\n $logger->debug(__METHOD__, [\n 'activity' => $activity->id_string,\n ]);\n\n if (! $activity->isProcessed()) {\n return new HttpFoundation\\JsonResponse([]);\n }\n\n $payload = [];\n\n if ($activity->hasTopicTriggers()) {\n $payload = $activity->getTopicTriggersSorted()\n ->map(\n static fn (Activity\\TopicTrigger $activityTopicTrigger): array\n => $transformer->transform($activityTopicTrigger)\n )\n ->values()\n ->all();\n }\n\n return new HttpFoundation\\JsonResponse($payload);\n }\n\n /**\n * @param Activity $activity\n * @param StatsTransformer $statsTransformer\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function stats(Activity $activity, StatsTransformer $statsTransformer)\n {\n $this->authorize('stream', $activity);\n\n if (! $activity->hasTranscription()) {\n return $this->response->errorNotFound('Waveform data is not yet generated.');\n }\n\n $this->response\n ->getManager()\n ->parseIncludes(['wavedata'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($activity, $statsTransformer);\n }\n\n public function destroy(Activity $activity)\n {\n $this->authorize('delete', $activity);\n\n $activity->delete();\n\n \\Log::info('Soft delete activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n\n return $this->response->withNoContent();\n }\n\n public function note(Activity $activity)\n {\n $this->authorize('note', $activity);\n\n $this->request->validate([\n 'note' => 'required|min:1|max:2000',\n 'time' => 'required|numeric|min:0|max:86400',\n ]);\n\n $note = $this->request->input('note');\n $time = $this->request->input('time');\n\n $this->activityService->setActivity($activity);\n $this->activityService->takeNote($this->getUser(), $note, $time);\n\n return $this->response->withCreated();\n }\n\n /**\n * Mark an activity as private.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPrivate(Activity $activity)\n {\n $this->authorize('markAsPrivate', $activity);\n\n if ($activity->is_private === false) {\n $activity->is_private = true;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * Mark an activity as public.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPublic(Activity $activity)\n {\n $this->authorize('markAsPublic', $activity);\n\n if ($activity->is_private) {\n $activity->is_private = false;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws LogicException\n */\n public function fetchCloudFrontS3MediaKeys(Activity $activity, PlaybackService $playbackService): JsonResponse\n {\n $masterTrack = $activity->masterTrack()->first();\n\n if (! $masterTrack instanceof Track) {\n throw new LogicException(sprintf('Master track not found for activity \"%s\"', $activity->getUuid()));\n }\n\n return $this->response->withArray(\n $playbackService->generateCookies(\n $masterTrack,\n $this->request->ip(),\n ),\n );\n }\n\n /**\n * @throws ValidationException\n */\n private function updateOrCreateActivitySearch(Request $request, ?Search $search = null): Search\n {\n $request->validate([\n 'name' => 'required|string|min:2|max:100',\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $searchName = $request->input('name');\n\n if ($search !== null) {\n $search->update([\n 'name' => $searchName,\n ]);\n\n return $search;\n }\n\n $request->validate([\n 'filters' => ['required', 'array', new MultidimensionalArrayMaxCharRule(limit: 255)],\n 'nudges' => 'array|max:' . count(Nudge::MAP_CHANNEL),\n 'nudges.*.channel' => 'required|in:' . implode(',', Nudge::MAP_CHANNEL),\n 'nudges.*.frequency' => 'required|in:' . implode(',', Nudge::MAP_FREQUENCY),\n 'nudges.*.expiresAt' => [\n 'required',\n 'date',\n 'after:today',\n 'before_or_equal:' . now()->addYear()->format('Y-m-d'),\n ],\n ]);\n\n $searchCriteria = Criteria::createFromRequest(\n Collection::make($request->input('filters', []))->all(),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($searchCriteria, $user);\n $this->validateSearch($request, $filterSet, 'filters.');\n\n /** @var Search $search */\n $search = Search::create([\n 'name' => $searchName,\n 'uuid' => Uuid::uuid4()->toString(),\n 'user_id' => $user->getId(),\n ]);\n\n Collection::make($request->input('nudges', []))\n ->each(fn (array $attributes): Nudge => $this->nudgeFactory->createNudge($search, $attributes));\n\n $this->storeNamedSearchFilters(Collection::make($request->all()), $search, $filterSet, 'filters.');\n\n return $search;\n }\n\n private function resolveAccount(\n Team $team,\n Contact $contact,\n ServiceInterface $crmService,\n array $prospects,\n ): ?Account {\n $this->logger->info('Resolving account from contact');\n $account = $contact->getAccount();\n\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS)) {\n $this->logger->info('Team does not have feature to link activity to multiple prospects');\n\n return $account;\n }\n\n $this->logger->info('Resolving account from prospect data');\n $accountData = array_filter(\n $prospects,\n static fn (array $prospectData): bool => $prospectData['type'] === 'account'\n );\n\n if (! empty($accountData)) {\n $this->logger->info('Found account data in prospects');\n $accountData = reset($accountData);\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountData['id'])->first();\n\n if (! $account instanceof Account) {\n $this->logger->info('Account not found in database, syncing from CRM');\n $account = $crmService->syncAccount($accountData['id']);\n }\n }\n\n $this->logger->info('Resolved account', ['account' => $account->getId()]);\n\n return $account;\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":"40","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"40","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"64","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","depth":4,"on_screen":true,"value":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","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}]...
|
-7287184300264252456
|
-8385861013499833196
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use Carbon\Carbon;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\In;
use Illuminate\Validation\ValidationException;
use InvalidArgumentException;
use Jiminny\Component\ActivityAnalytics;
use Jiminny\Component\ActivitySearch;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Queue\Constants;
use Jiminny\Contracts\ES\Events\UpdateSingleEntity;
use Jiminny\Contracts\ES\UpdateTargetEnum;
use Jiminny\Contracts\Nudge\NudgeFactoryInterface;
use Jiminny\Contracts\Playlist\PlaylistTrackFactoryInterface;
use Jiminny\Contracts\Repositories\PlaylistActivityRepository;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Enums\TeamSetting;
use Jiminny\Events\Activities\AiAutomation\ActivityProspectAdded;
use Jiminny\Events\Activities\Coaching\Coached;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Controllers\CommentContextInterface;
use Jiminny\Http\Responses\Api\AbstractResponse;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\ActivityCommentTransformer;
use Jiminny\Http\Transformers\ActivityTopicTriggerTransformer;
use Jiminny\Http\Transformers\ActivityTransformer;
use Jiminny\Http\Transformers\AvailabilityNotificationTransformer;
use Jiminny\Http\Transformers\CoachingFeedbackTransformer;
use Jiminny\Http\Transformers\CoachingSectionsTransformer;
use Jiminny\Http\Transformers\SearchTransformer;
use Jiminny\Http\Transformers\StatsTransformer;
use Jiminny\Jobs\Crm\SaveActivity;
use Jiminny\Jobs\Crm\UpdateStage;
use Jiminny\Jobs\Telephony\StartRecording;
use Jiminny\Jobs\Telephony\StopRecording;
use Jiminny\Jobs\Telephony\ToggleRecording;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\CoachingFeedback;
use Jiminny\Models\CoachingSection;
use Jiminny\Models\CoachingSectionCriterion;
use Jiminny\Models\CoachingSectionFeedback;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\LanguageDialect;
use Jiminny\Models\Lead;
use Jiminny\Models\Nudge;
use Jiminny\Models\PlaybookCategory;
use Jiminny\Models\Playlist;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\Track;
use Jiminny\Models\User;
use Jiminny\Repositories\CoachingFeedbackRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Rules\CrmReference;
use Jiminny\Rules\MultidimensionalArrayMaxCharRule;
use Jiminny\Services\ActivityService;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Services\PlaybackService;
use Jiminny\Services\UserService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
use Ramsey\Uuid\Uuid;
use Sentry;
use Symfony\Component\HttpFoundation;
final class ActivityController extends Controller implements CommentContextInterface
{
// Number of minutes to look back on activities. i.e. a timeout on activity duration.
private const int LOOK_BACK = 180;
public function __construct(
private ProviderRegistry $providerRegistry,
private ActivityService $activityService,
Response $response,
private UserService $userService,
private ActivitySearch\Service\ActivitySearch $activitySearch,
private NudgeFactoryInterface $nudgeFactory,
private ActivityCommentService $activityCommentService,
private LoggerInterface $logger,
private readonly CoachingFeedbackRepository $coachingFeedbackRepository,
private readonly TeamRepository $teamRepository,
) {
parent::__construct($response);
}
public static function getCommentImplementation(): string
{
return Comment::class;
}
public function delete()
{
$this->request->validate([
'*' => 'uuid:activities',
]);
$deletedIds = [];
foreach ($this->request->all() as $activityId) {
$activity = Activity::idOrUuId($activityId);
try {
if ($this->authorize('delete', $activity)) {
$activity->delete();
$deletedIds[] = $activityId;
\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);
}
} catch (AuthorizationException $authorizationException) {
// They didn't have permission.
}
}
return $this->response->withArray($deletedIds);
}
public function update(Request $request, Activity $activity)
{
$this->authorize('updateMetadata', $activity);
$request->validate([
'title' => 'string|max:250',
'category_id' => 'uuid:playbook_categories',
'language' => [
new In(
LanguageDialect::query()
->with('language')
->cursor()
->map(static function (LanguageDialect $languageDialect): string {
return $languageDialect->getLanguageLocale();
})
->all()
),
],
]);
if ($request->has('title')) {
$activity->title = $request->input('title');
}
if ($request->has('category_id')) {
$category = PlaybookCategory::uuid($request->input('category_id'));
if ($category->playbook->team_id !== $request->user()->team_id) {
return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
if ($request->has('language')) {
if (! $activity->isInProgress()) {
return $this->response->withError(
'Activity language can only be set while the meeting is in progress.',
400
);
}
$activity->setLanguageCode($request->input('language'));
}
$activity->save();
return $this->response->withOk();
}
// XXX: This should be merged with the update method.
/**
* @param Activity $activity
*
* @throws AuthorizationException
* @throws SocialAccountTokenInvalidException
*
* @return mixed
*/
public function summarize(Activity $activity): mixed
{
$this->logger->info('[Log Activity] Summarizing activity ', [
'activityId' => $activity->getUuid(),
'payload' => $this->request->all(),
]);
$this->authorize('update', $activity);
$this->logger->info('[Log Activity] Validating summary');
// Validate the payload.
$this->validateSummary($activity);
// All objects must belong to this team.
/** @var User $user */
$user = $this->request->user();
$team = $user->getTeam();
$crmService = $this->providerRegistry->get($team->crm->provider);
try {
$crmUser = $user;
if ($user->isCrmRequired() === false) {
$crmUser = $team->owner;
}
$crmService->setUser($crmUser);
} catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());
}
$rawEntities = $this->request->input('entities');
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid(
$this->request->input('layout_id')
);
// Delay execution of CRM jobs to avoid locking issues.
$jobDelay = 0;
// If we have arrived from a notification, mark it as read.
$notificationId = $this->request->input('nId');
if ($notificationId) {
$notification = $user->unreadNotifications->where('id', $notificationId)->first();
if ($notification) {
$notification->markAsRead();
}
}
$title = $this->request->input('title');
$prospects = $this->request->input('prospects');
$opportunityId = $this->request->input('opportunity_id');
$stageId = $this->request->input('stage_id');
$categoryId = $this->request->input('category_id');
$summary = $this->request->input('summary');
$crmProviderId = $this->request->input('crm_id');
$isInternal = $this->request->input('is_internal') ?? false;
$lead = null;
$category = null;
$account = null;
$contact = null;
$opportunity = null;
$stage = null;
$callStage = null;
foreach ($prospects as $prospectData) {
$objectId = $prospectData['id'];
if ($objectId === null) {
continue;
}
$objectType = $prospectData['type'];
$this->logger->info('debug', ['prospect_data' => $prospectData]);
try {
if ($objectType === null) {
$this->logger->info('no object type');
if ($crmService instanceof SupportsObjectTypeParseInterface) {
$objectType = $crmService->parseObjectType($objectId);
}
}
switch ($objectType) {
case 'lead':
$this->logger->info('Processing lead');
/** @var Lead|null $lead */
$lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();
// Lead does not exist locally, import it.
if ($lead === null) {
$this->logger->info('Lead does not exist locally');
/** @var Lead $lead */
$lead = $crmService->syncLead($objectId);
}
$this->logger->info('Lead found', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
if ($stageId === null) {
$this->logger->info('Stage ID is null');
// If it was not provided, just assume it is the current stage.
$callStage = $lead->stage;
break;
}
$this->logger->info('Looking for stage');
// Determine if they have changed the stage.
/** @var Stage $stage */
$stage = $team->crm->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_LEAD)
->firstOrFail();
$this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);
if ($lead->stage_id && $lead->stage_id !== $stage->id) {
$this->logger->info('Stage has changed');
// Storage current stage on activity.
$callStage = $lead->stage;
// The stage has changed, update in remote CRM.
dispatch(new UpdateStage($activity, $lead, $callStage, $stage));
$this->logger->info(
sprintf(
'[%s] User changing lead stage from %s to %s',
$crmService->getDisplayName(),
$callStage->getName(),
$stage->getName()
),
[
'user' => $user->getUuid(),
'lead' => $lead->getUuid(),
]
);
} else {
$this->logger->info('Stage has not changed');
// Stage remains as current.
$callStage = $stage;
}
break;
case 'account':
$this->logger->info('Processing account');
// If the object is not a lead, it should be an account.
$account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();
// Account does not exist locally, import it.
if ($account === null) {
$this->logger->info('Account does not exist locally');
$account = $crmService->syncAccount($objectId);
}
$this->logger->info('Account found', ['accountId' => $account->id]);
break;
case 'contact':
$this->logger->info('processing contact');
$contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$this->logger->info('contact does not exist locally');
$contact = $crmService->syncContact($objectId);
}
$this->logger->info('resolving account');
$account = $this->resolveAccount($team, $contact, $crmService, $prospects);
break;
}
// If they have specified an opportunity, retrieve this with stage.
if ($opportunityId) {
$this->logger->info('opportunity id is set');
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if ($opportunity === null) {
$this->logger->info('opportunity does not exist locally');
$opportunity = $crmService->syncOpportunity($opportunityId);
}
if ($stageId === null) {
$this->logger->info('stage id is null');
// If it was not provided, just assume it is the current stage.
$callStage = $opportunity->stage ?? null;
} else {
$this->logger->info('looking for stage');
/** @var ?Stage $opportunityStage */
$opportunityStage = $team->crm
->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
// There is a chance we still cannot import this opportunity.
if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {
$this->logger->info('opportunity stage has changed');
// Storage current stage on activity.
$callStage = $opportunity->stage;
dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));
$this->logger->info(
sprintf(
'[%s] User changing opportunity stage from %s to %s',
$crmService->getDisplayName(),
$callStage->name,
$opportunityStage->name
),
[
'userId' => $user->id_string,
'opportunityId' => $opportunity->id_string,
]
);
} else {
$this->logger->info('opportunity stage has not changed');
// Stage remains as current.
$callStage = $opportunityStage;
}
}
}
if ($crmProviderId) {
// Cast $crmProviderId to string otherwise it won't use database index for some records
$linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();
// Check if this activity has already been assigned to a different activity.
if ($linkedActivity && $linkedActivity->id !== $activity->id) {
throw new InvalidArgumentException(
'Sorry, the linked task has already been logged under a different call. '
. 'Please choose another linked task.'
);
}
}
} catch (InvalidArgumentException $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($exception->getMessage());
} catch (Exception $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorInternalError(
'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'
);
}
}
if ($categoryId) {
$category = PlaybookCategory::uuid($categoryId);
if ($category->playbook->team_id !== $team->id) {
throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
$this->logger->info('Prospect data', [
'lead_id' => $lead?->getId(),
'account_id' => $account?->getId(),
'contact_id' => $contact?->getId(),
'opportunity_id' => $opportunity?->getId(),
'stage_id' => $stage?->getId(),
]);
if ($title) {
$activity->title = $title;
}
if ($summary) {
$activity->summary = $summary;
}
if ($crmProviderId) {
$activity->crm_provider_id = $crmProviderId;
}
if ($callStage) {
$this->logger->info('Setting stage id', ['stageId' => $callStage->id]);
$activity->stage_id = $callStage->id;
}
if ($lead) {
$this->logger->info('Setting lead id', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
// If we are changed from an account > lead, unset the account data.
$this->logger->info('Unsetting account id, opportunity id, contact id, value');
$activity->account_id = null;
$activity->opportunity_id = null;
$activity->contact_id = null;
$activity->value = null;
}
if ($account) {
$this->logger->info('Setting account id', ['accountId' => $account->id]);
$activity->account_id = $account->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('unsetting lead id');
$activity->lead_id = null;
// Unset the contact if switching different accounts. Will be set up below if still applicable.
if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {
$this->logger->info('Unsetting contact id');
$activity->contact_id = null;
}
}
if ($opportunity) {
$this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);
$this->logger->info('unsetting lead id');
$activity->opportunity_id = $opportunity->id;
$activity->value = $opportunity->value;
// If we are changed from an lead > account, unset the lead data.
$activity->lead_id = null;
}
if ($contact) {
$this->logger->info('setting contact id', ['contactId' => $contact->id]);
$activity->contact_id = $contact->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('Unsetting lead id');
$activity->lead_id = null;
}
$activity->is_internal = $isInternal;
$activity->save();
$activity->refresh();
$this->logger->notice('Activity saved', [
'activity_id' => $activity->getId(),
'lead_id' => $activity->lead_id,
'account_id' => $activity->account_id,
'contact_id' => $activity->contact_id,
'opportunity_id' => $activity->opportunity_id,
'stage_id' => $activity->stage_id,
'crm_provider_id' => $activity->getCrmProviderId(),
]);
// Store entities as field data on the activity.
$updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);
if ($activity->isLoggable()) {
// Follow-up Task or Event data.
$followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);
$this->logger->info('CRM LOG manual log triggered', [
'activityId' => $activity->getUuid(),
'followupData' => $followupData,
'userId' => $user->getUuid(),
]);
// Store data in the CRM.
// ++add check for crm_required
$job = new SaveActivity($activity, $followupData);
if ($updatedData) {
$job->delay(Carbon::now()->addMinutes($jobDelay));
}
dispatch($job);
// Manually dispatch log for Opportunity or Prospect added
if ($activity->hasOpportunity() || $activity->hasProspect()) {
event(new ActivityProspectAdded(
activity: $activity,
eventSource: 'manually-log-crm-data'
));
}
}
return $this->response->withOk();
}
/**
* Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.
*
* @param ServiceInterface $service
* @param Activity $activity
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array
{
$updatedData = [];
$existingData = $activity->data()->get();
// We need to delete any existing data to overwrite with latest values.
$activity->data()->delete();
$layoutEntities = $layout->entities()
->with('field', 'parent')
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->get();
/** @var LayoutEntity $entity */
foreach ($layoutEntities as $entity) {
// If the user has provided a value for this entity
if (array_key_exists($entity->id_string, $entities)) {
$value = $entities[$entity->id_string];
// Convert raw data into values that the CRM can consume.
if ($value) {
$value = $service->normalizeValue($entity->field->type, $value);
}
// Check the field is part of the activity-summary section.
if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {
// This is the internal database ID, not the external CRM ID.
$objectId = null;
switch ($entity->field->object_type) {
case Field::OBJECT_ACCOUNT:
$objectId = $activity->account_id;
break;
case Field::OBJECT_CONTACT:
$objectId = $activity->contact_id;
break;
case Field::OBJECT_OPPORTUNITY:
$objectId = $activity->opportunity_id;
break;
case Field::OBJECT_LEAD:
$objectId = $activity->lead_id;
break;
case Field::OBJECT_TASK:
case Field::OBJECT_EVENT:
$objectId = $activity->id;
break;
}
if ($objectId) {
/** @var FieldData $data */
$data = $activity->data()->create([
'crm_layout_entity_id' => $entity->id,
'crm_field_id' => $entity->crm_field_id,
'object_type' => $entity->field->object_type,
'object_id' => $objectId,
'value' => $value,
]);
// Never send read-only field data to the CRM.
if ($entity->read_only === false && $entity->is_visible) {
$existingValue = $existingData
->where('crm_layout_entity_id', $entity->id)
->where('crm_field_id', $entity->crm_field_id)
->where('object_type', $entity->field->object_type)
->where('object_id', $objectId)
->first();
// If the field was actually changed, we need to reflect this in the CRM too.
if ($existingValue === null || $existingValue->value !== $value) {
$updatedData[] = $data->id;
}
}
}
}
}
}
return $updatedData;
}
/**
* Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.
*
* @param ServiceInterface $crmService
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array
{
$fieldData = [];
foreach ($entities as $entityId => $value) {
// Only bother with fields that have a value.
if ($value) {
// Extract the entity from the UUID. Check the field is valid and part of the follow-up section.
$entity = $layout->entities()
->uuid($entityId, false)
->whereHas('parent', function ($query) {
$query->where('label', 'follow-up');
})
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->first();
if ($entity) {
// Convert raw data into values that the CRM can consume.
$value = $crmService->normalizeValue($entity->field->type, $value);
// Add the field and value to the payload.
$fieldData += [
$entity->field->crm_provider_id => $value,
];
}
}
}
return $fieldData;
}
/**
* @param Activity $activity
*/
private function validateSummary(Activity $activity): void
{
$team = $activity->user->team;
$crmProvider = $team->crm->provider;
$attributes = [];
$rules = [
'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,
'title' => 'string|max:250',
'prospects' => 'required|array',
'opportunity_id' => new CrmReference($crmProvider),
'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',
'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator
'summary' => 'max:50000',
'nId' => 'exists:notifications,id',
'crm_id' => new CrmReference($crmProvider),
'entities' => 'array',
'is_internal' => 'boolean',
];
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));
// Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.
$entities = $layout->entities()
->where('read_only', 0)
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->whereHas('parent', function ($query) use ($activity) {
if ($activity->isLoggable() === false) {
$query->where('label', '<>', 'follow-up');
}
});
$isInternal = $this->request->input('is_internal', false);
foreach ($entities->get() as $entity) {
$rules += $this->buildFieldValidator($entity, $isInternal);
$attributes += $this->buildFieldMessage($entity);
}
$this->request->validate($rules, [], $attributes);
}
private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array
{
return [
'entities.' . $entity->id_string => $entity->getValidator($isInternal),
];
}
/**
* @param LayoutEntity $entity
*
* @return array
*/
private function buildFieldMessage(LayoutEntity $entity): array
{
$label = $entity->label;
if ($label === null) {
$label = $entity->field->label;
}
return [
'entities.' . $entity->id_string => $label,
];
}
public function search(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->debugLog(
$user,
'User extracted from request',
['user' => $user->getId(), 'tz' => $user->getTimezone()]
);
$searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());
$this->debugLog(
$user,
'ActivitySearch criteria built',
['searchCriteria' => $searchCriteria]
);
$filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);
$this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);
$this->validateSearch($request, $filterSet);
$this->debugLog($user, 'Request validated');
$searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);
/** @var Collection<Activity> $activities */
$activities = $searchResponse['results'];
$this->debugLog($user, 'Activities ES response extracted');
$hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(
$user->getTeamId(),
TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),
);
if ($hideInternalMeetingsSetting?->getValue() === '1') {
$activities = $activities->filter(function (Activity $activity) {
if ($activity->is_internal && empty($activity->actual_start_time)) {
return false;
}
return true;
});
}
$this->debugLog($user, 'Internal meetings (?!) filtered');
$this->response->getManager()
->parseIncludes([
'category',
'organizer.group',
'prospect',
'stage',
'opportunity',
'stats',
'scorecards',
'masterTrack',
'activeParticipants',
'notification',
])
->setSerializer(new JsonSerializer());
$transformerExcludes = $this->request->input('exclude');
if ($transformerExcludes) {
$this->response->getManager()->parseExcludes($transformerExcludes);
}
$this->debugLog($user, 'Response Manager (?!) applied');
$transformer = new ActivityTransformer();
$transformer->setConsumer($user);
$this->debugLog($user, 'Activity Transformer added');
$resource = new \League\Fractal\Resource\Collection($activities, $transformer);
$page = $searchCriteria->getPageNumber();
$this->debugLog($user, 'Search criteria page number called', ['page' => $page]);
$histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');
$this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);
return $this->response->withArray([
'pagination' => [
'total' => $searchResponse['totalHits'],
'current' => $page,
'prev' => max($page - 1, 1),
'next' => $page + 1,
],
'results' => $this->response->getManager()->createData($resource)->toArray(),
'histogram' => $histogram,
]);
}
private function debugLog(User $user, string $logMessage, ?array $context = []): void
{
// Debug for Learning People Only
if ($user->getTeamId() !== 260) {
return;
}
Log::notice(
sprintf('[activity-search-controller] %s', $logMessage),
$context
);
}
/** @throws ValidationException */
private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void
{
$rules = [
'exclude' => 'array',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
];
if ($prefix !== null && mb_strpos($prefix, '.') !== false) {
$rules[rtrim($prefix, '.')] = sprintf(
'required|array|max:%d',
$filterSet->count()
);
}
$validationRules = $filterSet->getValidationRules($prefix)
->merge($rules)
->all();
$request->validate($validationRules);
}
public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$search = $this->updateOrCreateActivitySearch($request);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function updateActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('update', $search);
$this->updateOrCreateActivitySearch($request, $search);
return $this->response->withOk();
}
private function storeNamedSearchFilters(
Collection $request,
Search $search,
FilterDefinitionCollection $filterSet,
?string $prefix = null,
): self {
$arrayTypeProperties = $filterSet
->getPropertyTypes([
FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,
])
->all();
$supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);
foreach ($supportedRequestProperties as $requestPropertyName) {
if (! array_has($request, $requestPropertyName)) {
continue;
}
/** @var string|string[] $propertyValue */
$propertyValue = array_get($request, $requestPropertyName);
$propertyName = $prefix === null
? $requestPropertyName
: mb_substr($requestPropertyName, mb_strlen($prefix));
$isArrayType = array_has($arrayTypeProperties, $propertyName);
if (! $isArrayType) {
/** @var string $requestPropertyValue */
$search->filters()->updateOrCreate(
[
'filter' => $propertyName,
],
[
'value' => $propertyValue,
]
);
continue;
}
/** @var string[] $requestPropertyValue */
/** @var SearchFilter[]|Collection $existingFilterValues */
$existingFilterValuesKeyed = $search->filters()
->where('filter', $propertyName)
->get()
->keyBy('id');
// Iterate over values provided as request parameters
foreach ($propertyValue as $value) {
/** @var SearchFilter|null $valueFilter */
$valueFilter = $search->filters()
->where(
[
'filter' => $propertyName,
'value' => $value,
]
)
->first();
if ($valueFilter !== null) {
// Remove filter value pair from list to be deleted
$existingFilterValuesKeyed->forget($valueFilter->id);
} else {
// Add new filter/value pair
$search->filters()->updateOrCreate([
'filter' => $propertyName,
'value' => $value,
]);
}
}
// Delete filter value pairs for this filter that no longer exist in request parameters
foreach ($existingFilterValuesKeyed as $existingFilter) {
$existingFilter->delete();
}
}
/** @var Collection<int, SearchFilter> $filtersKeyed */
$filtersKeyed = $search->filters()->get()->keyBy('filter');
// wipe removed filters from this search
foreach ($filtersKeyed as $filterName => $filter) {
if (array_has($request, $prefix . $filterName)) {
continue;
}
// Remove all filter values for this filter
$search->filters()->where('filter', $filterName)->delete();
}
return $this;
}
/**
* @throws AuthorizationException
*/
public function fetchActivitySearch(
Search $search,
Request $request,
SearchTransformer $searchTransformer,
): JsonResponse {
$this->authorize('view', $search);
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withCollection(
$user->searches()->get(),
$searchTransformer
->withConsumer($user)
);
}
/**
* Deletes a saved search
*
* @param Request $request
* @param Search $search
*
* @throws Exception
*
* @return JsonResponse
*/
public function deleteActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('delete', $search);
// Orphan any AutomatedReports that use this search
$search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);
// Delete filters and the search itself
$search->filters()->delete();
$search->delete();
return $this->response->withOk();
}
public function live(Request $request, ElasticActivityRepository $repository): JsonResponse
{
$user = $this->getUserFromRequest($request);
$this->request->validate([
'sort_direction' => 'in:asc,desc',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
]);
$activities = $repository->getLiveCoachingEligibleActivities(
user: $user,
lookBackMinutes: self::LOOK_BACK,
limit: (int) $this->request->input('limit', 25),
page: (int) $this->request->input('page', 1),
sortBy: ['actual_start_time', 'scheduled_start_time'],
sortDirection: (string) $this->request->input('sort_direction', 'asc'),
);
$this->response
->getManager()
->parseIncludes(['organizer.group', 'prospect'])
->setSerializer(new JsonSerializer());
return $this->response->withCollection($activities, new ActivityTransformer());
}
/**
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function show(Activity $activity, ActivityService $activityService): JsonResponse
{
$this->authorize('show', $activity);
$user = $activity->getUser();
$team = $user->getTeam();
// Sync the opportunity with the latest data if possible.
if ($activity->opportunity_id) {
try {
$crmService = $this->providerRegistry->get($team->crm->provider);
if (! $user->isCrmRequired()) {
$crmService->setUser($team->getOwner());
} else {
$crmService->setUser($user);
}
$crmService->syncOpportunity($activity->opportunity->crm_provider_id);
} catch (Exception $exception) {
// Move on.
}
}
$activityData = $activityService->getActivityData($this->request->user(), $activity);
return response()->json($activityData);
}
public function createRecording(Activity $activity)
{
$this->authorize('record', $activity);
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Tell Twilio to start recording this activity.
if ($activity->recording_state === Activity::RECORDING_OFF) {
$job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withCreated();
}
return $this->response->errorGone('Activity is already recording.');
}
public function updateRecording(Request $request, Activity $activity)
{
$this->authorize('record', $activity);
$request->validate([
'preference' => 'boolean',
'state' => [
'string',
Rule::in([
Activity::RECORDING_IN_PROGRESS,
Activity::RECORDING_PAUSED,
]),
],
]);
if ($request->has('state')) {
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Toggle the recording state between paused and resumed.
if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {
$job = (new ToggleRecording($activity, $request->input('state')))
->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Recording is not toggleable.');
}
if ($request->has('preference')) {
$activity->update([
'recording_preference' => $request->input('preference') ? 1 : 0,
]);
return $this->response->withOk();
}
return $this->response->errorWrongArgs('Something went wrong');
}
public function stopRecording(Activity $activity)
{
$this->authorize('stopRecord', $activity);
// Tell Twilio to stop recording this activity.
if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {
$job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Activity is not recording.');
}
/**
* Add activity to this user's favorites playlist
*
* @throws AuthorizationException
*/
public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse
{
$this->authorize('favorite', $activity);
$user = $this->getUserFromRequest($this->request);
$favorite = $activity->wasFavoritedBy($user);
$name = $activity->activity_title ?? '';
// It needs to check at least one record.
if (! $favorite) {
$favoritePlaylist = $user->favoritePlaylist();
$playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(
$activity,
$user,
$favoritePlaylist
);
if ($playlistActivity !== null) {
$playlistActivity->update(
// Just update, don't sort.
['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],
);
} else {
$playlistActivity = $activity->playlistActivities()->create([
'playlist_id' => $favoritePlaylist->getId(),
'user_id' => $user->getId(),
'start_time' => 0,
'name' => mb_strimwidth($name, 0, 100),
]);
// Sort it on top.
$playlistActivity->update(
[
'sort' => $playlistActivityRepository->calculateNewSortOrder(
null,
$playlistActivity,
),
],
);
}
$playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);
return new JsonResponse([], JsonResponse::HTTP_CREATED);
}
return new JsonResponse(
[
'error' => [
'code' => AbstractResponse::CODE_CONFLICT,
'http_code' => JsonResponse::HTTP_CONFLICT,
'message' => 'Resource Already Exists',
],
],
JsonResponse::HTTP_CONFLICT,
);
}
/**
* Remove activity from this user's favorites playlist
*
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function unfavorite(Activity $activity)
{
$user = $t...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
32866
|
1255
|
41
|
2026-05-13T09:42:15.708801+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665335708_m2.jpg...
|
PhpStorm
|
faVsco.js – ActivityController.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use Carbon\Carbon;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\In;
use Illuminate\Validation\ValidationException;
use InvalidArgumentException;
use Jiminny\Component\ActivityAnalytics;
use Jiminny\Component\ActivitySearch;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Queue\Constants;
use Jiminny\Contracts\ES\Events\UpdateSingleEntity;
use Jiminny\Contracts\ES\UpdateTargetEnum;
use Jiminny\Contracts\Nudge\NudgeFactoryInterface;
use Jiminny\Contracts\Playlist\PlaylistTrackFactoryInterface;
use Jiminny\Contracts\Repositories\PlaylistActivityRepository;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Enums\TeamSetting;
use Jiminny\Events\Activities\AiAutomation\ActivityProspectAdded;
use Jiminny\Events\Activities\Coaching\Coached;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Controllers\CommentContextInterface;
use Jiminny\Http\Responses\Api\AbstractResponse;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\ActivityCommentTransformer;
use Jiminny\Http\Transformers\ActivityTopicTriggerTransformer;
use Jiminny\Http\Transformers\ActivityTransformer;
use Jiminny\Http\Transformers\AvailabilityNotificationTransformer;
use Jiminny\Http\Transformers\CoachingFeedbackTransformer;
use Jiminny\Http\Transformers\CoachingSectionsTransformer;
use Jiminny\Http\Transformers\SearchTransformer;
use Jiminny\Http\Transformers\StatsTransformer;
use Jiminny\Jobs\Crm\SaveActivity;
use Jiminny\Jobs\Crm\UpdateStage;
use Jiminny\Jobs\Telephony\StartRecording;
use Jiminny\Jobs\Telephony\StopRecording;
use Jiminny\Jobs\Telephony\ToggleRecording;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\CoachingFeedback;
use Jiminny\Models\CoachingSection;
use Jiminny\Models\CoachingSectionCriterion;
use Jiminny\Models\CoachingSectionFeedback;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\LanguageDialect;
use Jiminny\Models\Lead;
use Jiminny\Models\Nudge;
use Jiminny\Models\PlaybookCategory;
use Jiminny\Models\Playlist;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\Track;
use Jiminny\Models\User;
use Jiminny\Repositories\CoachingFeedbackRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Rules\CrmReference;
use Jiminny\Rules\MultidimensionalArrayMaxCharRule;
use Jiminny\Services\ActivityService;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Services\PlaybackService;
use Jiminny\Services\UserService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
use Ramsey\Uuid\Uuid;
use Sentry;
use Symfony\Component\HttpFoundation;
final class ActivityController extends Controller implements CommentContextInterface
{
// Number of minutes to look back on activities. i.e. a timeout on activity duration.
private const int LOOK_BACK = 180;
public function __construct(
private ProviderRegistry $providerRegistry,
private ActivityService $activityService,
Response $response,
private UserService $userService,
private ActivitySearch\Service\ActivitySearch $activitySearch,
private NudgeFactoryInterface $nudgeFactory,
private ActivityCommentService $activityCommentService,
private LoggerInterface $logger,
private readonly CoachingFeedbackRepository $coachingFeedbackRepository,
private readonly TeamRepository $teamRepository,
) {
parent::__construct($response);
}
public static function getCommentImplementation(): string
{
return Comment::class;
}
public function delete()
{
$this->request->validate([
'*' => 'uuid:activities',
]);
$deletedIds = [];
foreach ($this->request->all() as $activityId) {
$activity = Activity::idOrUuId($activityId);
try {
if ($this->authorize('delete', $activity)) {
$activity->delete();
$deletedIds[] = $activityId;
\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);
}
} catch (AuthorizationException $authorizationException) {
// They didn't have permission.
}
}
return $this->response->withArray($deletedIds);
}
public function update(Request $request, Activity $activity)
{
$this->authorize('updateMetadata', $activity);
$request->validate([
'title' => 'string|max:250',
'category_id' => 'uuid:playbook_categories',
'language' => [
new In(
LanguageDialect::query()
->with('language')
->cursor()
->map(static function (LanguageDialect $languageDialect): string {
return $languageDialect->getLanguageLocale();
})
->all()
),
],
]);
if ($request->has('title')) {
$activity->title = $request->input('title');
}
if ($request->has('category_id')) {
$category = PlaybookCategory::uuid($request->input('category_id'));
if ($category->playbook->team_id !== $request->user()->team_id) {
return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
if ($request->has('language')) {
if (! $activity->isInProgress()) {
return $this->response->withError(
'Activity language can only be set while the meeting is in progress.',
400
);
}
$activity->setLanguageCode($request->input('language'));
}
$activity->save();
return $this->response->withOk();
}
// XXX: This should be merged with the update method.
/**
* @param Activity $activity
*
* @throws AuthorizationException
* @throws SocialAccountTokenInvalidException
*
* @return mixed
*/
public function summarize(Activity $activity): mixed
{
$this->logger->info('[Log Activity] Summarizing activity ', [
'activityId' => $activity->getUuid(),
'payload' => $this->request->all(),
]);
$this->authorize('update', $activity);
$this->logger->info('[Log Activity] Validating summary');
// Validate the payload.
$this->validateSummary($activity);
// All objects must belong to this team.
/** @var User $user */
$user = $this->request->user();
$team = $user->getTeam();
$crmService = $this->providerRegistry->get($team->crm->provider);
try {
$crmUser = $user;
if ($user->isCrmRequired() === false) {
$crmUser = $team->owner;
}
$crmService->setUser($crmUser);
} catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());
}
$rawEntities = $this->request->input('entities');
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid(
$this->request->input('layout_id')
);
// Delay execution of CRM jobs to avoid locking issues.
$jobDelay = 0;
// If we have arrived from a notification, mark it as read.
$notificationId = $this->request->input('nId');
if ($notificationId) {
$notification = $user->unreadNotifications->where('id', $notificationId)->first();
if ($notification) {
$notification->markAsRead();
}
}
$title = $this->request->input('title');
$prospects = $this->request->input('prospects');
$opportunityId = $this->request->input('opportunity_id');
$stageId = $this->request->input('stage_id');
$categoryId = $this->request->input('category_id');
$summary = $this->request->input('summary');
$crmProviderId = $this->request->input('crm_id');
$isInternal = $this->request->input('is_internal') ?? false;
$lead = null;
$category = null;
$account = null;
$contact = null;
$opportunity = null;
$stage = null;
$callStage = null;
foreach ($prospects as $prospectData) {
$objectId = $prospectData['id'];
if ($objectId === null) {
continue;
}
$objectType = $prospectData['type'];
$this->logger->info('debug', ['prospect_data' => $prospectData]);
try {
if ($objectType === null) {
$this->logger->info('no object type');
if ($crmService instanceof SupportsObjectTypeParseInterface) {
$objectType = $crmService->parseObjectType($objectId);
}
}
switch ($objectType) {
case 'lead':
$this->logger->info('Processing lead');
/** @var Lead|null $lead */
$lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();
// Lead does not exist locally, import it.
if ($lead === null) {
$this->logger->info('Lead does not exist locally');
/** @var Lead $lead */
$lead = $crmService->syncLead($objectId);
}
$this->logger->info('Lead found', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
if ($stageId === null) {
$this->logger->info('Stage ID is null');
// If it was not provided, just assume it is the current stage.
$callStage = $lead->stage;
break;
}
$this->logger->info('Looking for stage');
// Determine if they have changed the stage.
/** @var Stage $stage */
$stage = $team->crm->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_LEAD)
->firstOrFail();
$this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);
if ($lead->stage_id && $lead->stage_id !== $stage->id) {
$this->logger->info('Stage has changed');
// Storage current stage on activity.
$callStage = $lead->stage;
// The stage has changed, update in remote CRM.
dispatch(new UpdateStage($activity, $lead, $callStage, $stage));
$this->logger->info(
sprintf(
'[%s] User changing lead stage from %s to %s',
$crmService->getDisplayName(),
$callStage->getName(),
$stage->getName()
),
[
'user' => $user->getUuid(),
'lead' => $lead->getUuid(),
]
);
} else {
$this->logger->info('Stage has not changed');
// Stage remains as current.
$callStage = $stage;
}
break;
case 'account':
$this->logger->info('Processing account');
// If the object is not a lead, it should be an account.
$account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();
// Account does not exist locally, import it.
if ($account === null) {
$this->logger->info('Account does not exist locally');
$account = $crmService->syncAccount($objectId);
}
$this->logger->info('Account found', ['accountId' => $account->id]);
break;
case 'contact':
$this->logger->info('processing contact');
$contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$this->logger->info('contact does not exist locally');
$contact = $crmService->syncContact($objectId);
}
$this->logger->info('resolving account');
$account = $this->resolveAccount($team, $contact, $crmService, $prospects);
break;
}
// If they have specified an opportunity, retrieve this with stage.
if ($opportunityId) {
$this->logger->info('opportunity id is set');
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if ($opportunity === null) {
$this->logger->info('opportunity does not exist locally');
$opportunity = $crmService->syncOpportunity($opportunityId);
}
if ($stageId === null) {
$this->logger->info('stage id is null');
// If it was not provided, just assume it is the current stage.
$callStage = $opportunity->stage ?? null;
} else {
$this->logger->info('looking for stage');
/** @var ?Stage $opportunityStage */
$opportunityStage = $team->crm
->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
// There is a chance we still cannot import this opportunity.
if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {
$this->logger->info('opportunity stage has changed');
// Storage current stage on activity.
$callStage = $opportunity->stage;
dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));
$this->logger->info(
sprintf(
'[%s] User changing opportunity stage from %s to %s',
$crmService->getDisplayName(),
$callStage->name,
$opportunityStage->name
),
[
'userId' => $user->id_string,
'opportunityId' => $opportunity->id_string,
]
);
} else {
$this->logger->info('opportunity stage has not changed');
// Stage remains as current.
$callStage = $opportunityStage;
}
}
}
if ($crmProviderId) {
// Cast $crmProviderId to string otherwise it won't use database index for some records
$linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();
// Check if this activity has already been assigned to a different activity.
if ($linkedActivity && $linkedActivity->id !== $activity->id) {
throw new InvalidArgumentException(
'Sorry, the linked task has already been logged under a different call. '
. 'Please choose another linked task.'
);
}
}
} catch (InvalidArgumentException $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($exception->getMessage());
} catch (Exception $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorInternalError(
'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'
);
}
}
if ($categoryId) {
$category = PlaybookCategory::uuid($categoryId);
if ($category->playbook->team_id !== $team->id) {
throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
$this->logger->info('Prospect data', [
'lead_id' => $lead?->getId(),
'account_id' => $account?->getId(),
'contact_id' => $contact?->getId(),
'opportunity_id' => $opportunity?->getId(),
'stage_id' => $stage?->getId(),
]);
if ($title) {
$activity->title = $title;
}
if ($summary) {
$activity->summary = $summary;
}
if ($crmProviderId) {
$activity->crm_provider_id = $crmProviderId;
}
if ($callStage) {
$this->logger->info('Setting stage id', ['stageId' => $callStage->id]);
$activity->stage_id = $callStage->id;
}
if ($lead) {
$this->logger->info('Setting lead id', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
// If we are changed from an account > lead, unset the account data.
$this->logger->info('Unsetting account id, opportunity id, contact id, value');
$activity->account_id = null;
$activity->opportunity_id = null;
$activity->contact_id = null;
$activity->value = null;
}
if ($account) {
$this->logger->info('Setting account id', ['accountId' => $account->id]);
$activity->account_id = $account->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('unsetting lead id');
$activity->lead_id = null;
// Unset the contact if switching different accounts. Will be set up below if still applicable.
if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {
$this->logger->info('Unsetting contact id');
$activity->contact_id = null;
}
}
if ($opportunity) {
$this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);
$this->logger->info('unsetting lead id');
$activity->opportunity_id = $opportunity->id;
$activity->value = $opportunity->value;
// If we are changed from an lead > account, unset the lead data.
$activity->lead_id = null;
}
if ($contact) {
$this->logger->info('setting contact id', ['contactId' => $contact->id]);
$activity->contact_id = $contact->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('Unsetting lead id');
$activity->lead_id = null;
}
$activity->is_internal = $isInternal;
$activity->save();
$activity->refresh();
$this->logger->notice('Activity saved', [
'activity_id' => $activity->getId(),
'lead_id' => $activity->lead_id,
'account_id' => $activity->account_id,
'contact_id' => $activity->contact_id,
'opportunity_id' => $activity->opportunity_id,
'stage_id' => $activity->stage_id,
'crm_provider_id' => $activity->getCrmProviderId(),
]);
// Store entities as field data on the activity.
$updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);
if ($activity->isLoggable()) {
// Follow-up Task or Event data.
$followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);
$this->logger->info('CRM LOG manual log triggered', [
'activityId' => $activity->getUuid(),
'followupData' => $followupData,
'userId' => $user->getUuid(),
]);
// Store data in the CRM.
// ++add check for crm_required
$job = new SaveActivity($activity, $followupData);
if ($updatedData) {
$job->delay(Carbon::now()->addMinutes($jobDelay));
}
dispatch($job);
// Manually dispatch log for Opportunity or Prospect added
if ($activity->hasOpportunity() || $activity->hasProspect()) {
event(new ActivityProspectAdded(
activity: $activity,
eventSource: 'manually-log-crm-data'
));
}
}
return $this->response->withOk();
}
/**
* Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.
*
* @param ServiceInterface $service
* @param Activity $activity
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array
{
$updatedData = [];
$existingData = $activity->data()->get();
// We need to delete any existing data to overwrite with latest values.
$activity->data()->delete();
$layoutEntities = $layout->entities()
->with('field', 'parent')
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->get();
/** @var LayoutEntity $entity */
foreach ($layoutEntities as $entity) {
// If the user has provided a value for this entity
if (array_key_exists($entity->id_string, $entities)) {
$value = $entities[$entity->id_string];
// Convert raw data into values that the CRM can consume.
if ($value) {
$value = $service->normalizeValue($entity->field->type, $value);
}
// Check the field is part of the activity-summary section.
if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {
// This is the internal database ID, not the external CRM ID.
$objectId = null;
switch ($entity->field->object_type) {
case Field::OBJECT_ACCOUNT:
$objectId = $activity->account_id;
break;
case Field::OBJECT_CONTACT:
$objectId = $activity->contact_id;
break;
case Field::OBJECT_OPPORTUNITY:
$objectId = $activity->opportunity_id;
break;
case Field::OBJECT_LEAD:
$objectId = $activity->lead_id;
break;
case Field::OBJECT_TASK:
case Field::OBJECT_EVENT:
$objectId = $activity->id;
break;
}
if ($objectId) {
/** @var FieldData $data */
$data = $activity->data()->create([
'crm_layout_entity_id' => $entity->id,
'crm_field_id' => $entity->crm_field_id,
'object_type' => $entity->field->object_type,
'object_id' => $objectId,
'value' => $value,
]);
// Never send read-only field data to the CRM.
if ($entity->read_only === false && $entity->is_visible) {
$existingValue = $existingData
->where('crm_layout_entity_id', $entity->id)
->where('crm_field_id', $entity->crm_field_id)
->where('object_type', $entity->field->object_type)
->where('object_id', $objectId)
->first();
// If the field was actually changed, we need to reflect this in the CRM too.
if ($existingValue === null || $existingValue->value !== $value) {
$updatedData[] = $data->id;
}
}
}
}
}
}
return $updatedData;
}
/**
* Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.
*
* @param ServiceInterface $crmService
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array
{
$fieldData = [];
foreach ($entities as $entityId => $value) {
// Only bother with fields that have a value.
if ($value) {
// Extract the entity from the UUID. Check the field is valid and part of the follow-up section.
$entity = $layout->entities()
->uuid($entityId, false)
->whereHas('parent', function ($query) {
$query->where('label', 'follow-up');
})
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->first();
if ($entity) {
// Convert raw data into values that the CRM can consume.
$value = $crmService->normalizeValue($entity->field->type, $value);
// Add the field and value to the payload.
$fieldData += [
$entity->field->crm_provider_id => $value,
];
}
}
}
return $fieldData;
}
/**
* @param Activity $activity
*/
private function validateSummary(Activity $activity): void
{
$team = $activity->user->team;
$crmProvider = $team->crm->provider;
$attributes = [];
$rules = [
'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,
'title' => 'string|max:250',
'prospects' => 'required|array',
'opportunity_id' => new CrmReference($crmProvider),
'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',
'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator
'summary' => 'max:50000',
'nId' => 'exists:notifications,id',
'crm_id' => new CrmReference($crmProvider),
'entities' => 'array',
'is_internal' => 'boolean',
];
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));
// Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.
$entities = $layout->entities()
->where('read_only', 0)
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->whereHas('parent', function ($query) use ($activity) {
if ($activity->isLoggable() === false) {
$query->where('label', '<>', 'follow-up');
}
});
$isInternal = $this->request->input('is_internal', false);
foreach ($entities->get() as $entity) {
$rules += $this->buildFieldValidator($entity, $isInternal);
$attributes += $this->buildFieldMessage($entity);
}
$this->request->validate($rules, [], $attributes);
}
private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array
{
return [
'entities.' . $entity->id_string => $entity->getValidator($isInternal),
];
}
/**
* @param LayoutEntity $entity
*
* @return array
*/
private function buildFieldMessage(LayoutEntity $entity): array
{
$label = $entity->label;
if ($label === null) {
$label = $entity->field->label;
}
return [
'entities.' . $entity->id_string => $label,
];
}
public function search(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->debugLog(
$user,
'User extracted from request',
['user' => $user->getId(), 'tz' => $user->getTimezone()]
);
$searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());
$this->debugLog(
$user,
'ActivitySearch criteria built',
['searchCriteria' => $searchCriteria]
);
$filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);
$this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);
$this->validateSearch($request, $filterSet);
$this->debugLog($user, 'Request validated');
$searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);
/** @var Collection<Activity> $activities */
$activities = $searchResponse['results'];
$this->debugLog($user, 'Activities ES response extracted');
$hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(
$user->getTeamId(),
TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),
);
if ($hideInternalMeetingsSetting?->getValue() === '1') {
$activities = $activities->filter(function (Activity $activity) {
if ($activity->is_internal && empty($activity->actual_start_time)) {
return false;
}
return true;
});
}
$this->debugLog($user, 'Internal meetings (?!) filtered');
$this->response->getManager()
->parseIncludes([
'category',
'organizer.group',
'prospect',
'stage',
'opportunity',
'stats',
'scorecards',
'masterTrack',
'activeParticipants',
'notification',
])
->setSerializer(new JsonSerializer());
$transformerExcludes = $this->request->input('exclude');
if ($transformerExcludes) {
$this->response->getManager()->parseExcludes($transformerExcludes);
}
$this->debugLog($user, 'Response Manager (?!) applied');
$transformer = new ActivityTransformer();
$transformer->setConsumer($user);
$this->debugLog($user, 'Activity Transformer added');
$resource = new \League\Fractal\Resource\Collection($activities, $transformer);
$page = $searchCriteria->getPageNumber();
$this->debugLog($user, 'Search criteria page number called', ['page' => $page]);
$histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');
$this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);
return $this->response->withArray([
'pagination' => [
'total' => $searchResponse['totalHits'],
'current' => $page,
'prev' => max($page - 1, 1),
'next' => $page + 1,
],
'results' => $this->response->getManager()->createData($resource)->toArray(),
'histogram' => $histogram,
]);
}
private function debugLog(User $user, string $logMessage, ?array $context = []): void
{
// Debug for Learning People Only
if ($user->getTeamId() !== 260) {
return;
}
Log::notice(
sprintf('[activity-search-controller] %s', $logMessage),
$context
);
}
/** @throws ValidationException */
private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void
{
$rules = [
'exclude' => 'array',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
];
if ($prefix !== null && mb_strpos($prefix, '.') !== false) {
$rules[rtrim($prefix, '.')] = sprintf(
'required|array|max:%d',
$filterSet->count()
);
}
$validationRules = $filterSet->getValidationRules($prefix)
->merge($rules)
->all();
$request->validate($validationRules);
}
public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$search = $this->updateOrCreateActivitySearch($request);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function updateActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('update', $search);
$this->updateOrCreateActivitySearch($request, $search);
return $this->response->withOk();
}
private function storeNamedSearchFilters(
Collection $request,
Search $search,
FilterDefinitionCollection $filterSet,
?string $prefix = null,
): self {
$arrayTypeProperties = $filterSet
->getPropertyTypes([
FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,
])
->all();
$supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);
foreach ($supportedRequestProperties as $requestPropertyName) {
if (! array_has($request, $requestPropertyName)) {
continue;
}
/** @var string|string[] $propertyValue */
$propertyValue = array_get($request, $requestPropertyName);
$propertyName = $prefix === null
? $requestPropertyName
: mb_substr($requestPropertyName, mb_strlen($prefix));
$isArrayType = array_has($arrayTypeProperties, $propertyName);
if (! $isArrayType) {
/** @var string $requestPropertyValue */
$search->filters()->updateOrCreate(
[
'filter' => $propertyName,
],
[
'value' => $propertyValue,
]
);
continue;
}
/** @var string[] $requestPropertyValue */
/** @var SearchFilter[]|Collection $existingFilterValues */
$existingFilterValuesKeyed = $search->filters()
->where('filter', $propertyName)
->get()
->keyBy('id');
// Iterate over values provided as request parameters
foreach ($propertyValue as $value) {
/** @var SearchFilter|null $valueFilter */
$valueFilter = $search->filters()
->where(
[
'filter' => $propertyName,
'value' => $value,
]
)
->first();
if ($valueFilter !== null) {
// Remove filter value pair from list to be deleted
$existingFilterValuesKeyed->forget($valueFilter->id);
} else {
// Add new filter/value pair
$search->filters()->updateOrCreate([
'filter' => $propertyName,
'value' => $value,
]);
}
}
// Delete filter value pairs for this filter that no longer exist in request parameters
foreach ($existingFilterValuesKeyed as $existingFilter) {
$existingFilter->delete();
}
}
/** @var Collection<int, SearchFilter> $filtersKeyed */
$filtersKeyed = $search->filters()->get()->keyBy('filter');
// wipe removed filters from this search
foreach ($filtersKeyed as $filterName => $filter) {
if (array_has($request, $prefix . $filterName)) {
continue;
}
// Remove all filter values for this filter
$search->filters()->where('filter', $filterName)->delete();
}
return $this;
}
/**
* @throws AuthorizationException
*/
public function fetchActivitySearch(
Search $search,
Request $request,
SearchTransformer $searchTransformer,
): JsonResponse {
$this->authorize('view', $search);
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withCollection(
$user->searches()->get(),
$searchTransformer
->withConsumer($user)
);
}
/**
* Deletes a saved search
*
* @param Request $request
* @param Search $search
*
* @throws Exception
*
* @return JsonResponse
*/
public function deleteActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('delete', $search);
// Orphan any AutomatedReports that use this search
$search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);
// Delete filters and the search itself
$search->filters()->delete();
$search->delete();
return $this->response->withOk();
}
public function live(Request $request, ElasticActivityRepository $repository): JsonResponse
{
$user = $this->getUserFromRequest($request);
$this->request->validate([
'sort_direction' => 'in:asc,desc',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
]);
$activities = $repository->getLiveCoachingEligibleActivities(
user: $user,
lookBackMinutes: self::LOOK_BACK,
limit: (int) $this->request->input('limit', 25),
page: (int) $this->request->input('page', 1),
sortBy: ['actual_start_time', 'scheduled_start_time'],
sortDirection: (string) $this->request->input('sort_direction', 'asc'),
);
$this->response
->getManager()
->parseIncludes(['organizer.group', 'prospect'])
->setSerializer(new JsonSerializer());
return $this->response->withCollection($activities, new ActivityTransformer());
}
/**
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function show(Activity $activity, ActivityService $activityService): JsonResponse
{
$this->authorize('show', $activity);
$user = $activity->getUser();
$team = $user->getTeam();
// Sync the opportunity with the latest data if possible.
if ($activity->opportunity_id) {
try {
$crmService = $this->providerRegistry->get($team->crm->provider);
if (! $user->isCrmRequired()) {
$crmService->setUser($team->getOwner());
} else {
$crmService->setUser($user);
}
$crmService->syncOpportunity($activity->opportunity->crm_provider_id);
} catch (Exception $exception) {
// Move on.
}
}
$activityData = $activityService->getActivityData($this->request->user(), $activity);
return response()->json($activityData);
}
public function createRecording(Activity $activity)
{
$this->authorize('record', $activity);
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Tell Twilio to start recording this activity.
if ($activity->recording_state === Activity::RECORDING_OFF) {
$job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withCreated();
}
return $this->response->errorGone('Activity is already recording.');
}
public function updateRecording(Request $request, Activity $activity)
{
$this->authorize('record', $activity);
$request->validate([
'preference' => 'boolean',
'state' => [
'string',
Rule::in([
Activity::RECORDING_IN_PROGRESS,
Activity::RECORDING_PAUSED,
]),
],
]);
if ($request->has('state')) {
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Toggle the recording state between paused and resumed.
if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {
$job = (new ToggleRecording($activity, $request->input('state')))
->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Recording is not toggleable.');
}
if ($request->has('preference')) {
$activity->update([
'recording_preference' => $request->input('preference') ? 1 : 0,
]);
return $this->response->withOk();
}
return $this->response->errorWrongArgs('Something went wrong');
}
public function stopRecording(Activity $activity)
{
$this->authorize('stopRecord', $activity);
// Tell Twilio to stop recording this activity.
if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {
$job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Activity is not recording.');
}
/**
* Add activity to this user's favorites playlist
*
* @throws AuthorizationException
*/
public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse
{
$this->authorize('favorite', $activity);
$user = $this->getUserFromRequest($this->request);
$favorite = $activity->wasFavoritedBy($user);
$name = $activity->activity_title ?? '';
// It needs to check at least one record.
if (! $favorite) {
$favoritePlaylist = $user->favoritePlaylist();
$playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(
$activity,
$user,
$favoritePlaylist
);
if ($playlistActivity !== null) {
$playlistActivity->update(
// Just update, don't sort.
['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],
);
} else {
$playlistActivity = $activity->playlistActivities()->create([
'playlist_id' => $favoritePlaylist->getId(),
'user_id' => $user->getId(),
'start_time' => 0,
'name' => mb_strimwidth($name, 0, 100),
]);
// Sort it on top.
$playlistActivity->update(
[
'sort' => $playlistActivityRepository->calculateNewSortOrder(
null,
$playlistActivity,
),
],
);
}
$playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);
return new JsonResponse([], JsonResponse::HTTP_CREATED);
}
return new JsonResponse(
[
'error' => [
'code' => AbstractResponse::CODE_CONFLICT,
'http_code' => JsonResponse::HTTP_CONFLICT,
'message' => 'Resource Already Exists',
],
],
JsonResponse::HTTP_CONFLICT,
);
}
/**
* Remove activity from this user's favorites playlist
*
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function unfavorite(Activity $activity)
{
$user = $t...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.034242023,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Analyzing…","depth":4,"bounds":{"left":0.37200797,"top":0.07581804,"width":0.019946808,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.39361703,"top":0.074221864,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.40093085,"top":0.074221864,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Http\\Controllers\\API;\n\nuse Carbon\\Carbon;\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Exception;\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Validation\\Rule;\nuse Illuminate\\Validation\\Rules\\In;\nuse Illuminate\\Validation\\ValidationException;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ActivityAnalytics;\nuse Jiminny\\Component\\ActivitySearch;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Contracts\\ES\\Events\\UpdateSingleEntity;\nuse Jiminny\\Contracts\\ES\\UpdateTargetEnum;\nuse Jiminny\\Contracts\\Nudge\\NudgeFactoryInterface;\nuse Jiminny\\Contracts\\Playlist\\PlaylistTrackFactoryInterface;\nuse Jiminny\\Contracts\\Repositories\\PlaylistActivityRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Enums\\TeamSetting;\nuse Jiminny\\Events\\Activities\\AiAutomation\\ActivityProspectAdded;\nuse Jiminny\\Events\\Activities\\Coaching\\Coached;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Controllers\\CommentContextInterface;\nuse Jiminny\\Http\\Responses\\Api\\AbstractResponse;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\ActivityCommentTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTopicTriggerTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTransformer;\nuse Jiminny\\Http\\Transformers\\AvailabilityNotificationTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingFeedbackTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingSectionsTransformer;\nuse Jiminny\\Http\\Transformers\\SearchTransformer;\nuse Jiminny\\Http\\Transformers\\StatsTransformer;\nuse Jiminny\\Jobs\\Crm\\SaveActivity;\nuse Jiminny\\Jobs\\Crm\\UpdateStage;\nuse Jiminny\\Jobs\\Telephony\\StartRecording;\nuse Jiminny\\Jobs\\Telephony\\StopRecording;\nuse Jiminny\\Jobs\\Telephony\\ToggleRecording;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\CoachingFeedback;\nuse Jiminny\\Models\\CoachingSection;\nuse Jiminny\\Models\\CoachingSectionCriterion;\nuse Jiminny\\Models\\CoachingSectionFeedback;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\LanguageDialect;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Nudge;\nuse Jiminny\\Models\\PlaybookCategory;\nuse Jiminny\\Models\\Playlist;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\Track;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\CoachingFeedbackRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Rules\\MultidimensionalArrayMaxCharRule;\nuse Jiminny\\Services\\ActivityService;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Services\\PlaybackService;\nuse Jiminny\\Services\\UserService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\nuse Ramsey\\Uuid\\Uuid;\nuse Sentry;\nuse Symfony\\Component\\HttpFoundation;\n\nfinal class ActivityController extends Controller implements CommentContextInterface\n{\n // Number of minutes to look back on activities. i.e. a timeout on activity duration.\n private const int LOOK_BACK = 180;\n\n public function __construct(\n private ProviderRegistry $providerRegistry,\n private ActivityService $activityService,\n Response $response,\n private UserService $userService,\n private ActivitySearch\\Service\\ActivitySearch $activitySearch,\n private NudgeFactoryInterface $nudgeFactory,\n private ActivityCommentService $activityCommentService,\n private LoggerInterface $logger,\n private readonly CoachingFeedbackRepository $coachingFeedbackRepository,\n private readonly TeamRepository $teamRepository,\n ) {\n parent::__construct($response);\n }\n\n public static function getCommentImplementation(): string\n {\n return Comment::class;\n }\n\n public function delete()\n {\n $this->request->validate([\n '*' => 'uuid:activities',\n ]);\n\n $deletedIds = [];\n foreach ($this->request->all() as $activityId) {\n $activity = Activity::idOrUuId($activityId);\n\n try {\n if ($this->authorize('delete', $activity)) {\n $activity->delete();\n $deletedIds[] = $activityId;\n\n \\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n }\n } catch (AuthorizationException $authorizationException) {\n // They didn't have permission.\n }\n }\n\n return $this->response->withArray($deletedIds);\n }\n\n public function update(Request $request, Activity $activity)\n {\n $this->authorize('updateMetadata', $activity);\n\n $request->validate([\n 'title' => 'string|max:250',\n 'category_id' => 'uuid:playbook_categories',\n 'language' => [\n new In(\n LanguageDialect::query()\n ->with('language')\n ->cursor()\n ->map(static function (LanguageDialect $languageDialect): string {\n return $languageDialect->getLanguageLocale();\n })\n ->all()\n ),\n ],\n ]);\n\n if ($request->has('title')) {\n $activity->title = $request->input('title');\n }\n\n if ($request->has('category_id')) {\n $category = PlaybookCategory::uuid($request->input('category_id'));\n\n if ($category->playbook->team_id !== $request->user()->team_id) {\n return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n if ($request->has('language')) {\n if (! $activity->isInProgress()) {\n return $this->response->withError(\n 'Activity language can only be set while the meeting is in progress.',\n 400\n );\n }\n\n $activity->setLanguageCode($request->input('language'));\n }\n\n $activity->save();\n\n return $this->response->withOk();\n }\n\n // XXX: This should be merged with the update method.\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws SocialAccountTokenInvalidException\n *\n * @return mixed\n */\n public function summarize(Activity $activity): mixed\n {\n $this->logger->info('[Log Activity] Summarizing activity ', [\n 'activityId' => $activity->getUuid(),\n 'payload' => $this->request->all(),\n ]);\n $this->authorize('update', $activity);\n\n $this->logger->info('[Log Activity] Validating summary');\n // Validate the payload.\n $this->validateSummary($activity);\n\n // All objects must belong to this team.\n /** @var User $user */\n $user = $this->request->user();\n $team = $user->getTeam();\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n try {\n $crmUser = $user;\n if ($user->isCrmRequired() === false) {\n $crmUser = $team->owner;\n }\n $crmService->setUser($crmUser);\n } catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());\n }\n\n $rawEntities = $this->request->input('entities');\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid(\n $this->request->input('layout_id')\n );\n\n // Delay execution of CRM jobs to avoid locking issues.\n $jobDelay = 0;\n\n // If we have arrived from a notification, mark it as read.\n $notificationId = $this->request->input('nId');\n if ($notificationId) {\n $notification = $user->unreadNotifications->where('id', $notificationId)->first();\n\n if ($notification) {\n $notification->markAsRead();\n }\n }\n\n $title = $this->request->input('title');\n $prospects = $this->request->input('prospects');\n $opportunityId = $this->request->input('opportunity_id');\n $stageId = $this->request->input('stage_id');\n $categoryId = $this->request->input('category_id');\n $summary = $this->request->input('summary');\n $crmProviderId = $this->request->input('crm_id');\n $isInternal = $this->request->input('is_internal') ?? false;\n\n $lead = null;\n $category = null;\n $account = null;\n $contact = null;\n $opportunity = null;\n $stage = null;\n $callStage = null;\n\n foreach ($prospects as $prospectData) {\n $objectId = $prospectData['id'];\n\n if ($objectId === null) {\n continue;\n }\n\n $objectType = $prospectData['type'];\n $this->logger->info('debug', ['prospect_data' => $prospectData]);\n\n try {\n if ($objectType === null) {\n $this->logger->info('no object type');\n if ($crmService instanceof SupportsObjectTypeParseInterface) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n }\n\n switch ($objectType) {\n case 'lead':\n $this->logger->info('Processing lead');\n /** @var Lead|null $lead */\n $lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();\n\n // Lead does not exist locally, import it.\n if ($lead === null) {\n $this->logger->info('Lead does not exist locally');\n /** @var Lead $lead */\n $lead = $crmService->syncLead($objectId);\n }\n\n $this->logger->info('Lead found', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n if ($stageId === null) {\n $this->logger->info('Stage ID is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $lead->stage;\n\n break;\n }\n\n $this->logger->info('Looking for stage');\n // Determine if they have changed the stage.\n /** @var Stage $stage */\n $stage = $team->crm->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_LEAD)\n ->firstOrFail();\n\n $this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);\n if ($lead->stage_id && $lead->stage_id !== $stage->id) {\n $this->logger->info('Stage has changed');\n // Storage current stage on activity.\n $callStage = $lead->stage;\n\n // The stage has changed, update in remote CRM.\n dispatch(new UpdateStage($activity, $lead, $callStage, $stage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing lead stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->getName(),\n $stage->getName()\n ),\n [\n 'user' => $user->getUuid(),\n 'lead' => $lead->getUuid(),\n ]\n );\n } else {\n $this->logger->info('Stage has not changed');\n // Stage remains as current.\n $callStage = $stage;\n }\n\n break;\n\n case 'account':\n $this->logger->info('Processing account');\n // If the object is not a lead, it should be an account.\n $account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();\n\n // Account does not exist locally, import it.\n if ($account === null) {\n $this->logger->info('Account does not exist locally');\n $account = $crmService->syncAccount($objectId);\n }\n\n $this->logger->info('Account found', ['accountId' => $account->id]);\n\n break;\n case 'contact':\n $this->logger->info('processing contact');\n $contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $this->logger->info('contact does not exist locally');\n $contact = $crmService->syncContact($objectId);\n }\n\n $this->logger->info('resolving account');\n $account = $this->resolveAccount($team, $contact, $crmService, $prospects);\n\n break;\n }\n\n // If they have specified an opportunity, retrieve this with stage.\n if ($opportunityId) {\n $this->logger->info('opportunity id is set');\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if ($opportunity === null) {\n $this->logger->info('opportunity does not exist locally');\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n if ($stageId === null) {\n $this->logger->info('stage id is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $opportunity->stage ?? null;\n } else {\n $this->logger->info('looking for stage');\n /** @var ?Stage $opportunityStage */\n $opportunityStage = $team->crm\n ->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n // There is a chance we still cannot import this opportunity.\n if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {\n $this->logger->info('opportunity stage has changed');\n // Storage current stage on activity.\n $callStage = $opportunity->stage;\n\n dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing opportunity stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->name,\n $opportunityStage->name\n ),\n [\n 'userId' => $user->id_string,\n 'opportunityId' => $opportunity->id_string,\n ]\n );\n } else {\n $this->logger->info('opportunity stage has not changed');\n // Stage remains as current.\n $callStage = $opportunityStage;\n }\n }\n }\n\n if ($crmProviderId) {\n // Cast $crmProviderId to string otherwise it won't use database index for some records\n $linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();\n\n // Check if this activity has already been assigned to a different activity.\n if ($linkedActivity && $linkedActivity->id !== $activity->id) {\n throw new InvalidArgumentException(\n 'Sorry, the linked task has already been logged under a different call. '\n . 'Please choose another linked task.'\n );\n }\n }\n } catch (InvalidArgumentException $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($exception->getMessage());\n } catch (Exception $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorInternalError(\n 'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'\n );\n }\n }\n\n if ($categoryId) {\n $category = PlaybookCategory::uuid($categoryId);\n\n if ($category->playbook->team_id !== $team->id) {\n throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n $this->logger->info('Prospect data', [\n 'lead_id' => $lead?->getId(),\n 'account_id' => $account?->getId(),\n 'contact_id' => $contact?->getId(),\n 'opportunity_id' => $opportunity?->getId(),\n 'stage_id' => $stage?->getId(),\n ]);\n\n if ($title) {\n $activity->title = $title;\n }\n\n if ($summary) {\n $activity->summary = $summary;\n }\n\n if ($crmProviderId) {\n $activity->crm_provider_id = $crmProviderId;\n }\n\n if ($callStage) {\n $this->logger->info('Setting stage id', ['stageId' => $callStage->id]);\n $activity->stage_id = $callStage->id;\n }\n\n if ($lead) {\n $this->logger->info('Setting lead id', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n // If we are changed from an account > lead, unset the account data.\n $this->logger->info('Unsetting account id, opportunity id, contact id, value');\n $activity->account_id = null;\n $activity->opportunity_id = null;\n $activity->contact_id = null;\n $activity->value = null;\n }\n\n if ($account) {\n $this->logger->info('Setting account id', ['accountId' => $account->id]);\n $activity->account_id = $account->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('unsetting lead id');\n $activity->lead_id = null;\n\n // Unset the contact if switching different accounts. Will be set up below if still applicable.\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {\n $this->logger->info('Unsetting contact id');\n $activity->contact_id = null;\n }\n }\n\n if ($opportunity) {\n $this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);\n $this->logger->info('unsetting lead id');\n $activity->opportunity_id = $opportunity->id;\n $activity->value = $opportunity->value;\n\n // If we are changed from an lead > account, unset the lead data.\n $activity->lead_id = null;\n }\n\n if ($contact) {\n $this->logger->info('setting contact id', ['contactId' => $contact->id]);\n $activity->contact_id = $contact->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('Unsetting lead id');\n $activity->lead_id = null;\n }\n\n $activity->is_internal = $isInternal;\n $activity->save();\n $activity->refresh();\n\n $this->logger->notice('Activity saved', [\n 'activity_id' => $activity->getId(),\n 'lead_id' => $activity->lead_id,\n 'account_id' => $activity->account_id,\n 'contact_id' => $activity->contact_id,\n 'opportunity_id' => $activity->opportunity_id,\n 'stage_id' => $activity->stage_id,\n 'crm_provider_id' => $activity->getCrmProviderId(),\n ]);\n\n // Store entities as field data on the activity.\n $updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);\n\n if ($activity->isLoggable()) {\n // Follow-up Task or Event data.\n $followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);\n\n $this->logger->info('CRM LOG manual log triggered', [\n 'activityId' => $activity->getUuid(),\n 'followupData' => $followupData,\n 'userId' => $user->getUuid(),\n ]);\n\n // Store data in the CRM.\n // ++add check for crm_required\n $job = new SaveActivity($activity, $followupData);\n\n if ($updatedData) {\n $job->delay(Carbon::now()->addMinutes($jobDelay));\n }\n\n dispatch($job);\n\n // Manually dispatch log for Opportunity or Prospect added\n if ($activity->hasOpportunity() || $activity->hasProspect()) {\n event(new ActivityProspectAdded(\n activity: $activity,\n eventSource: 'manually-log-crm-data'\n ));\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.\n *\n * @param ServiceInterface $service\n * @param Activity $activity\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array\n {\n $updatedData = [];\n $existingData = $activity->data()->get();\n\n // We need to delete any existing data to overwrite with latest values.\n $activity->data()->delete();\n\n $layoutEntities = $layout->entities()\n ->with('field', 'parent')\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->get();\n\n /** @var LayoutEntity $entity */\n foreach ($layoutEntities as $entity) {\n // If the user has provided a value for this entity\n if (array_key_exists($entity->id_string, $entities)) {\n $value = $entities[$entity->id_string];\n\n // Convert raw data into values that the CRM can consume.\n if ($value) {\n $value = $service->normalizeValue($entity->field->type, $value);\n }\n\n // Check the field is part of the activity-summary section.\n if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {\n // This is the internal database ID, not the external CRM ID.\n $objectId = null;\n\n switch ($entity->field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $objectId = $activity->account_id;\n\n break;\n\n case Field::OBJECT_CONTACT:\n $objectId = $activity->contact_id;\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n $objectId = $activity->opportunity_id;\n\n break;\n\n case Field::OBJECT_LEAD:\n $objectId = $activity->lead_id;\n\n break;\n\n case Field::OBJECT_TASK:\n case Field::OBJECT_EVENT:\n $objectId = $activity->id;\n\n break;\n }\n\n if ($objectId) {\n /** @var FieldData $data */\n $data = $activity->data()->create([\n 'crm_layout_entity_id' => $entity->id,\n 'crm_field_id' => $entity->crm_field_id,\n 'object_type' => $entity->field->object_type,\n 'object_id' => $objectId,\n 'value' => $value,\n ]);\n\n // Never send read-only field data to the CRM.\n if ($entity->read_only === false && $entity->is_visible) {\n $existingValue = $existingData\n ->where('crm_layout_entity_id', $entity->id)\n ->where('crm_field_id', $entity->crm_field_id)\n ->where('object_type', $entity->field->object_type)\n ->where('object_id', $objectId)\n ->first();\n\n // If the field was actually changed, we need to reflect this in the CRM too.\n if ($existingValue === null || $existingValue->value !== $value) {\n $updatedData[] = $data->id;\n }\n }\n }\n }\n }\n }\n\n return $updatedData;\n }\n\n /**\n * Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.\n *\n * @param ServiceInterface $crmService\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array\n {\n $fieldData = [];\n foreach ($entities as $entityId => $value) {\n // Only bother with fields that have a value.\n if ($value) {\n // Extract the entity from the UUID. Check the field is valid and part of the follow-up section.\n $entity = $layout->entities()\n ->uuid($entityId, false)\n ->whereHas('parent', function ($query) {\n $query->where('label', 'follow-up');\n })\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->first();\n\n if ($entity) {\n // Convert raw data into values that the CRM can consume.\n $value = $crmService->normalizeValue($entity->field->type, $value);\n\n // Add the field and value to the payload.\n $fieldData += [\n $entity->field->crm_provider_id => $value,\n ];\n }\n }\n }\n\n return $fieldData;\n }\n\n /**\n * @param Activity $activity\n */\n private function validateSummary(Activity $activity): void\n {\n $team = $activity->user->team;\n $crmProvider = $team->crm->provider;\n $attributes = [];\n\n $rules = [\n 'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,\n 'title' => 'string|max:250',\n 'prospects' => 'required|array',\n 'opportunity_id' => new CrmReference($crmProvider),\n 'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',\n 'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator\n 'summary' => 'max:50000',\n 'nId' => 'exists:notifications,id',\n 'crm_id' => new CrmReference($crmProvider),\n 'entities' => 'array',\n 'is_internal' => 'boolean',\n ];\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));\n\n // Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.\n $entities = $layout->entities()\n ->where('read_only', 0)\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->whereHas('parent', function ($query) use ($activity) {\n if ($activity->isLoggable() === false) {\n $query->where('label', '<>', 'follow-up');\n }\n });\n\n $isInternal = $this->request->input('is_internal', false);\n\n foreach ($entities->get() as $entity) {\n $rules += $this->buildFieldValidator($entity, $isInternal);\n $attributes += $this->buildFieldMessage($entity);\n }\n\n $this->request->validate($rules, [], $attributes);\n }\n\n private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array\n {\n return [\n 'entities.' . $entity->id_string => $entity->getValidator($isInternal),\n ];\n }\n\n /**\n * @param LayoutEntity $entity\n *\n * @return array\n */\n private function buildFieldMessage(LayoutEntity $entity): array\n {\n $label = $entity->label;\n if ($label === null) {\n $label = $entity->field->label;\n }\n\n return [\n 'entities.' . $entity->id_string => $label,\n ];\n }\n\n public function search(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->debugLog(\n $user,\n 'User extracted from request',\n ['user' => $user->getId(), 'tz' => $user->getTimezone()]\n );\n\n $searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());\n\n $this->debugLog(\n $user,\n 'ActivitySearch criteria built',\n ['searchCriteria' => $searchCriteria]\n );\n\n $filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);\n\n $this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);\n\n $this->validateSearch($request, $filterSet);\n\n $this->debugLog($user, 'Request validated');\n\n $searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);\n\n /** @var Collection<Activity> $activities */\n $activities = $searchResponse['results'];\n\n $this->debugLog($user, 'Activities ES response extracted');\n\n $hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(\n $user->getTeamId(),\n TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),\n );\n\n if ($hideInternalMeetingsSetting?->getValue() === '1') {\n $activities = $activities->filter(function (Activity $activity) {\n if ($activity->is_internal && empty($activity->actual_start_time)) {\n return false;\n }\n\n return true;\n });\n }\n\n $this->debugLog($user, 'Internal meetings (?!) filtered');\n\n $this->response->getManager()\n ->parseIncludes([\n 'category',\n 'organizer.group',\n 'prospect',\n 'stage',\n 'opportunity',\n 'stats',\n 'scorecards',\n 'masterTrack',\n 'activeParticipants',\n 'notification',\n ])\n ->setSerializer(new JsonSerializer());\n\n $transformerExcludes = $this->request->input('exclude');\n if ($transformerExcludes) {\n $this->response->getManager()->parseExcludes($transformerExcludes);\n }\n\n $this->debugLog($user, 'Response Manager (?!) applied');\n\n $transformer = new ActivityTransformer();\n $transformer->setConsumer($user);\n\n $this->debugLog($user, 'Activity Transformer added');\n\n $resource = new \\League\\Fractal\\Resource\\Collection($activities, $transformer);\n $page = $searchCriteria->getPageNumber();\n\n $this->debugLog($user, 'Search criteria page number called', ['page' => $page]);\n\n $histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');\n\n $this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);\n\n return $this->response->withArray([\n 'pagination' => [\n 'total' => $searchResponse['totalHits'],\n 'current' => $page,\n 'prev' => max($page - 1, 1),\n 'next' => $page + 1,\n ],\n 'results' => $this->response->getManager()->createData($resource)->toArray(),\n 'histogram' => $histogram,\n ]);\n }\n\n private function debugLog(User $user, string $logMessage, ?array $context = []): void\n {\n // Debug for Learning People Only\n if ($user->getTeamId() !== 260) {\n return;\n }\n\n Log::notice(\n sprintf('[activity-search-controller] %s', $logMessage),\n $context\n );\n }\n\n /** @throws ValidationException */\n private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void\n {\n $rules = [\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ];\n\n if ($prefix !== null && mb_strpos($prefix, '.') !== false) {\n $rules[rtrim($prefix, '.')] = sprintf(\n 'required|array|max:%d',\n $filterSet->count()\n );\n }\n\n $validationRules = $filterSet->getValidationRules($prefix)\n ->merge($rules)\n ->all();\n\n $request->validate($validationRules);\n }\n\n public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $search = $this->updateOrCreateActivitySearch($request);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function updateActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('update', $search);\n\n $this->updateOrCreateActivitySearch($request, $search);\n\n return $this->response->withOk();\n }\n\n private function storeNamedSearchFilters(\n Collection $request,\n Search $search,\n FilterDefinitionCollection $filterSet,\n ?string $prefix = null,\n ): self {\n $arrayTypeProperties = $filterSet\n ->getPropertyTypes([\n FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,\n ])\n ->all();\n\n $supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);\n\n foreach ($supportedRequestProperties as $requestPropertyName) {\n if (! array_has($request, $requestPropertyName)) {\n continue;\n }\n\n /** @var string|string[] $propertyValue */\n $propertyValue = array_get($request, $requestPropertyName);\n $propertyName = $prefix === null\n ? $requestPropertyName\n : mb_substr($requestPropertyName, mb_strlen($prefix));\n\n $isArrayType = array_has($arrayTypeProperties, $propertyName);\n\n if (! $isArrayType) {\n /** @var string $requestPropertyValue */\n\n $search->filters()->updateOrCreate(\n [\n 'filter' => $propertyName,\n ],\n [\n 'value' => $propertyValue,\n ]\n );\n\n continue;\n }\n\n /** @var string[] $requestPropertyValue */\n\n /** @var SearchFilter[]|Collection $existingFilterValues */\n $existingFilterValuesKeyed = $search->filters()\n ->where('filter', $propertyName)\n ->get()\n ->keyBy('id');\n\n // Iterate over values provided as request parameters\n foreach ($propertyValue as $value) {\n /** @var SearchFilter|null $valueFilter */\n $valueFilter = $search->filters()\n ->where(\n [\n 'filter' => $propertyName,\n 'value' => $value,\n ]\n )\n ->first();\n\n if ($valueFilter !== null) {\n // Remove filter value pair from list to be deleted\n $existingFilterValuesKeyed->forget($valueFilter->id);\n } else {\n // Add new filter/value pair\n $search->filters()->updateOrCreate([\n 'filter' => $propertyName,\n 'value' => $value,\n ]);\n }\n }\n\n // Delete filter value pairs for this filter that no longer exist in request parameters\n foreach ($existingFilterValuesKeyed as $existingFilter) {\n $existingFilter->delete();\n }\n }\n\n /** @var Collection<int, SearchFilter> $filtersKeyed */\n $filtersKeyed = $search->filters()->get()->keyBy('filter');\n\n // wipe removed filters from this search\n foreach ($filtersKeyed as $filterName => $filter) {\n if (array_has($request, $prefix . $filterName)) {\n continue;\n }\n\n // Remove all filter values for this filter\n $search->filters()->where('filter', $filterName)->delete();\n }\n\n return $this;\n }\n\n /**\n * @throws AuthorizationException\n */\n public function fetchActivitySearch(\n Search $search,\n Request $request,\n SearchTransformer $searchTransformer,\n ): JsonResponse {\n $this->authorize('view', $search);\n\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection(\n $user->searches()->get(),\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n /**\n * Deletes a saved search\n *\n * @param Request $request\n * @param Search $search\n *\n * @throws Exception\n *\n * @return JsonResponse\n */\n public function deleteActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('delete', $search);\n\n // Orphan any AutomatedReports that use this search\n $search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);\n\n // Delete filters and the search itself\n $search->filters()->delete();\n $search->delete();\n\n return $this->response->withOk();\n }\n\n public function live(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n $user = $this->getUserFromRequest($request);\n\n $this->request->validate([\n 'sort_direction' => 'in:asc,desc',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ]);\n\n $activities = $repository->getLiveCoachingEligibleActivities(\n user: $user,\n lookBackMinutes: self::LOOK_BACK,\n limit: (int) $this->request->input('limit', 25),\n page: (int) $this->request->input('page', 1),\n sortBy: ['actual_start_time', 'scheduled_start_time'],\n sortDirection: (string) $this->request->input('sort_direction', 'asc'),\n );\n\n $this->response\n ->getManager()\n ->parseIncludes(['organizer.group', 'prospect'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($activities, new ActivityTransformer());\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function show(Activity $activity, ActivityService $activityService): JsonResponse\n {\n $this->authorize('show', $activity);\n\n $user = $activity->getUser();\n $team = $user->getTeam();\n\n // Sync the opportunity with the latest data if possible.\n if ($activity->opportunity_id) {\n try {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n if (! $user->isCrmRequired()) {\n $crmService->setUser($team->getOwner());\n } else {\n $crmService->setUser($user);\n }\n\n $crmService->syncOpportunity($activity->opportunity->crm_provider_id);\n } catch (Exception $exception) {\n // Move on.\n }\n }\n\n $activityData = $activityService->getActivityData($this->request->user(), $activity);\n\n return response()->json($activityData);\n }\n\n public function createRecording(Activity $activity)\n {\n $this->authorize('record', $activity);\n\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Tell Twilio to start recording this activity.\n if ($activity->recording_state === Activity::RECORDING_OFF) {\n $job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withCreated();\n }\n\n return $this->response->errorGone('Activity is already recording.');\n }\n\n public function updateRecording(Request $request, Activity $activity)\n {\n $this->authorize('record', $activity);\n\n $request->validate([\n 'preference' => 'boolean',\n 'state' => [\n 'string',\n Rule::in([\n Activity::RECORDING_IN_PROGRESS,\n Activity::RECORDING_PAUSED,\n ]),\n ],\n ]);\n\n if ($request->has('state')) {\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Toggle the recording state between paused and resumed.\n if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {\n $job = (new ToggleRecording($activity, $request->input('state')))\n ->onQueue(Constants::QUEUE_CONFERENCES);\n\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Recording is not toggleable.');\n }\n\n if ($request->has('preference')) {\n $activity->update([\n 'recording_preference' => $request->input('preference') ? 1 : 0,\n ]);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorWrongArgs('Something went wrong');\n }\n\n public function stopRecording(Activity $activity)\n {\n $this->authorize('stopRecord', $activity);\n\n // Tell Twilio to stop recording this activity.\n if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {\n $job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Activity is not recording.');\n }\n\n /**\n * Add activity to this user's favorites playlist\n *\n * @throws AuthorizationException\n */\n public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse\n {\n $this->authorize('favorite', $activity);\n\n $user = $this->getUserFromRequest($this->request);\n $favorite = $activity->wasFavoritedBy($user);\n $name = $activity->activity_title ?? '';\n\n // It needs to check at least one record.\n if (! $favorite) {\n $favoritePlaylist = $user->favoritePlaylist();\n\n $playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(\n $activity,\n $user,\n $favoritePlaylist\n );\n\n if ($playlistActivity !== null) {\n $playlistActivity->update(\n // Just update, don't sort.\n ['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],\n );\n } else {\n $playlistActivity = $activity->playlistActivities()->create([\n 'playlist_id' => $favoritePlaylist->getId(),\n 'user_id' => $user->getId(),\n 'start_time' => 0,\n 'name' => mb_strimwidth($name, 0, 100),\n ]);\n // Sort it on top.\n $playlistActivity->update(\n [\n 'sort' => $playlistActivityRepository->calculateNewSortOrder(\n null,\n $playlistActivity,\n ),\n ],\n );\n }\n\n $playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);\n\n return new JsonResponse([], JsonResponse::HTTP_CREATED);\n }\n\n return new JsonResponse(\n [\n 'error' => [\n 'code' => AbstractResponse::CODE_CONFLICT,\n 'http_code' => JsonResponse::HTTP_CONFLICT,\n 'message' => 'Resource Already Exists',\n ],\n ],\n JsonResponse::HTTP_CONFLICT,\n );\n }\n\n /**\n * Remove activity from this user's favorites playlist\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unfavorite(Activity $activity)\n {\n $user = $this->request->user();\n\n $favorites = $activity->favoritedBy($user);\n\n if ($favorites && $favorites->isEmpty()) {\n return $this->response->errorNotFound('Favorite not found.');\n }\n\n $this->authorize('unfavorite', [$activity, $favorites]);\n\n // When you unfavorite an activity,\n // it should remove all the activities in it, including snippets.\n $isDeleted = $favorites->each(function ($favorite) {\n $favorite->forceDelete();\n });\n\n if ($isDeleted) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not remove favorite.');\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function notify(Activity $activity)\n {\n $this->authorize('notify', $activity);\n\n $user = $this->request->user();\n\n $existingNotification = $activity->availabilityNotifications()\n ->where('user_id', $user->id)\n ->exists();\n\n if ($existingNotification) {\n return $this->response->errorWrongArgs('Notification is already configured.');\n }\n\n $notification = Activity\\AvailabilityNotification::create([\n 'user_id' => $user->id,\n 'activity_id' => $activity->id,\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($notification, new AvailabilityNotificationTransformer());\n }\n\n /**\n * @param Activity $activity\n * @param Activity\\AvailabilityNotification $notification\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unnotify(Activity $activity, Activity\\AvailabilityNotification $notification)\n {\n $this->authorize('unnotify', [$activity, $notification]);\n\n if ($notification->sent_at || $notification->delete()) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not delete notification.');\n }\n\n public function play(Request $request, Activity $activity)\n {\n $this->authorize('stream', $activity);\n\n $request->validate([\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $activity->plays()->create([\n 'user_id' => $user->getId(),\n 'start_time' => $request->input('start_time'),\n ]);\n\n return $this->response->withCreated();\n }\n\n /**\n * @param Activity $activity\n *\n * @return mixed\n */\n public function comment(Activity $activity)\n {\n return $this->newComment($activity);\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @return mixed\n */\n public function replyComment(Activity $activity, Comment $comment)\n {\n return $this->newComment($activity, $comment);\n }\n\n /**\n * @param Activity $activity\n * @param Comment|null $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n protected function newComment(Activity $activity, ?Comment $comment = null)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n 'type' => 'integer|between:0,3',\n 'visibility' => sprintf('nullable|integer|between:1,%d', count(Comment::getVisibilityLevels())),\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n $threadStartId = null;\n if ($comment) {\n $threadStartId = $comment->thread_start_id ?: $comment->id;\n }\n\n try {\n $newComment = Comment::create([\n 'parent_comment_id' => $comment->id ?? null,\n 'thread_start_id' => $threadStartId,\n 'activity_id' => $activity->id,\n 'user_id' => $this->request->user()->id,\n 'comment' => trim($this->request->input('comment')),\n 'start_time' => $this->request->input('start_time', 0),\n 'end_time' => $this->request->input('end_time', 0),\n 'type' => $this->request->input('type', Comment::TYPE_NEUTRAL),\n 'visibility' => $this->request->input('visibility', Comment::VISIBILITY_PUBLIC),\n ]);\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($newComment, new ActivityCommentTransformer());\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not create comment.' . $exception->getMessage());\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function updateComment(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n try {\n $comment->update([\n 'comment' => trim($this->request->input('comment')),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment.');\n }\n }\n\n public function updateCommentVisibility(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'visibility' => sprintf('integer|between:1,%d', count(Comment::getVisibilityLevels())),\n ]);\n\n $visibility = $this->request->input('visibility');\n\n if ($comment->parent !== null) {\n return $this->response->errorWrongArgs('Comment visibility can only be updated on top level comments.');\n }\n\n try {\n $this->activityCommentService->updateCommentVisibility($comment, $visibility);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment\\'s visibility.');\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function deleteComment(Activity $activity, Comment $comment)\n {\n $this->authorize('deleteComment', [$activity, $comment]);\n\n // Delete comment and any children.\n $comment->delete();\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function fetchComments()\n {\n $user = $this->request->user();\n $this->request->validate([\n 'forUserId' => 'uuid:users,team_id,' . $user->team_id,\n 'types' => 'array',\n 'types.*' => 'integer|between:0,3',\n ]);\n $forUser = null;\n\n $types = [Comment::TYPE_NEUTRAL, Comment::TYPE_GAME_CHANGER, Comment::TYPE_POSITIVE];\n $user = $this->request->user();\n if ($this->request->has('forUserId')) {\n $forUser = $user->team->users()->uuid($this->request->input('forUserId'));\n }\n\n $comments = Comment::query()\n ->whereHas('activity', static function (Builder $builder) use ($user, $forUser): void {\n $builder\n // I left feedback on my own activity; or\n ->where('activities.user_id', $user->getId());\n if ($forUser) {\n // I left feedback on any activity for this user.\n $builder->orWhere([\n 'user_id' => $user->getId(),\n 'activities.user_id' => $forUser->getId(),\n ]);\n }\n })\n ->whereIn('type', $this->request->input('types', $types))\n ->orderBy('created_at', 'desc')\n ->get();\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity', 'user'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($comments, new ActivityCommentTransformer());\n }\n\n public function deleteCoachingFeedback(Activity $activity, CoachingFeedback $coachingFeedback)\n {\n $this->authorize('deleteCoachingFeedback', [$activity, $coachingFeedback]);\n $activity = $coachingFeedback->getActivity();\n\n if ($coachingFeedback->delete()) {\n event(new UpdateSingleEntity(\n entityId: $activity->getId(),\n updateTarget: UpdateTargetEnum::ACTIVITY,\n purpose: 'delete-coaching-feedback',\n ));\n\n return $this->response->withOk();\n }\n\n return $this->response->withError('Delete operation failed. Contact support.', 500);\n }\n\n /**\n * Add new or update Coaching feedback\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws \\Illuminate\\Validation\\ValidationException\n *\n * @return mixed\n */\n public function putCoachingFeedback(Request $request, Activity $activity)\n {\n $user = $request->user();\n\n if (! $user instanceof User) {\n abort(403);\n }\n $teamId = $user->getTeamId();\n\n $this->authorize('coach', $activity);\n\n $this->request->validate([\n 'coach_id' => 'required|uuid:users,team_id,' . $teamId,\n 'coachee_id' => 'required|uuid:users,team_id,' . $teamId,\n 'visibility' => ['required', Rule::in(CoachingFeedback::VISIBILITIES)],\n 'coaching_sections.*.uuid' => 'required|uuid:coaching_sections',\n 'coaching_sections.*.score' => ['required', Rule::in(CoachingSectionFeedback::SCORES)],\n 'coaching_sections.*.summary' => 'string|max:10000',\n 'coaching_sections.*.criteria.*.uuid' => 'required|uuid:coaching_section_criteria',\n 'coaching_sections.*.criteria.*.note' => 'required|string|max:10000',\n 'sharedWithUsers' => [\n 'required_if:visibility,' . CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS,\n 'array',\n ],\n 'sharedWithUsers.*' => [\n 'uuid:users,team_id,' . $teamId,\n ],\n ]);\n\n /** @var User $coach */\n $coach = User::uuid($this->request->input('coach_id'));\n /** @var User $coachee */\n $coachee = User::uuid($this->request->input('coachee_id'));\n $coachingSectionFeedbacks = $this->request->input('coaching_sections');\n\n $previousRecord = $this->coachingFeedbackRepository->getOneForActivityByCoacheeAndCoach(\n $coachee->getId(),\n $coach->getId(),\n $activity->getId()\n );\n $recordIsNew = false;\n if ($previousRecord === null) {\n $recordIsNew = true;\n }\n\n if (! $coachee->isSameTeamId($coach)) {\n return $this->response->errorForbidden('User not member of your team.');\n }\n\n if (! is_array($coachingSectionFeedbacks) || count($coachingSectionFeedbacks) < 1) {\n return $this->response->withError('At least one Coaching Framework Section shall be scored.', 422);\n }\n\n if (! $activity->participants()->where('participants.user_id', $coachee->id)->exists()) {\n return $this->response->withError('Coached user did not participate activity.', 422);\n }\n\n $visibility = $this->request->input('visibility');\n\n $shouldSendNotification = $recordIsNew;\n if ($recordIsNew === false && $visibility !== $previousRecord->getVisibility()) {\n $shouldSendNotification = true;\n }\n\n /**\n * Create CoachingFeedback\n *\n * @var CoachingFeedback $coachingFeedback\n */\n $coachingFeedback = $activity->coachingFeedbacks()->updateOrCreate(\n [\n 'coach_id' => $coach->id,\n 'coachee_id' => $coachee->id,\n ],\n [\n 'framework_id' => $activity->category->id,\n 'visibility' => $visibility,\n ]\n );\n\n $sharedUserIds = [];\n if ($visibility === CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS) {\n foreach ($this->request->input('sharedWithUsers') as $sharedWithUserUuid) {\n /** @var User $user */\n $user = User::uuid($sharedWithUserUuid);\n $sharedUserIds[] = $user->getId();\n }\n }\n\n $syncResult = $coachingFeedback->customAccessUsers()->sync($sharedUserIds);\n\n $scores = [];\n\n\n /**\n * Create CoachingSectionsFeedbacks.\n *\n * @var CoachingSectionFeedback $coachingSectionFeedback\n */\n foreach ($coachingSectionFeedbacks as $coachingSectionFeedbackInput) {\n $coachingSection = CoachingSection::uuid($coachingSectionFeedbackInput['uuid']);\n $coachingSectionFeedback = $coachingFeedback->sectionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_id' => $coachingSection->id,\n ],\n [\n 'score' => array_get($coachingSectionFeedbackInput, 'score'),\n 'summary' => array_get($coachingSectionFeedbackInput, 'summary') ?? '',\n ]\n );\n\n $scores[] = array_get($coachingSectionFeedbackInput, 'score');\n\n $criteria = array_get($coachingSectionFeedbackInput, 'criteria');\n if (is_array($criteria) && ! empty($criteria)) {\n foreach ($criteria as $criteriaFeedbackInput) {\n $coachingSectionFeedback->criterionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_criterion_id' => CoachingSectionCriterion::uuid(array_get($criteriaFeedbackInput, 'uuid'))\n ->id,\n ],\n ['note' => array_get($criteriaFeedbackInput, 'note')],\n );\n }\n }\n }\n\n $coachingFeedback->average_score = array_sum($scores) / count($scores);\n\n if ($recordIsNew === false && $coachingFeedback->getAverageScore() !== $previousRecord->getAverageScore()) {\n $shouldSendNotification = true;\n }\n if (! empty($syncResult['attached']) || ! empty($syncResult['detached']) || ! empty($syncResult['updated'])) {\n $shouldSendNotification = true;\n }\n\n $coachingFeedback->save();\n // ensure updated at for coaching feedback on section feedback summary added.\n $coachingFeedback->touch();\n\n if ($shouldSendNotification) {\n event(new Coached($coachingFeedback));\n }\n\n Datadog::increment('jiminny.activity.score.update', 1, ['company' => $activity->user->team->slug]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n $coachingFeedbackTransformer = new CoachingFeedbackTransformer();\n $coachingFeedbackTransformer->setConsumer($this->getUserFromRequest($request));\n\n return $this->response->withItem($coachingFeedback, $coachingFeedbackTransformer);\n }\n\n\n /**\n * Retrieve category criteria for coaching.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachingSections(Activity $activity)\n {\n $this->authorize('coach', $activity);\n\n if ($activity->category === null) {\n return $this->response->errorUnprocessable('Category has not yet been assigned.');\n }\n\n $criteria = $activity\n ->category\n ->coachingSections()\n ->where('is_enabled', 1)\n ->orderBy('sequence', 'asc');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($criteria->get(), new CoachingSectionsTransformer());\n }\n\n /**\n * @throws AuthorizationException\n * @throws ValidationException\n *\n * @return mixed\n */\n public function addToPlaylist(Activity $activity, PlaylistTrackFactoryInterface $playlistTrackFactory)\n {\n $this->request->validate([\n 'playlists' => 'required|array',\n 'playlists.*' => 'uuid:playlists',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'name' => 'required|max:100',\n ]);\n\n $this->authorize('addToPlaylist', [$activity, $this->request->input('playlists')]);\n\n $startTime = $this->request->input('start_time');\n $endTime = $this->request->input('end_time');\n $name = $this->request->input('name');\n /** @var User $user */\n $user = $this->request->user();\n\n // Get playlist by uuid.\n foreach ($this->request->input('playlists') as $playlistId) {\n // Pull out the playlist model.\n $playlist = Playlist::uuid($playlistId);\n\n $playlistTrackFactory->createTrack($playlist, $user, [\n 'name' => $name,\n 'activity' => $activity,\n 'start_time' => $startTime,\n 'end_time' => $endTime,\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function share(Request $request, Activity $activity): JsonResponse\n {\n $this->authorize('share', $activity);\n\n $request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'recipients.*.type' => 'in:user,group',\n 'recipients.*.id' => 'string|max:40',\n 'share' => 'string|max:255',\n ]);\n\n $user = $request->user();\n\n $recipients = $request->get('recipients');\n $users = $this->userService->convertRecipientsToUsers($user, $recipients);\n\n $shareData = [\n 'from_user_id' => $user->id,\n 'note' => $request->input('note'),\n 'start_time' => $request->input('start_time'),\n 'end_time' => $request->input('end_time'),\n ];\n\n // Create a share object against a notification provider channel\n if ($request->input('share')) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'notification_provider_channel' => $request->input('share'),\n ]\n )\n );\n\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n\n // Create a share object against each recipient\n foreach ($users as $recipient) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'to_user_id' => $recipient->id,\n ]\n )\n );\n\n // If parent_share_id has been selected yet\n if (! isset($shareData['parent_share_id'])) {\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachRequest(Activity $activity)\n {\n $this->authorize('coachRequest', $activity);\n\n $this->request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'coachers.*.type' => 'required|in:user',\n 'coachers.*.id' => 'required',\n ]);\n\n $coachers = $this->request->get('coachers');\n $user = $this->request->user();\n $users = $this->userService->convertRecipientsToUsers($user, $coachers);\n\n foreach ($users as $coacher) {\n CoachRequest::create([\n 'user_id' => $coacher->id,\n 'activity_id' => $activity->id,\n 'note' => $this->request->get('note'),\n 'start_time' => $this->request->get('start_time'),\n 'end_time' => $this->request->get('end_time'),\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function createActivityTopicTriggers(Activity $activity, LoggerInterface $logger): HttpFoundation\\JsonResponse\n {\n $this->authorize('analyzeTopicTriggers', $activity);\n\n if (! $activity->hasTranscription()) {\n return new HttpFoundation\\JsonResponse(\n [\n 'error' => 'Transcription not found.',\n ],\n JsonResponse::HTTP_NOT_FOUND\n );\n }\n\n $logger->info(__METHOD__ . ': queued for analysis', [\n 'activity' => $activity->id_string,\n ]);\n\n dispatch(new ActivityAnalytics\\Job\\AnalyzeActivityTopicTriggers($activity));\n\n return new HttpFoundation\\JsonResponse(null, JsonResponse::HTTP_CREATED);\n }\n\n public function fetchActivityTopicTriggers(\n Activity $activity,\n LoggerInterface $logger,\n ActivityTopicTriggerTransformer $transformer\n ): HttpFoundation\\JsonResponse {\n $this->authorize('fetchTopicTriggers', $activity);\n\n $logger->debug(__METHOD__, [\n 'activity' => $activity->id_string,\n ]);\n\n if (! $activity->isProcessed()) {\n return new HttpFoundation\\JsonResponse([]);\n }\n\n $payload = [];\n\n if ($activity->hasTopicTriggers()) {\n $payload = $activity->getTopicTriggersSorted()\n ->map(\n static fn (Activity\\TopicTrigger $activityTopicTrigger): array\n => $transformer->transform($activityTopicTrigger)\n )\n ->values()\n ->all();\n }\n\n return new HttpFoundation\\JsonResponse($payload);\n }\n\n /**\n * @param Activity $activity\n * @param StatsTransformer $statsTransformer\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function stats(Activity $activity, StatsTransformer $statsTransformer)\n {\n $this->authorize('stream', $activity);\n\n if (! $activity->hasTranscription()) {\n return $this->response->errorNotFound('Waveform data is not yet generated.');\n }\n\n $this->response\n ->getManager()\n ->parseIncludes(['wavedata'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($activity, $statsTransformer);\n }\n\n public function destroy(Activity $activity)\n {\n $this->authorize('delete', $activity);\n\n $activity->delete();\n\n \\Log::info('Soft delete activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n\n return $this->response->withNoContent();\n }\n\n public function note(Activity $activity)\n {\n $this->authorize('note', $activity);\n\n $this->request->validate([\n 'note' => 'required|min:1|max:2000',\n 'time' => 'required|numeric|min:0|max:86400',\n ]);\n\n $note = $this->request->input('note');\n $time = $this->request->input('time');\n\n $this->activityService->setActivity($activity);\n $this->activityService->takeNote($this->getUser(), $note, $time);\n\n return $this->response->withCreated();\n }\n\n /**\n * Mark an activity as private.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPrivate(Activity $activity)\n {\n $this->authorize('markAsPrivate', $activity);\n\n if ($activity->is_private === false) {\n $activity->is_private = true;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * Mark an activity as public.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPublic(Activity $activity)\n {\n $this->authorize('markAsPublic', $activity);\n\n if ($activity->is_private) {\n $activity->is_private = false;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws LogicException\n */\n public function fetchCloudFrontS3MediaKeys(Activity $activity, PlaybackService $playbackService): JsonResponse\n {\n $masterTrack = $activity->masterTrack()->first();\n\n if (! $masterTrack instanceof Track) {\n throw new LogicException(sprintf('Master track not found for activity \"%s\"', $activity->getUuid()));\n }\n\n return $this->response->withArray(\n $playbackService->generateCookies(\n $masterTrack,\n $this->request->ip(),\n ),\n );\n }\n\n /**\n * @throws ValidationException\n */\n private function updateOrCreateActivitySearch(Request $request, ?Search $search = null): Search\n {\n $request->validate([\n 'name' => 'required|string|min:2|max:100',\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $searchName = $request->input('name');\n\n if ($search !== null) {\n $search->update([\n 'name' => $searchName,\n ]);\n\n return $search;\n }\n\n $request->validate([\n 'filters' => ['required', 'array', new MultidimensionalArrayMaxCharRule(limit: 255)],\n 'nudges' => 'array|max:' . count(Nudge::MAP_CHANNEL),\n 'nudges.*.channel' => 'required|in:' . implode(',', Nudge::MAP_CHANNEL),\n 'nudges.*.frequency' => 'required|in:' . implode(',', Nudge::MAP_FREQUENCY),\n 'nudges.*.expiresAt' => [\n 'required',\n 'date',\n 'after:today',\n 'before_or_equal:' . now()->addYear()->format('Y-m-d'),\n ],\n ]);\n\n $searchCriteria = Criteria::createFromRequest(\n Collection::make($request->input('filters', []))->all(),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($searchCriteria, $user);\n $this->validateSearch($request, $filterSet, 'filters.');\n\n /** @var Search $search */\n $search = Search::create([\n 'name' => $searchName,\n 'uuid' => Uuid::uuid4()->toString(),\n 'user_id' => $user->getId(),\n ]);\n\n Collection::make($request->input('nudges', []))\n ->each(fn (array $attributes): Nudge => $this->nudgeFactory->createNudge($search, $attributes));\n\n $this->storeNamedSearchFilters(Collection::make($request->all()), $search, $filterSet, 'filters.');\n\n return $search;\n }\n\n private function resolveAccount(\n Team $team,\n Contact $contact,\n ServiceInterface $crmService,\n array $prospects,\n ): ?Account {\n $this->logger->info('Resolving account from contact');\n $account = $contact->getAccount();\n\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS)) {\n $this->logger->info('Team does not have feature to link activity to multiple prospects');\n\n return $account;\n }\n\n $this->logger->info('Resolving account from prospect data');\n $accountData = array_filter(\n $prospects,\n static fn (array $prospectData): bool => $prospectData['type'] === 'account'\n );\n\n if (! empty($accountData)) {\n $this->logger->info('Found account data in prospects');\n $accountData = reset($accountData);\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountData['id'])->first();\n\n if (! $account instanceof Account) {\n $this->logger->info('Account not found in database, syncing from CRM');\n $account = $crmService->syncAccount($accountData['id']);\n }\n }\n\n $this->logger->info('Resolved account', ['account' => $account->getId()]);\n\n return $account;\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Http\\Controllers\\API;\n\nuse Carbon\\Carbon;\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Exception;\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Validation\\Rule;\nuse Illuminate\\Validation\\Rules\\In;\nuse Illuminate\\Validation\\ValidationException;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ActivityAnalytics;\nuse Jiminny\\Component\\ActivitySearch;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Contracts\\ES\\Events\\UpdateSingleEntity;\nuse Jiminny\\Contracts\\ES\\UpdateTargetEnum;\nuse Jiminny\\Contracts\\Nudge\\NudgeFactoryInterface;\nuse Jiminny\\Contracts\\Playlist\\PlaylistTrackFactoryInterface;\nuse Jiminny\\Contracts\\Repositories\\PlaylistActivityRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Enums\\TeamSetting;\nuse Jiminny\\Events\\Activities\\AiAutomation\\ActivityProspectAdded;\nuse Jiminny\\Events\\Activities\\Coaching\\Coached;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Controllers\\CommentContextInterface;\nuse Jiminny\\Http\\Responses\\Api\\AbstractResponse;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\ActivityCommentTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTopicTriggerTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTransformer;\nuse Jiminny\\Http\\Transformers\\AvailabilityNotificationTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingFeedbackTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingSectionsTransformer;\nuse Jiminny\\Http\\Transformers\\SearchTransformer;\nuse Jiminny\\Http\\Transformers\\StatsTransformer;\nuse Jiminny\\Jobs\\Crm\\SaveActivity;\nuse Jiminny\\Jobs\\Crm\\UpdateStage;\nuse Jiminny\\Jobs\\Telephony\\StartRecording;\nuse Jiminny\\Jobs\\Telephony\\StopRecording;\nuse Jiminny\\Jobs\\Telephony\\ToggleRecording;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\CoachingFeedback;\nuse Jiminny\\Models\\CoachingSection;\nuse Jiminny\\Models\\CoachingSectionCriterion;\nuse Jiminny\\Models\\CoachingSectionFeedback;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\LanguageDialect;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Nudge;\nuse Jiminny\\Models\\PlaybookCategory;\nuse Jiminny\\Models\\Playlist;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\Track;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\CoachingFeedbackRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Rules\\MultidimensionalArrayMaxCharRule;\nuse Jiminny\\Services\\ActivityService;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Services\\PlaybackService;\nuse Jiminny\\Services\\UserService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\nuse Ramsey\\Uuid\\Uuid;\nuse Sentry;\nuse Symfony\\Component\\HttpFoundation;\n\nfinal class ActivityController extends Controller implements CommentContextInterface\n{\n // Number of minutes to look back on activities. i.e. a timeout on activity duration.\n private const int LOOK_BACK = 180;\n\n public function __construct(\n private ProviderRegistry $providerRegistry,\n private ActivityService $activityService,\n Response $response,\n private UserService $userService,\n private ActivitySearch\\Service\\ActivitySearch $activitySearch,\n private NudgeFactoryInterface $nudgeFactory,\n private ActivityCommentService $activityCommentService,\n private LoggerInterface $logger,\n private readonly CoachingFeedbackRepository $coachingFeedbackRepository,\n private readonly TeamRepository $teamRepository,\n ) {\n parent::__construct($response);\n }\n\n public static function getCommentImplementation(): string\n {\n return Comment::class;\n }\n\n public function delete()\n {\n $this->request->validate([\n '*' => 'uuid:activities',\n ]);\n\n $deletedIds = [];\n foreach ($this->request->all() as $activityId) {\n $activity = Activity::idOrUuId($activityId);\n\n try {\n if ($this->authorize('delete', $activity)) {\n $activity->delete();\n $deletedIds[] = $activityId;\n\n \\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n }\n } catch (AuthorizationException $authorizationException) {\n // They didn't have permission.\n }\n }\n\n return $this->response->withArray($deletedIds);\n }\n\n public function update(Request $request, Activity $activity)\n {\n $this->authorize('updateMetadata', $activity);\n\n $request->validate([\n 'title' => 'string|max:250',\n 'category_id' => 'uuid:playbook_categories',\n 'language' => [\n new In(\n LanguageDialect::query()\n ->with('language')\n ->cursor()\n ->map(static function (LanguageDialect $languageDialect): string {\n return $languageDialect->getLanguageLocale();\n })\n ->all()\n ),\n ],\n ]);\n\n if ($request->has('title')) {\n $activity->title = $request->input('title');\n }\n\n if ($request->has('category_id')) {\n $category = PlaybookCategory::uuid($request->input('category_id'));\n\n if ($category->playbook->team_id !== $request->user()->team_id) {\n return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n if ($request->has('language')) {\n if (! $activity->isInProgress()) {\n return $this->response->withError(\n 'Activity language can only be set while the meeting is in progress.',\n 400\n );\n }\n\n $activity->setLanguageCode($request->input('language'));\n }\n\n $activity->save();\n\n return $this->response->withOk();\n }\n\n // XXX: This should be merged with the update method.\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws SocialAccountTokenInvalidException\n *\n * @return mixed\n */\n public function summarize(Activity $activity): mixed\n {\n $this->logger->info('[Log Activity] Summarizing activity ', [\n 'activityId' => $activity->getUuid(),\n 'payload' => $this->request->all(),\n ]);\n $this->authorize('update', $activity);\n\n $this->logger->info('[Log Activity] Validating summary');\n // Validate the payload.\n $this->validateSummary($activity);\n\n // All objects must belong to this team.\n /** @var User $user */\n $user = $this->request->user();\n $team = $user->getTeam();\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n try {\n $crmUser = $user;\n if ($user->isCrmRequired() === false) {\n $crmUser = $team->owner;\n }\n $crmService->setUser($crmUser);\n } catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());\n }\n\n $rawEntities = $this->request->input('entities');\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid(\n $this->request->input('layout_id')\n );\n\n // Delay execution of CRM jobs to avoid locking issues.\n $jobDelay = 0;\n\n // If we have arrived from a notification, mark it as read.\n $notificationId = $this->request->input('nId');\n if ($notificationId) {\n $notification = $user->unreadNotifications->where('id', $notificationId)->first();\n\n if ($notification) {\n $notification->markAsRead();\n }\n }\n\n $title = $this->request->input('title');\n $prospects = $this->request->input('prospects');\n $opportunityId = $this->request->input('opportunity_id');\n $stageId = $this->request->input('stage_id');\n $categoryId = $this->request->input('category_id');\n $summary = $this->request->input('summary');\n $crmProviderId = $this->request->input('crm_id');\n $isInternal = $this->request->input('is_internal') ?? false;\n\n $lead = null;\n $category = null;\n $account = null;\n $contact = null;\n $opportunity = null;\n $stage = null;\n $callStage = null;\n\n foreach ($prospects as $prospectData) {\n $objectId = $prospectData['id'];\n\n if ($objectId === null) {\n continue;\n }\n\n $objectType = $prospectData['type'];\n $this->logger->info('debug', ['prospect_data' => $prospectData]);\n\n try {\n if ($objectType === null) {\n $this->logger->info('no object type');\n if ($crmService instanceof SupportsObjectTypeParseInterface) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n }\n\n switch ($objectType) {\n case 'lead':\n $this->logger->info('Processing lead');\n /** @var Lead|null $lead */\n $lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();\n\n // Lead does not exist locally, import it.\n if ($lead === null) {\n $this->logger->info('Lead does not exist locally');\n /** @var Lead $lead */\n $lead = $crmService->syncLead($objectId);\n }\n\n $this->logger->info('Lead found', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n if ($stageId === null) {\n $this->logger->info('Stage ID is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $lead->stage;\n\n break;\n }\n\n $this->logger->info('Looking for stage');\n // Determine if they have changed the stage.\n /** @var Stage $stage */\n $stage = $team->crm->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_LEAD)\n ->firstOrFail();\n\n $this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);\n if ($lead->stage_id && $lead->stage_id !== $stage->id) {\n $this->logger->info('Stage has changed');\n // Storage current stage on activity.\n $callStage = $lead->stage;\n\n // The stage has changed, update in remote CRM.\n dispatch(new UpdateStage($activity, $lead, $callStage, $stage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing lead stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->getName(),\n $stage->getName()\n ),\n [\n 'user' => $user->getUuid(),\n 'lead' => $lead->getUuid(),\n ]\n );\n } else {\n $this->logger->info('Stage has not changed');\n // Stage remains as current.\n $callStage = $stage;\n }\n\n break;\n\n case 'account':\n $this->logger->info('Processing account');\n // If the object is not a lead, it should be an account.\n $account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();\n\n // Account does not exist locally, import it.\n if ($account === null) {\n $this->logger->info('Account does not exist locally');\n $account = $crmService->syncAccount($objectId);\n }\n\n $this->logger->info('Account found', ['accountId' => $account->id]);\n\n break;\n case 'contact':\n $this->logger->info('processing contact');\n $contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $this->logger->info('contact does not exist locally');\n $contact = $crmService->syncContact($objectId);\n }\n\n $this->logger->info('resolving account');\n $account = $this->resolveAccount($team, $contact, $crmService, $prospects);\n\n break;\n }\n\n // If they have specified an opportunity, retrieve this with stage.\n if ($opportunityId) {\n $this->logger->info('opportunity id is set');\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if ($opportunity === null) {\n $this->logger->info('opportunity does not exist locally');\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n if ($stageId === null) {\n $this->logger->info('stage id is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $opportunity->stage ?? null;\n } else {\n $this->logger->info('looking for stage');\n /** @var ?Stage $opportunityStage */\n $opportunityStage = $team->crm\n ->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n // There is a chance we still cannot import this opportunity.\n if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {\n $this->logger->info('opportunity stage has changed');\n // Storage current stage on activity.\n $callStage = $opportunity->stage;\n\n dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing opportunity stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->name,\n $opportunityStage->name\n ),\n [\n 'userId' => $user->id_string,\n 'opportunityId' => $opportunity->id_string,\n ]\n );\n } else {\n $this->logger->info('opportunity stage has not changed');\n // Stage remains as current.\n $callStage = $opportunityStage;\n }\n }\n }\n\n if ($crmProviderId) {\n // Cast $crmProviderId to string otherwise it won't use database index for some records\n $linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();\n\n // Check if this activity has already been assigned to a different activity.\n if ($linkedActivity && $linkedActivity->id !== $activity->id) {\n throw new InvalidArgumentException(\n 'Sorry, the linked task has already been logged under a different call. '\n . 'Please choose another linked task.'\n );\n }\n }\n } catch (InvalidArgumentException $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($exception->getMessage());\n } catch (Exception $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorInternalError(\n 'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'\n );\n }\n }\n\n if ($categoryId) {\n $category = PlaybookCategory::uuid($categoryId);\n\n if ($category->playbook->team_id !== $team->id) {\n throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n $this->logger->info('Prospect data', [\n 'lead_id' => $lead?->getId(),\n 'account_id' => $account?->getId(),\n 'contact_id' => $contact?->getId(),\n 'opportunity_id' => $opportunity?->getId(),\n 'stage_id' => $stage?->getId(),\n ]);\n\n if ($title) {\n $activity->title = $title;\n }\n\n if ($summary) {\n $activity->summary = $summary;\n }\n\n if ($crmProviderId) {\n $activity->crm_provider_id = $crmProviderId;\n }\n\n if ($callStage) {\n $this->logger->info('Setting stage id', ['stageId' => $callStage->id]);\n $activity->stage_id = $callStage->id;\n }\n\n if ($lead) {\n $this->logger->info('Setting lead id', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n // If we are changed from an account > lead, unset the account data.\n $this->logger->info('Unsetting account id, opportunity id, contact id, value');\n $activity->account_id = null;\n $activity->opportunity_id = null;\n $activity->contact_id = null;\n $activity->value = null;\n }\n\n if ($account) {\n $this->logger->info('Setting account id', ['accountId' => $account->id]);\n $activity->account_id = $account->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('unsetting lead id');\n $activity->lead_id = null;\n\n // Unset the contact if switching different accounts. Will be set up below if still applicable.\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {\n $this->logger->info('Unsetting contact id');\n $activity->contact_id = null;\n }\n }\n\n if ($opportunity) {\n $this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);\n $this->logger->info('unsetting lead id');\n $activity->opportunity_id = $opportunity->id;\n $activity->value = $opportunity->value;\n\n // If we are changed from an lead > account, unset the lead data.\n $activity->lead_id = null;\n }\n\n if ($contact) {\n $this->logger->info('setting contact id', ['contactId' => $contact->id]);\n $activity->contact_id = $contact->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('Unsetting lead id');\n $activity->lead_id = null;\n }\n\n $activity->is_internal = $isInternal;\n $activity->save();\n $activity->refresh();\n\n $this->logger->notice('Activity saved', [\n 'activity_id' => $activity->getId(),\n 'lead_id' => $activity->lead_id,\n 'account_id' => $activity->account_id,\n 'contact_id' => $activity->contact_id,\n 'opportunity_id' => $activity->opportunity_id,\n 'stage_id' => $activity->stage_id,\n 'crm_provider_id' => $activity->getCrmProviderId(),\n ]);\n\n // Store entities as field data on the activity.\n $updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);\n\n if ($activity->isLoggable()) {\n // Follow-up Task or Event data.\n $followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);\n\n $this->logger->info('CRM LOG manual log triggered', [\n 'activityId' => $activity->getUuid(),\n 'followupData' => $followupData,\n 'userId' => $user->getUuid(),\n ]);\n\n // Store data in the CRM.\n // ++add check for crm_required\n $job = new SaveActivity($activity, $followupData);\n\n if ($updatedData) {\n $job->delay(Carbon::now()->addMinutes($jobDelay));\n }\n\n dispatch($job);\n\n // Manually dispatch log for Opportunity or Prospect added\n if ($activity->hasOpportunity() || $activity->hasProspect()) {\n event(new ActivityProspectAdded(\n activity: $activity,\n eventSource: 'manually-log-crm-data'\n ));\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.\n *\n * @param ServiceInterface $service\n * @param Activity $activity\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array\n {\n $updatedData = [];\n $existingData = $activity->data()->get();\n\n // We need to delete any existing data to overwrite with latest values.\n $activity->data()->delete();\n\n $layoutEntities = $layout->entities()\n ->with('field', 'parent')\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->get();\n\n /** @var LayoutEntity $entity */\n foreach ($layoutEntities as $entity) {\n // If the user has provided a value for this entity\n if (array_key_exists($entity->id_string, $entities)) {\n $value = $entities[$entity->id_string];\n\n // Convert raw data into values that the CRM can consume.\n if ($value) {\n $value = $service->normalizeValue($entity->field->type, $value);\n }\n\n // Check the field is part of the activity-summary section.\n if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {\n // This is the internal database ID, not the external CRM ID.\n $objectId = null;\n\n switch ($entity->field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $objectId = $activity->account_id;\n\n break;\n\n case Field::OBJECT_CONTACT:\n $objectId = $activity->contact_id;\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n $objectId = $activity->opportunity_id;\n\n break;\n\n case Field::OBJECT_LEAD:\n $objectId = $activity->lead_id;\n\n break;\n\n case Field::OBJECT_TASK:\n case Field::OBJECT_EVENT:\n $objectId = $activity->id;\n\n break;\n }\n\n if ($objectId) {\n /** @var FieldData $data */\n $data = $activity->data()->create([\n 'crm_layout_entity_id' => $entity->id,\n 'crm_field_id' => $entity->crm_field_id,\n 'object_type' => $entity->field->object_type,\n 'object_id' => $objectId,\n 'value' => $value,\n ]);\n\n // Never send read-only field data to the CRM.\n if ($entity->read_only === false && $entity->is_visible) {\n $existingValue = $existingData\n ->where('crm_layout_entity_id', $entity->id)\n ->where('crm_field_id', $entity->crm_field_id)\n ->where('object_type', $entity->field->object_type)\n ->where('object_id', $objectId)\n ->first();\n\n // If the field was actually changed, we need to reflect this in the CRM too.\n if ($existingValue === null || $existingValue->value !== $value) {\n $updatedData[] = $data->id;\n }\n }\n }\n }\n }\n }\n\n return $updatedData;\n }\n\n /**\n * Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.\n *\n * @param ServiceInterface $crmService\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array\n {\n $fieldData = [];\n foreach ($entities as $entityId => $value) {\n // Only bother with fields that have a value.\n if ($value) {\n // Extract the entity from the UUID. Check the field is valid and part of the follow-up section.\n $entity = $layout->entities()\n ->uuid($entityId, false)\n ->whereHas('parent', function ($query) {\n $query->where('label', 'follow-up');\n })\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->first();\n\n if ($entity) {\n // Convert raw data into values that the CRM can consume.\n $value = $crmService->normalizeValue($entity->field->type, $value);\n\n // Add the field and value to the payload.\n $fieldData += [\n $entity->field->crm_provider_id => $value,\n ];\n }\n }\n }\n\n return $fieldData;\n }\n\n /**\n * @param Activity $activity\n */\n private function validateSummary(Activity $activity): void\n {\n $team = $activity->user->team;\n $crmProvider = $team->crm->provider;\n $attributes = [];\n\n $rules = [\n 'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,\n 'title' => 'string|max:250',\n 'prospects' => 'required|array',\n 'opportunity_id' => new CrmReference($crmProvider),\n 'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',\n 'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator\n 'summary' => 'max:50000',\n 'nId' => 'exists:notifications,id',\n 'crm_id' => new CrmReference($crmProvider),\n 'entities' => 'array',\n 'is_internal' => 'boolean',\n ];\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));\n\n // Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.\n $entities = $layout->entities()\n ->where('read_only', 0)\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->whereHas('parent', function ($query) use ($activity) {\n if ($activity->isLoggable() === false) {\n $query->where('label', '<>', 'follow-up');\n }\n });\n\n $isInternal = $this->request->input('is_internal', false);\n\n foreach ($entities->get() as $entity) {\n $rules += $this->buildFieldValidator($entity, $isInternal);\n $attributes += $this->buildFieldMessage($entity);\n }\n\n $this->request->validate($rules, [], $attributes);\n }\n\n private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array\n {\n return [\n 'entities.' . $entity->id_string => $entity->getValidator($isInternal),\n ];\n }\n\n /**\n * @param LayoutEntity $entity\n *\n * @return array\n */\n private function buildFieldMessage(LayoutEntity $entity): array\n {\n $label = $entity->label;\n if ($label === null) {\n $label = $entity->field->label;\n }\n\n return [\n 'entities.' . $entity->id_string => $label,\n ];\n }\n\n public function search(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->debugLog(\n $user,\n 'User extracted from request',\n ['user' => $user->getId(), 'tz' => $user->getTimezone()]\n );\n\n $searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());\n\n $this->debugLog(\n $user,\n 'ActivitySearch criteria built',\n ['searchCriteria' => $searchCriteria]\n );\n\n $filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);\n\n $this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);\n\n $this->validateSearch($request, $filterSet);\n\n $this->debugLog($user, 'Request validated');\n\n $searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);\n\n /** @var Collection<Activity> $activities */\n $activities = $searchResponse['results'];\n\n $this->debugLog($user, 'Activities ES response extracted');\n\n $hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(\n $user->getTeamId(),\n TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),\n );\n\n if ($hideInternalMeetingsSetting?->getValue() === '1') {\n $activities = $activities->filter(function (Activity $activity) {\n if ($activity->is_internal && empty($activity->actual_start_time)) {\n return false;\n }\n\n return true;\n });\n }\n\n $this->debugLog($user, 'Internal meetings (?!) filtered');\n\n $this->response->getManager()\n ->parseIncludes([\n 'category',\n 'organizer.group',\n 'prospect',\n 'stage',\n 'opportunity',\n 'stats',\n 'scorecards',\n 'masterTrack',\n 'activeParticipants',\n 'notification',\n ])\n ->setSerializer(new JsonSerializer());\n\n $transformerExcludes = $this->request->input('exclude');\n if ($transformerExcludes) {\n $this->response->getManager()->parseExcludes($transformerExcludes);\n }\n\n $this->debugLog($user, 'Response Manager (?!) applied');\n\n $transformer = new ActivityTransformer();\n $transformer->setConsumer($user);\n\n $this->debugLog($user, 'Activity Transformer added');\n\n $resource = new \\League\\Fractal\\Resource\\Collection($activities, $transformer);\n $page = $searchCriteria->getPageNumber();\n\n $this->debugLog($user, 'Search criteria page number called', ['page' => $page]);\n\n $histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');\n\n $this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);\n\n return $this->response->withArray([\n 'pagination' => [\n 'total' => $searchResponse['totalHits'],\n 'current' => $page,\n 'prev' => max($page - 1, 1),\n 'next' => $page + 1,\n ],\n 'results' => $this->response->getManager()->createData($resource)->toArray(),\n 'histogram' => $histogram,\n ]);\n }\n\n private function debugLog(User $user, string $logMessage, ?array $context = []): void\n {\n // Debug for Learning People Only\n if ($user->getTeamId() !== 260) {\n return;\n }\n\n Log::notice(\n sprintf('[activity-search-controller] %s', $logMessage),\n $context\n );\n }\n\n /** @throws ValidationException */\n private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void\n {\n $rules = [\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ];\n\n if ($prefix !== null && mb_strpos($prefix, '.') !== false) {\n $rules[rtrim($prefix, '.')] = sprintf(\n 'required|array|max:%d',\n $filterSet->count()\n );\n }\n\n $validationRules = $filterSet->getValidationRules($prefix)\n ->merge($rules)\n ->all();\n\n $request->validate($validationRules);\n }\n\n public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $search = $this->updateOrCreateActivitySearch($request);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function updateActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('update', $search);\n\n $this->updateOrCreateActivitySearch($request, $search);\n\n return $this->response->withOk();\n }\n\n private function storeNamedSearchFilters(\n Collection $request,\n Search $search,\n FilterDefinitionCollection $filterSet,\n ?string $prefix = null,\n ): self {\n $arrayTypeProperties = $filterSet\n ->getPropertyTypes([\n FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,\n ])\n ->all();\n\n $supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);\n\n foreach ($supportedRequestProperties as $requestPropertyName) {\n if (! array_has($request, $requestPropertyName)) {\n continue;\n }\n\n /** @var string|string[] $propertyValue */\n $propertyValue = array_get($request, $requestPropertyName);\n $propertyName = $prefix === null\n ? $requestPropertyName\n : mb_substr($requestPropertyName, mb_strlen($prefix));\n\n $isArrayType = array_has($arrayTypeProperties, $propertyName);\n\n if (! $isArrayType) {\n /** @var string $requestPropertyValue */\n\n $search->filters()->updateOrCreate(\n [\n 'filter' => $propertyName,\n ],\n [\n 'value' => $propertyValue,\n ]\n );\n\n continue;\n }\n\n /** @var string[] $requestPropertyValue */\n\n /** @var SearchFilter[]|Collection $existingFilterValues */\n $existingFilterValuesKeyed = $search->filters()\n ->where('filter', $propertyName)\n ->get()\n ->keyBy('id');\n\n // Iterate over values provided as request parameters\n foreach ($propertyValue as $value) {\n /** @var SearchFilter|null $valueFilter */\n $valueFilter = $search->filters()\n ->where(\n [\n 'filter' => $propertyName,\n 'value' => $value,\n ]\n )\n ->first();\n\n if ($valueFilter !== null) {\n // Remove filter value pair from list to be deleted\n $existingFilterValuesKeyed->forget($valueFilter->id);\n } else {\n // Add new filter/value pair\n $search->filters()->updateOrCreate([\n 'filter' => $propertyName,\n 'value' => $value,\n ]);\n }\n }\n\n // Delete filter value pairs for this filter that no longer exist in request parameters\n foreach ($existingFilterValuesKeyed as $existingFilter) {\n $existingFilter->delete();\n }\n }\n\n /** @var Collection<int, SearchFilter> $filtersKeyed */\n $filtersKeyed = $search->filters()->get()->keyBy('filter');\n\n // wipe removed filters from this search\n foreach ($filtersKeyed as $filterName => $filter) {\n if (array_has($request, $prefix . $filterName)) {\n continue;\n }\n\n // Remove all filter values for this filter\n $search->filters()->where('filter', $filterName)->delete();\n }\n\n return $this;\n }\n\n /**\n * @throws AuthorizationException\n */\n public function fetchActivitySearch(\n Search $search,\n Request $request,\n SearchTransformer $searchTransformer,\n ): JsonResponse {\n $this->authorize('view', $search);\n\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection(\n $user->searches()->get(),\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n /**\n * Deletes a saved search\n *\n * @param Request $request\n * @param Search $search\n *\n * @throws Exception\n *\n * @return JsonResponse\n */\n public function deleteActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('delete', $search);\n\n // Orphan any AutomatedReports that use this search\n $search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);\n\n // Delete filters and the search itself\n $search->filters()->delete();\n $search->delete();\n\n return $this->response->withOk();\n }\n\n public function live(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n $user = $this->getUserFromRequest($request);\n\n $this->request->validate([\n 'sort_direction' => 'in:asc,desc',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ]);\n\n $activities = $repository->getLiveCoachingEligibleActivities(\n user: $user,\n lookBackMinutes: self::LOOK_BACK,\n limit: (int) $this->request->input('limit', 25),\n page: (int) $this->request->input('page', 1),\n sortBy: ['actual_start_time', 'scheduled_start_time'],\n sortDirection: (string) $this->request->input('sort_direction', 'asc'),\n );\n\n $this->response\n ->getManager()\n ->parseIncludes(['organizer.group', 'prospect'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($activities, new ActivityTransformer());\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function show(Activity $activity, ActivityService $activityService): JsonResponse\n {\n $this->authorize('show', $activity);\n\n $user = $activity->getUser();\n $team = $user->getTeam();\n\n // Sync the opportunity with the latest data if possible.\n if ($activity->opportunity_id) {\n try {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n if (! $user->isCrmRequired()) {\n $crmService->setUser($team->getOwner());\n } else {\n $crmService->setUser($user);\n }\n\n $crmService->syncOpportunity($activity->opportunity->crm_provider_id);\n } catch (Exception $exception) {\n // Move on.\n }\n }\n\n $activityData = $activityService->getActivityData($this->request->user(), $activity);\n\n return response()->json($activityData);\n }\n\n public function createRecording(Activity $activity)\n {\n $this->authorize('record', $activity);\n\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Tell Twilio to start recording this activity.\n if ($activity->recording_state === Activity::RECORDING_OFF) {\n $job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withCreated();\n }\n\n return $this->response->errorGone('Activity is already recording.');\n }\n\n public function updateRecording(Request $request, Activity $activity)\n {\n $this->authorize('record', $activity);\n\n $request->validate([\n 'preference' => 'boolean',\n 'state' => [\n 'string',\n Rule::in([\n Activity::RECORDING_IN_PROGRESS,\n Activity::RECORDING_PAUSED,\n ]),\n ],\n ]);\n\n if ($request->has('state')) {\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Toggle the recording state between paused and resumed.\n if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {\n $job = (new ToggleRecording($activity, $request->input('state')))\n ->onQueue(Constants::QUEUE_CONFERENCES);\n\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Recording is not toggleable.');\n }\n\n if ($request->has('preference')) {\n $activity->update([\n 'recording_preference' => $request->input('preference') ? 1 : 0,\n ]);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorWrongArgs('Something went wrong');\n }\n\n public function stopRecording(Activity $activity)\n {\n $this->authorize('stopRecord', $activity);\n\n // Tell Twilio to stop recording this activity.\n if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {\n $job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Activity is not recording.');\n }\n\n /**\n * Add activity to this user's favorites playlist\n *\n * @throws AuthorizationException\n */\n public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse\n {\n $this->authorize('favorite', $activity);\n\n $user = $this->getUserFromRequest($this->request);\n $favorite = $activity->wasFavoritedBy($user);\n $name = $activity->activity_title ?? '';\n\n // It needs to check at least one record.\n if (! $favorite) {\n $favoritePlaylist = $user->favoritePlaylist();\n\n $playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(\n $activity,\n $user,\n $favoritePlaylist\n );\n\n if ($playlistActivity !== null) {\n $playlistActivity->update(\n // Just update, don't sort.\n ['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],\n );\n } else {\n $playlistActivity = $activity->playlistActivities()->create([\n 'playlist_id' => $favoritePlaylist->getId(),\n 'user_id' => $user->getId(),\n 'start_time' => 0,\n 'name' => mb_strimwidth($name, 0, 100),\n ]);\n // Sort it on top.\n $playlistActivity->update(\n [\n 'sort' => $playlistActivityRepository->calculateNewSortOrder(\n null,\n $playlistActivity,\n ),\n ],\n );\n }\n\n $playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);\n\n return new JsonResponse([], JsonResponse::HTTP_CREATED);\n }\n\n return new JsonResponse(\n [\n 'error' => [\n 'code' => AbstractResponse::CODE_CONFLICT,\n 'http_code' => JsonResponse::HTTP_CONFLICT,\n 'message' => 'Resource Already Exists',\n ],\n ],\n JsonResponse::HTTP_CONFLICT,\n );\n }\n\n /**\n * Remove activity from this user's favorites playlist\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unfavorite(Activity $activity)\n {\n $user = $this->request->user();\n\n $favorites = $activity->favoritedBy($user);\n\n if ($favorites && $favorites->isEmpty()) {\n return $this->response->errorNotFound('Favorite not found.');\n }\n\n $this->authorize('unfavorite', [$activity, $favorites]);\n\n // When you unfavorite an activity,\n // it should remove all the activities in it, including snippets.\n $isDeleted = $favorites->each(function ($favorite) {\n $favorite->forceDelete();\n });\n\n if ($isDeleted) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not remove favorite.');\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function notify(Activity $activity)\n {\n $this->authorize('notify', $activity);\n\n $user = $this->request->user();\n\n $existingNotification = $activity->availabilityNotifications()\n ->where('user_id', $user->id)\n ->exists();\n\n if ($existingNotification) {\n return $this->response->errorWrongArgs('Notification is already configured.');\n }\n\n $notification = Activity\\AvailabilityNotification::create([\n 'user_id' => $user->id,\n 'activity_id' => $activity->id,\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($notification, new AvailabilityNotificationTransformer());\n }\n\n /**\n * @param Activity $activity\n * @param Activity\\AvailabilityNotification $notification\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unnotify(Activity $activity, Activity\\AvailabilityNotification $notification)\n {\n $this->authorize('unnotify', [$activity, $notification]);\n\n if ($notification->sent_at || $notification->delete()) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not delete notification.');\n }\n\n public function play(Request $request, Activity $activity)\n {\n $this->authorize('stream', $activity);\n\n $request->validate([\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $activity->plays()->create([\n 'user_id' => $user->getId(),\n 'start_time' => $request->input('start_time'),\n ]);\n\n return $this->response->withCreated();\n }\n\n /**\n * @param Activity $activity\n *\n * @return mixed\n */\n public function comment(Activity $activity)\n {\n return $this->newComment($activity);\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @return mixed\n */\n public function replyComment(Activity $activity, Comment $comment)\n {\n return $this->newComment($activity, $comment);\n }\n\n /**\n * @param Activity $activity\n * @param Comment|null $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n protected function newComment(Activity $activity, ?Comment $comment = null)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n 'type' => 'integer|between:0,3',\n 'visibility' => sprintf('nullable|integer|between:1,%d', count(Comment::getVisibilityLevels())),\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n $threadStartId = null;\n if ($comment) {\n $threadStartId = $comment->thread_start_id ?: $comment->id;\n }\n\n try {\n $newComment = Comment::create([\n 'parent_comment_id' => $comment->id ?? null,\n 'thread_start_id' => $threadStartId,\n 'activity_id' => $activity->id,\n 'user_id' => $this->request->user()->id,\n 'comment' => trim($this->request->input('comment')),\n 'start_time' => $this->request->input('start_time', 0),\n 'end_time' => $this->request->input('end_time', 0),\n 'type' => $this->request->input('type', Comment::TYPE_NEUTRAL),\n 'visibility' => $this->request->input('visibility', Comment::VISIBILITY_PUBLIC),\n ]);\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($newComment, new ActivityCommentTransformer());\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not create comment.' . $exception->getMessage());\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function updateComment(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n try {\n $comment->update([\n 'comment' => trim($this->request->input('comment')),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment.');\n }\n }\n\n public function updateCommentVisibility(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'visibility' => sprintf('integer|between:1,%d', count(Comment::getVisibilityLevels())),\n ]);\n\n $visibility = $this->request->input('visibility');\n\n if ($comment->parent !== null) {\n return $this->response->errorWrongArgs('Comment visibility can only be updated on top level comments.');\n }\n\n try {\n $this->activityCommentService->updateCommentVisibility($comment, $visibility);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment\\'s visibility.');\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function deleteComment(Activity $activity, Comment $comment)\n {\n $this->authorize('deleteComment', [$activity, $comment]);\n\n // Delete comment and any children.\n $comment->delete();\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function fetchComments()\n {\n $user = $this->request->user();\n $this->request->validate([\n 'forUserId' => 'uuid:users,team_id,' . $user->team_id,\n 'types' => 'array',\n 'types.*' => 'integer|between:0,3',\n ]);\n $forUser = null;\n\n $types = [Comment::TYPE_NEUTRAL, Comment::TYPE_GAME_CHANGER, Comment::TYPE_POSITIVE];\n $user = $this->request->user();\n if ($this->request->has('forUserId')) {\n $forUser = $user->team->users()->uuid($this->request->input('forUserId'));\n }\n\n $comments = Comment::query()\n ->whereHas('activity', static function (Builder $builder) use ($user, $forUser): void {\n $builder\n // I left feedback on my own activity; or\n ->where('activities.user_id', $user->getId());\n if ($forUser) {\n // I left feedback on any activity for this user.\n $builder->orWhere([\n 'user_id' => $user->getId(),\n 'activities.user_id' => $forUser->getId(),\n ]);\n }\n })\n ->whereIn('type', $this->request->input('types', $types))\n ->orderBy('created_at', 'desc')\n ->get();\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity', 'user'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($comments, new ActivityCommentTransformer());\n }\n\n public function deleteCoachingFeedback(Activity $activity, CoachingFeedback $coachingFeedback)\n {\n $this->authorize('deleteCoachingFeedback', [$activity, $coachingFeedback]);\n $activity = $coachingFeedback->getActivity();\n\n if ($coachingFeedback->delete()) {\n event(new UpdateSingleEntity(\n entityId: $activity->getId(),\n updateTarget: UpdateTargetEnum::ACTIVITY,\n purpose: 'delete-coaching-feedback',\n ));\n\n return $this->response->withOk();\n }\n\n return $this->response->withError('Delete operation failed. Contact support.', 500);\n }\n\n /**\n * Add new or update Coaching feedback\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws \\Illuminate\\Validation\\ValidationException\n *\n * @return mixed\n */\n public function putCoachingFeedback(Request $request, Activity $activity)\n {\n $user = $request->user();\n\n if (! $user instanceof User) {\n abort(403);\n }\n $teamId = $user->getTeamId();\n\n $this->authorize('coach', $activity);\n\n $this->request->validate([\n 'coach_id' => 'required|uuid:users,team_id,' . $teamId,\n 'coachee_id' => 'required|uuid:users,team_id,' . $teamId,\n 'visibility' => ['required', Rule::in(CoachingFeedback::VISIBILITIES)],\n 'coaching_sections.*.uuid' => 'required|uuid:coaching_sections',\n 'coaching_sections.*.score' => ['required', Rule::in(CoachingSectionFeedback::SCORES)],\n 'coaching_sections.*.summary' => 'string|max:10000',\n 'coaching_sections.*.criteria.*.uuid' => 'required|uuid:coaching_section_criteria',\n 'coaching_sections.*.criteria.*.note' => 'required|string|max:10000',\n 'sharedWithUsers' => [\n 'required_if:visibility,' . CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS,\n 'array',\n ],\n 'sharedWithUsers.*' => [\n 'uuid:users,team_id,' . $teamId,\n ],\n ]);\n\n /** @var User $coach */\n $coach = User::uuid($this->request->input('coach_id'));\n /** @var User $coachee */\n $coachee = User::uuid($this->request->input('coachee_id'));\n $coachingSectionFeedbacks = $this->request->input('coaching_sections');\n\n $previousRecord = $this->coachingFeedbackRepository->getOneForActivityByCoacheeAndCoach(\n $coachee->getId(),\n $coach->getId(),\n $activity->getId()\n );\n $recordIsNew = false;\n if ($previousRecord === null) {\n $recordIsNew = true;\n }\n\n if (! $coachee->isSameTeamId($coach)) {\n return $this->response->errorForbidden('User not member of your team.');\n }\n\n if (! is_array($coachingSectionFeedbacks) || count($coachingSectionFeedbacks) < 1) {\n return $this->response->withError('At least one Coaching Framework Section shall be scored.', 422);\n }\n\n if (! $activity->participants()->where('participants.user_id', $coachee->id)->exists()) {\n return $this->response->withError('Coached user did not participate activity.', 422);\n }\n\n $visibility = $this->request->input('visibility');\n\n $shouldSendNotification = $recordIsNew;\n if ($recordIsNew === false && $visibility !== $previousRecord->getVisibility()) {\n $shouldSendNotification = true;\n }\n\n /**\n * Create CoachingFeedback\n *\n * @var CoachingFeedback $coachingFeedback\n */\n $coachingFeedback = $activity->coachingFeedbacks()->updateOrCreate(\n [\n 'coach_id' => $coach->id,\n 'coachee_id' => $coachee->id,\n ],\n [\n 'framework_id' => $activity->category->id,\n 'visibility' => $visibility,\n ]\n );\n\n $sharedUserIds = [];\n if ($visibility === CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS) {\n foreach ($this->request->input('sharedWithUsers') as $sharedWithUserUuid) {\n /** @var User $user */\n $user = User::uuid($sharedWithUserUuid);\n $sharedUserIds[] = $user->getId();\n }\n }\n\n $syncResult = $coachingFeedback->customAccessUsers()->sync($sharedUserIds);\n\n $scores = [];\n\n\n /**\n * Create CoachingSectionsFeedbacks.\n *\n * @var CoachingSectionFeedback $coachingSectionFeedback\n */\n foreach ($coachingSectionFeedbacks as $coachingSectionFeedbackInput) {\n $coachingSection = CoachingSection::uuid($coachingSectionFeedbackInput['uuid']);\n $coachingSectionFeedback = $coachingFeedback->sectionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_id' => $coachingSection->id,\n ],\n [\n 'score' => array_get($coachingSectionFeedbackInput, 'score'),\n 'summary' => array_get($coachingSectionFeedbackInput, 'summary') ?? '',\n ]\n );\n\n $scores[] = array_get($coachingSectionFeedbackInput, 'score');\n\n $criteria = array_get($coachingSectionFeedbackInput, 'criteria');\n if (is_array($criteria) && ! empty($criteria)) {\n foreach ($criteria as $criteriaFeedbackInput) {\n $coachingSectionFeedback->criterionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_criterion_id' => CoachingSectionCriterion::uuid(array_get($criteriaFeedbackInput, 'uuid'))\n ->id,\n ],\n ['note' => array_get($criteriaFeedbackInput, 'note')],\n );\n }\n }\n }\n\n $coachingFeedback->average_score = array_sum($scores) / count($scores);\n\n if ($recordIsNew === false && $coachingFeedback->getAverageScore() !== $previousRecord->getAverageScore()) {\n $shouldSendNotification = true;\n }\n if (! empty($syncResult['attached']) || ! empty($syncResult['detached']) || ! empty($syncResult['updated'])) {\n $shouldSendNotification = true;\n }\n\n $coachingFeedback->save();\n // ensure updated at for coaching feedback on section feedback summary added.\n $coachingFeedback->touch();\n\n if ($shouldSendNotification) {\n event(new Coached($coachingFeedback));\n }\n\n Datadog::increment('jiminny.activity.score.update', 1, ['company' => $activity->user->team->slug]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n $coachingFeedbackTransformer = new CoachingFeedbackTransformer();\n $coachingFeedbackTransformer->setConsumer($this->getUserFromRequest($request));\n\n return $this->response->withItem($coachingFeedback, $coachingFeedbackTransformer);\n }\n\n\n /**\n * Retrieve category criteria for coaching.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachingSections(Activity $activity)\n {\n $this->authorize('coach', $activity);\n\n if ($activity->category === null) {\n return $this->response->errorUnprocessable('Category has not yet been assigned.');\n }\n\n $criteria = $activity\n ->category\n ->coachingSections()\n ->where('is_enabled', 1)\n ->orderBy('sequence', 'asc');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($criteria->get(), new CoachingSectionsTransformer());\n }\n\n /**\n * @throws AuthorizationException\n * @throws ValidationException\n *\n * @return mixed\n */\n public function addToPlaylist(Activity $activity, PlaylistTrackFactoryInterface $playlistTrackFactory)\n {\n $this->request->validate([\n 'playlists' => 'required|array',\n 'playlists.*' => 'uuid:playlists',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'name' => 'required|max:100',\n ]);\n\n $this->authorize('addToPlaylist', [$activity, $this->request->input('playlists')]);\n\n $startTime = $this->request->input('start_time');\n $endTime = $this->request->input('end_time');\n $name = $this->request->input('name');\n /** @var User $user */\n $user = $this->request->user();\n\n // Get playlist by uuid.\n foreach ($this->request->input('playlists') as $playlistId) {\n // Pull out the playlist model.\n $playlist = Playlist::uuid($playlistId);\n\n $playlistTrackFactory->createTrack($playlist, $user, [\n 'name' => $name,\n 'activity' => $activity,\n 'start_time' => $startTime,\n 'end_time' => $endTime,\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function share(Request $request, Activity $activity): JsonResponse\n {\n $this->authorize('share', $activity);\n\n $request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'recipients.*.type' => 'in:user,group',\n 'recipients.*.id' => 'string|max:40',\n 'share' => 'string|max:255',\n ]);\n\n $user = $request->user();\n\n $recipients = $request->get('recipients');\n $users = $this->userService->convertRecipientsToUsers($user, $recipients);\n\n $shareData = [\n 'from_user_id' => $user->id,\n 'note' => $request->input('note'),\n 'start_time' => $request->input('start_time'),\n 'end_time' => $request->input('end_time'),\n ];\n\n // Create a share object against a notification provider channel\n if ($request->input('share')) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'notification_provider_channel' => $request->input('share'),\n ]\n )\n );\n\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n\n // Create a share object against each recipient\n foreach ($users as $recipient) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'to_user_id' => $recipient->id,\n ]\n )\n );\n\n // If parent_share_id has been selected yet\n if (! isset($shareData['parent_share_id'])) {\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachRequest(Activity $activity)\n {\n $this->authorize('coachRequest', $activity);\n\n $this->request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'coachers.*.type' => 'required|in:user',\n 'coachers.*.id' => 'required',\n ]);\n\n $coachers = $this->request->get('coachers');\n $user = $this->request->user();\n $users = $this->userService->convertRecipientsToUsers($user, $coachers);\n\n foreach ($users as $coacher) {\n CoachRequest::create([\n 'user_id' => $coacher->id,\n 'activity_id' => $activity->id,\n 'note' => $this->request->get('note'),\n 'start_time' => $this->request->get('start_time'),\n 'end_time' => $this->request->get('end_time'),\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function createActivityTopicTriggers(Activity $activity, LoggerInterface $logger): HttpFoundation\\JsonResponse\n {\n $this->authorize('analyzeTopicTriggers', $activity);\n\n if (! $activity->hasTranscription()) {\n return new HttpFoundation\\JsonResponse(\n [\n 'error' => 'Transcription not found.',\n ],\n JsonResponse::HTTP_NOT_FOUND\n );\n }\n\n $logger->info(__METHOD__ . ': queued for analysis', [\n 'activity' => $activity->id_string,\n ]);\n\n dispatch(new ActivityAnalytics\\Job\\AnalyzeActivityTopicTriggers($activity));\n\n return new HttpFoundation\\JsonResponse(null, JsonResponse::HTTP_CREATED);\n }\n\n public function fetchActivityTopicTriggers(\n Activity $activity,\n LoggerInterface $logger,\n ActivityTopicTriggerTransformer $transformer\n ): HttpFoundation\\JsonResponse {\n $this->authorize('fetchTopicTriggers', $activity);\n\n $logger->debug(__METHOD__, [\n 'activity' => $activity->id_string,\n ]);\n\n if (! $activity->isProcessed()) {\n return new HttpFoundation\\JsonResponse([]);\n }\n\n $payload = [];\n\n if ($activity->hasTopicTriggers()) {\n $payload = $activity->getTopicTriggersSorted()\n ->map(\n static fn (Activity\\TopicTrigger $activityTopicTrigger): array\n => $transformer->transform($activityTopicTrigger)\n )\n ->values()\n ->all();\n }\n\n return new HttpFoundation\\JsonResponse($payload);\n }\n\n /**\n * @param Activity $activity\n * @param StatsTransformer $statsTransformer\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function stats(Activity $activity, StatsTransformer $statsTransformer)\n {\n $this->authorize('stream', $activity);\n\n if (! $activity->hasTranscription()) {\n return $this->response->errorNotFound('Waveform data is not yet generated.');\n }\n\n $this->response\n ->getManager()\n ->parseIncludes(['wavedata'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($activity, $statsTransformer);\n }\n\n public function destroy(Activity $activity)\n {\n $this->authorize('delete', $activity);\n\n $activity->delete();\n\n \\Log::info('Soft delete activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n\n return $this->response->withNoContent();\n }\n\n public function note(Activity $activity)\n {\n $this->authorize('note', $activity);\n\n $this->request->validate([\n 'note' => 'required|min:1|max:2000',\n 'time' => 'required|numeric|min:0|max:86400',\n ]);\n\n $note = $this->request->input('note');\n $time = $this->request->input('time');\n\n $this->activityService->setActivity($activity);\n $this->activityService->takeNote($this->getUser(), $note, $time);\n\n return $this->response->withCreated();\n }\n\n /**\n * Mark an activity as private.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPrivate(Activity $activity)\n {\n $this->authorize('markAsPrivate', $activity);\n\n if ($activity->is_private === false) {\n $activity->is_private = true;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * Mark an activity as public.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPublic(Activity $activity)\n {\n $this->authorize('markAsPublic', $activity);\n\n if ($activity->is_private) {\n $activity->is_private = false;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws LogicException\n */\n public function fetchCloudFrontS3MediaKeys(Activity $activity, PlaybackService $playbackService): JsonResponse\n {\n $masterTrack = $activity->masterTrack()->first();\n\n if (! $masterTrack instanceof Track) {\n throw new LogicException(sprintf('Master track not found for activity \"%s\"', $activity->getUuid()));\n }\n\n return $this->response->withArray(\n $playbackService->generateCookies(\n $masterTrack,\n $this->request->ip(),\n ),\n );\n }\n\n /**\n * @throws ValidationException\n */\n private function updateOrCreateActivitySearch(Request $request, ?Search $search = null): Search\n {\n $request->validate([\n 'name' => 'required|string|min:2|max:100',\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $searchName = $request->input('name');\n\n if ($search !== null) {\n $search->update([\n 'name' => $searchName,\n ]);\n\n return $search;\n }\n\n $request->validate([\n 'filters' => ['required', 'array', new MultidimensionalArrayMaxCharRule(limit: 255)],\n 'nudges' => 'array|max:' . count(Nudge::MAP_CHANNEL),\n 'nudges.*.channel' => 'required|in:' . implode(',', Nudge::MAP_CHANNEL),\n 'nudges.*.frequency' => 'required|in:' . implode(',', Nudge::MAP_FREQUENCY),\n 'nudges.*.expiresAt' => [\n 'required',\n 'date',\n 'after:today',\n 'before_or_equal:' . now()->addYear()->format('Y-m-d'),\n ],\n ]);\n\n $searchCriteria = Criteria::createFromRequest(\n Collection::make($request->input('filters', []))->all(),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($searchCriteria, $user);\n $this->validateSearch($request, $filterSet, 'filters.');\n\n /** @var Search $search */\n $search = Search::create([\n 'name' => $searchName,\n 'uuid' => Uuid::uuid4()->toString(),\n 'user_id' => $user->getId(),\n ]);\n\n Collection::make($request->input('nudges', []))\n ->each(fn (array $attributes): Nudge => $this->nudgeFactory->createNudge($search, $attributes));\n\n $this->storeNamedSearchFilters(Collection::make($request->all()), $search, $filterSet, 'filters.');\n\n return $search;\n }\n\n private function resolveAccount(\n Team $team,\n Contact $contact,\n ServiceInterface $crmService,\n array $prospects,\n ): ?Account {\n $this->logger->info('Resolving account from contact');\n $account = $contact->getAccount();\n\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS)) {\n $this->logger->info('Team does not have feature to link activity to multiple prospects');\n\n return $account;\n }\n\n $this->logger->info('Resolving account from prospect data');\n $accountData = array_filter(\n $prospects,\n static fn (array $prospectData): bool => $prospectData['type'] === 'account'\n );\n\n if (! empty($accountData)) {\n $this->logger->info('Found account data in prospects');\n $accountData = reset($accountData);\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountData['id'])->first();\n\n if (! $account instanceof Account) {\n $this->logger->info('Account not found in database, syncing from CRM');\n $account = $crmService->syncAccount($accountData['id']);\n }\n }\n\n $this->logger->info('Resolved account', ['account' => $account->getId()]);\n\n return $account;\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.40957448,"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.41821808,"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.42918882,"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.43783244,"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.44647607,"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.4574468,"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.46841756,"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.4950133,"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.50598407,"top":0.09896249,"width":0.029587766,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"bounds":{"left":0.7084442,"top":0.09896249,"width":0.02825798,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"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":"40","depth":4,"bounds":{"left":0.67785907,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.69015956,"top":0.123703115,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"40","depth":4,"bounds":{"left":0.6994681,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"64","depth":4,"bounds":{"left":0.7117686,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.7237367,"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.73105055,"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 * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","depth":4,"on_screen":true,"value":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","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}]...
|
-7287184300264252456
|
-8385861013499833196
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use Carbon\Carbon;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\In;
use Illuminate\Validation\ValidationException;
use InvalidArgumentException;
use Jiminny\Component\ActivityAnalytics;
use Jiminny\Component\ActivitySearch;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Queue\Constants;
use Jiminny\Contracts\ES\Events\UpdateSingleEntity;
use Jiminny\Contracts\ES\UpdateTargetEnum;
use Jiminny\Contracts\Nudge\NudgeFactoryInterface;
use Jiminny\Contracts\Playlist\PlaylistTrackFactoryInterface;
use Jiminny\Contracts\Repositories\PlaylistActivityRepository;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Enums\TeamSetting;
use Jiminny\Events\Activities\AiAutomation\ActivityProspectAdded;
use Jiminny\Events\Activities\Coaching\Coached;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Controllers\CommentContextInterface;
use Jiminny\Http\Responses\Api\AbstractResponse;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\ActivityCommentTransformer;
use Jiminny\Http\Transformers\ActivityTopicTriggerTransformer;
use Jiminny\Http\Transformers\ActivityTransformer;
use Jiminny\Http\Transformers\AvailabilityNotificationTransformer;
use Jiminny\Http\Transformers\CoachingFeedbackTransformer;
use Jiminny\Http\Transformers\CoachingSectionsTransformer;
use Jiminny\Http\Transformers\SearchTransformer;
use Jiminny\Http\Transformers\StatsTransformer;
use Jiminny\Jobs\Crm\SaveActivity;
use Jiminny\Jobs\Crm\UpdateStage;
use Jiminny\Jobs\Telephony\StartRecording;
use Jiminny\Jobs\Telephony\StopRecording;
use Jiminny\Jobs\Telephony\ToggleRecording;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\CoachingFeedback;
use Jiminny\Models\CoachingSection;
use Jiminny\Models\CoachingSectionCriterion;
use Jiminny\Models\CoachingSectionFeedback;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\LanguageDialect;
use Jiminny\Models\Lead;
use Jiminny\Models\Nudge;
use Jiminny\Models\PlaybookCategory;
use Jiminny\Models\Playlist;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\Track;
use Jiminny\Models\User;
use Jiminny\Repositories\CoachingFeedbackRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Rules\CrmReference;
use Jiminny\Rules\MultidimensionalArrayMaxCharRule;
use Jiminny\Services\ActivityService;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Services\PlaybackService;
use Jiminny\Services\UserService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
use Ramsey\Uuid\Uuid;
use Sentry;
use Symfony\Component\HttpFoundation;
final class ActivityController extends Controller implements CommentContextInterface
{
// Number of minutes to look back on activities. i.e. a timeout on activity duration.
private const int LOOK_BACK = 180;
public function __construct(
private ProviderRegistry $providerRegistry,
private ActivityService $activityService,
Response $response,
private UserService $userService,
private ActivitySearch\Service\ActivitySearch $activitySearch,
private NudgeFactoryInterface $nudgeFactory,
private ActivityCommentService $activityCommentService,
private LoggerInterface $logger,
private readonly CoachingFeedbackRepository $coachingFeedbackRepository,
private readonly TeamRepository $teamRepository,
) {
parent::__construct($response);
}
public static function getCommentImplementation(): string
{
return Comment::class;
}
public function delete()
{
$this->request->validate([
'*' => 'uuid:activities',
]);
$deletedIds = [];
foreach ($this->request->all() as $activityId) {
$activity = Activity::idOrUuId($activityId);
try {
if ($this->authorize('delete', $activity)) {
$activity->delete();
$deletedIds[] = $activityId;
\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);
}
} catch (AuthorizationException $authorizationException) {
// They didn't have permission.
}
}
return $this->response->withArray($deletedIds);
}
public function update(Request $request, Activity $activity)
{
$this->authorize('updateMetadata', $activity);
$request->validate([
'title' => 'string|max:250',
'category_id' => 'uuid:playbook_categories',
'language' => [
new In(
LanguageDialect::query()
->with('language')
->cursor()
->map(static function (LanguageDialect $languageDialect): string {
return $languageDialect->getLanguageLocale();
})
->all()
),
],
]);
if ($request->has('title')) {
$activity->title = $request->input('title');
}
if ($request->has('category_id')) {
$category = PlaybookCategory::uuid($request->input('category_id'));
if ($category->playbook->team_id !== $request->user()->team_id) {
return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
if ($request->has('language')) {
if (! $activity->isInProgress()) {
return $this->response->withError(
'Activity language can only be set while the meeting is in progress.',
400
);
}
$activity->setLanguageCode($request->input('language'));
}
$activity->save();
return $this->response->withOk();
}
// XXX: This should be merged with the update method.
/**
* @param Activity $activity
*
* @throws AuthorizationException
* @throws SocialAccountTokenInvalidException
*
* @return mixed
*/
public function summarize(Activity $activity): mixed
{
$this->logger->info('[Log Activity] Summarizing activity ', [
'activityId' => $activity->getUuid(),
'payload' => $this->request->all(),
]);
$this->authorize('update', $activity);
$this->logger->info('[Log Activity] Validating summary');
// Validate the payload.
$this->validateSummary($activity);
// All objects must belong to this team.
/** @var User $user */
$user = $this->request->user();
$team = $user->getTeam();
$crmService = $this->providerRegistry->get($team->crm->provider);
try {
$crmUser = $user;
if ($user->isCrmRequired() === false) {
$crmUser = $team->owner;
}
$crmService->setUser($crmUser);
} catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());
}
$rawEntities = $this->request->input('entities');
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid(
$this->request->input('layout_id')
);
// Delay execution of CRM jobs to avoid locking issues.
$jobDelay = 0;
// If we have arrived from a notification, mark it as read.
$notificationId = $this->request->input('nId');
if ($notificationId) {
$notification = $user->unreadNotifications->where('id', $notificationId)->first();
if ($notification) {
$notification->markAsRead();
}
}
$title = $this->request->input('title');
$prospects = $this->request->input('prospects');
$opportunityId = $this->request->input('opportunity_id');
$stageId = $this->request->input('stage_id');
$categoryId = $this->request->input('category_id');
$summary = $this->request->input('summary');
$crmProviderId = $this->request->input('crm_id');
$isInternal = $this->request->input('is_internal') ?? false;
$lead = null;
$category = null;
$account = null;
$contact = null;
$opportunity = null;
$stage = null;
$callStage = null;
foreach ($prospects as $prospectData) {
$objectId = $prospectData['id'];
if ($objectId === null) {
continue;
}
$objectType = $prospectData['type'];
$this->logger->info('debug', ['prospect_data' => $prospectData]);
try {
if ($objectType === null) {
$this->logger->info('no object type');
if ($crmService instanceof SupportsObjectTypeParseInterface) {
$objectType = $crmService->parseObjectType($objectId);
}
}
switch ($objectType) {
case 'lead':
$this->logger->info('Processing lead');
/** @var Lead|null $lead */
$lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();
// Lead does not exist locally, import it.
if ($lead === null) {
$this->logger->info('Lead does not exist locally');
/** @var Lead $lead */
$lead = $crmService->syncLead($objectId);
}
$this->logger->info('Lead found', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
if ($stageId === null) {
$this->logger->info('Stage ID is null');
// If it was not provided, just assume it is the current stage.
$callStage = $lead->stage;
break;
}
$this->logger->info('Looking for stage');
// Determine if they have changed the stage.
/** @var Stage $stage */
$stage = $team->crm->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_LEAD)
->firstOrFail();
$this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);
if ($lead->stage_id && $lead->stage_id !== $stage->id) {
$this->logger->info('Stage has changed');
// Storage current stage on activity.
$callStage = $lead->stage;
// The stage has changed, update in remote CRM.
dispatch(new UpdateStage($activity, $lead, $callStage, $stage));
$this->logger->info(
sprintf(
'[%s] User changing lead stage from %s to %s',
$crmService->getDisplayName(),
$callStage->getName(),
$stage->getName()
),
[
'user' => $user->getUuid(),
'lead' => $lead->getUuid(),
]
);
} else {
$this->logger->info('Stage has not changed');
// Stage remains as current.
$callStage = $stage;
}
break;
case 'account':
$this->logger->info('Processing account');
// If the object is not a lead, it should be an account.
$account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();
// Account does not exist locally, import it.
if ($account === null) {
$this->logger->info('Account does not exist locally');
$account = $crmService->syncAccount($objectId);
}
$this->logger->info('Account found', ['accountId' => $account->id]);
break;
case 'contact':
$this->logger->info('processing contact');
$contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$this->logger->info('contact does not exist locally');
$contact = $crmService->syncContact($objectId);
}
$this->logger->info('resolving account');
$account = $this->resolveAccount($team, $contact, $crmService, $prospects);
break;
}
// If they have specified an opportunity, retrieve this with stage.
if ($opportunityId) {
$this->logger->info('opportunity id is set');
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if ($opportunity === null) {
$this->logger->info('opportunity does not exist locally');
$opportunity = $crmService->syncOpportunity($opportunityId);
}
if ($stageId === null) {
$this->logger->info('stage id is null');
// If it was not provided, just assume it is the current stage.
$callStage = $opportunity->stage ?? null;
} else {
$this->logger->info('looking for stage');
/** @var ?Stage $opportunityStage */
$opportunityStage = $team->crm
->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
// There is a chance we still cannot import this opportunity.
if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {
$this->logger->info('opportunity stage has changed');
// Storage current stage on activity.
$callStage = $opportunity->stage;
dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));
$this->logger->info(
sprintf(
'[%s] User changing opportunity stage from %s to %s',
$crmService->getDisplayName(),
$callStage->name,
$opportunityStage->name
),
[
'userId' => $user->id_string,
'opportunityId' => $opportunity->id_string,
]
);
} else {
$this->logger->info('opportunity stage has not changed');
// Stage remains as current.
$callStage = $opportunityStage;
}
}
}
if ($crmProviderId) {
// Cast $crmProviderId to string otherwise it won't use database index for some records
$linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();
// Check if this activity has already been assigned to a different activity.
if ($linkedActivity && $linkedActivity->id !== $activity->id) {
throw new InvalidArgumentException(
'Sorry, the linked task has already been logged under a different call. '
. 'Please choose another linked task.'
);
}
}
} catch (InvalidArgumentException $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($exception->getMessage());
} catch (Exception $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorInternalError(
'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'
);
}
}
if ($categoryId) {
$category = PlaybookCategory::uuid($categoryId);
if ($category->playbook->team_id !== $team->id) {
throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
$this->logger->info('Prospect data', [
'lead_id' => $lead?->getId(),
'account_id' => $account?->getId(),
'contact_id' => $contact?->getId(),
'opportunity_id' => $opportunity?->getId(),
'stage_id' => $stage?->getId(),
]);
if ($title) {
$activity->title = $title;
}
if ($summary) {
$activity->summary = $summary;
}
if ($crmProviderId) {
$activity->crm_provider_id = $crmProviderId;
}
if ($callStage) {
$this->logger->info('Setting stage id', ['stageId' => $callStage->id]);
$activity->stage_id = $callStage->id;
}
if ($lead) {
$this->logger->info('Setting lead id', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
// If we are changed from an account > lead, unset the account data.
$this->logger->info('Unsetting account id, opportunity id, contact id, value');
$activity->account_id = null;
$activity->opportunity_id = null;
$activity->contact_id = null;
$activity->value = null;
}
if ($account) {
$this->logger->info('Setting account id', ['accountId' => $account->id]);
$activity->account_id = $account->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('unsetting lead id');
$activity->lead_id = null;
// Unset the contact if switching different accounts. Will be set up below if still applicable.
if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {
$this->logger->info('Unsetting contact id');
$activity->contact_id = null;
}
}
if ($opportunity) {
$this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);
$this->logger->info('unsetting lead id');
$activity->opportunity_id = $opportunity->id;
$activity->value = $opportunity->value;
// If we are changed from an lead > account, unset the lead data.
$activity->lead_id = null;
}
if ($contact) {
$this->logger->info('setting contact id', ['contactId' => $contact->id]);
$activity->contact_id = $contact->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('Unsetting lead id');
$activity->lead_id = null;
}
$activity->is_internal = $isInternal;
$activity->save();
$activity->refresh();
$this->logger->notice('Activity saved', [
'activity_id' => $activity->getId(),
'lead_id' => $activity->lead_id,
'account_id' => $activity->account_id,
'contact_id' => $activity->contact_id,
'opportunity_id' => $activity->opportunity_id,
'stage_id' => $activity->stage_id,
'crm_provider_id' => $activity->getCrmProviderId(),
]);
// Store entities as field data on the activity.
$updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);
if ($activity->isLoggable()) {
// Follow-up Task or Event data.
$followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);
$this->logger->info('CRM LOG manual log triggered', [
'activityId' => $activity->getUuid(),
'followupData' => $followupData,
'userId' => $user->getUuid(),
]);
// Store data in the CRM.
// ++add check for crm_required
$job = new SaveActivity($activity, $followupData);
if ($updatedData) {
$job->delay(Carbon::now()->addMinutes($jobDelay));
}
dispatch($job);
// Manually dispatch log for Opportunity or Prospect added
if ($activity->hasOpportunity() || $activity->hasProspect()) {
event(new ActivityProspectAdded(
activity: $activity,
eventSource: 'manually-log-crm-data'
));
}
}
return $this->response->withOk();
}
/**
* Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.
*
* @param ServiceInterface $service
* @param Activity $activity
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array
{
$updatedData = [];
$existingData = $activity->data()->get();
// We need to delete any existing data to overwrite with latest values.
$activity->data()->delete();
$layoutEntities = $layout->entities()
->with('field', 'parent')
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->get();
/** @var LayoutEntity $entity */
foreach ($layoutEntities as $entity) {
// If the user has provided a value for this entity
if (array_key_exists($entity->id_string, $entities)) {
$value = $entities[$entity->id_string];
// Convert raw data into values that the CRM can consume.
if ($value) {
$value = $service->normalizeValue($entity->field->type, $value);
}
// Check the field is part of the activity-summary section.
if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {
// This is the internal database ID, not the external CRM ID.
$objectId = null;
switch ($entity->field->object_type) {
case Field::OBJECT_ACCOUNT:
$objectId = $activity->account_id;
break;
case Field::OBJECT_CONTACT:
$objectId = $activity->contact_id;
break;
case Field::OBJECT_OPPORTUNITY:
$objectId = $activity->opportunity_id;
break;
case Field::OBJECT_LEAD:
$objectId = $activity->lead_id;
break;
case Field::OBJECT_TASK:
case Field::OBJECT_EVENT:
$objectId = $activity->id;
break;
}
if ($objectId) {
/** @var FieldData $data */
$data = $activity->data()->create([
'crm_layout_entity_id' => $entity->id,
'crm_field_id' => $entity->crm_field_id,
'object_type' => $entity->field->object_type,
'object_id' => $objectId,
'value' => $value,
]);
// Never send read-only field data to the CRM.
if ($entity->read_only === false && $entity->is_visible) {
$existingValue = $existingData
->where('crm_layout_entity_id', $entity->id)
->where('crm_field_id', $entity->crm_field_id)
->where('object_type', $entity->field->object_type)
->where('object_id', $objectId)
->first();
// If the field was actually changed, we need to reflect this in the CRM too.
if ($existingValue === null || $existingValue->value !== $value) {
$updatedData[] = $data->id;
}
}
}
}
}
}
return $updatedData;
}
/**
* Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.
*
* @param ServiceInterface $crmService
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array
{
$fieldData = [];
foreach ($entities as $entityId => $value) {
// Only bother with fields that have a value.
if ($value) {
// Extract the entity from the UUID. Check the field is valid and part of the follow-up section.
$entity = $layout->entities()
->uuid($entityId, false)
->whereHas('parent', function ($query) {
$query->where('label', 'follow-up');
})
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->first();
if ($entity) {
// Convert raw data into values that the CRM can consume.
$value = $crmService->normalizeValue($entity->field->type, $value);
// Add the field and value to the payload.
$fieldData += [
$entity->field->crm_provider_id => $value,
];
}
}
}
return $fieldData;
}
/**
* @param Activity $activity
*/
private function validateSummary(Activity $activity): void
{
$team = $activity->user->team;
$crmProvider = $team->crm->provider;
$attributes = [];
$rules = [
'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,
'title' => 'string|max:250',
'prospects' => 'required|array',
'opportunity_id' => new CrmReference($crmProvider),
'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',
'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator
'summary' => 'max:50000',
'nId' => 'exists:notifications,id',
'crm_id' => new CrmReference($crmProvider),
'entities' => 'array',
'is_internal' => 'boolean',
];
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));
// Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.
$entities = $layout->entities()
->where('read_only', 0)
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->whereHas('parent', function ($query) use ($activity) {
if ($activity->isLoggable() === false) {
$query->where('label', '<>', 'follow-up');
}
});
$isInternal = $this->request->input('is_internal', false);
foreach ($entities->get() as $entity) {
$rules += $this->buildFieldValidator($entity, $isInternal);
$attributes += $this->buildFieldMessage($entity);
}
$this->request->validate($rules, [], $attributes);
}
private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array
{
return [
'entities.' . $entity->id_string => $entity->getValidator($isInternal),
];
}
/**
* @param LayoutEntity $entity
*
* @return array
*/
private function buildFieldMessage(LayoutEntity $entity): array
{
$label = $entity->label;
if ($label === null) {
$label = $entity->field->label;
}
return [
'entities.' . $entity->id_string => $label,
];
}
public function search(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->debugLog(
$user,
'User extracted from request',
['user' => $user->getId(), 'tz' => $user->getTimezone()]
);
$searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());
$this->debugLog(
$user,
'ActivitySearch criteria built',
['searchCriteria' => $searchCriteria]
);
$filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);
$this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);
$this->validateSearch($request, $filterSet);
$this->debugLog($user, 'Request validated');
$searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);
/** @var Collection<Activity> $activities */
$activities = $searchResponse['results'];
$this->debugLog($user, 'Activities ES response extracted');
$hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(
$user->getTeamId(),
TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),
);
if ($hideInternalMeetingsSetting?->getValue() === '1') {
$activities = $activities->filter(function (Activity $activity) {
if ($activity->is_internal && empty($activity->actual_start_time)) {
return false;
}
return true;
});
}
$this->debugLog($user, 'Internal meetings (?!) filtered');
$this->response->getManager()
->parseIncludes([
'category',
'organizer.group',
'prospect',
'stage',
'opportunity',
'stats',
'scorecards',
'masterTrack',
'activeParticipants',
'notification',
])
->setSerializer(new JsonSerializer());
$transformerExcludes = $this->request->input('exclude');
if ($transformerExcludes) {
$this->response->getManager()->parseExcludes($transformerExcludes);
}
$this->debugLog($user, 'Response Manager (?!) applied');
$transformer = new ActivityTransformer();
$transformer->setConsumer($user);
$this->debugLog($user, 'Activity Transformer added');
$resource = new \League\Fractal\Resource\Collection($activities, $transformer);
$page = $searchCriteria->getPageNumber();
$this->debugLog($user, 'Search criteria page number called', ['page' => $page]);
$histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');
$this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);
return $this->response->withArray([
'pagination' => [
'total' => $searchResponse['totalHits'],
'current' => $page,
'prev' => max($page - 1, 1),
'next' => $page + 1,
],
'results' => $this->response->getManager()->createData($resource)->toArray(),
'histogram' => $histogram,
]);
}
private function debugLog(User $user, string $logMessage, ?array $context = []): void
{
// Debug for Learning People Only
if ($user->getTeamId() !== 260) {
return;
}
Log::notice(
sprintf('[activity-search-controller] %s', $logMessage),
$context
);
}
/** @throws ValidationException */
private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void
{
$rules = [
'exclude' => 'array',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
];
if ($prefix !== null && mb_strpos($prefix, '.') !== false) {
$rules[rtrim($prefix, '.')] = sprintf(
'required|array|max:%d',
$filterSet->count()
);
}
$validationRules = $filterSet->getValidationRules($prefix)
->merge($rules)
->all();
$request->validate($validationRules);
}
public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$search = $this->updateOrCreateActivitySearch($request);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function updateActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('update', $search);
$this->updateOrCreateActivitySearch($request, $search);
return $this->response->withOk();
}
private function storeNamedSearchFilters(
Collection $request,
Search $search,
FilterDefinitionCollection $filterSet,
?string $prefix = null,
): self {
$arrayTypeProperties = $filterSet
->getPropertyTypes([
FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,
])
->all();
$supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);
foreach ($supportedRequestProperties as $requestPropertyName) {
if (! array_has($request, $requestPropertyName)) {
continue;
}
/** @var string|string[] $propertyValue */
$propertyValue = array_get($request, $requestPropertyName);
$propertyName = $prefix === null
? $requestPropertyName
: mb_substr($requestPropertyName, mb_strlen($prefix));
$isArrayType = array_has($arrayTypeProperties, $propertyName);
if (! $isArrayType) {
/** @var string $requestPropertyValue */
$search->filters()->updateOrCreate(
[
'filter' => $propertyName,
],
[
'value' => $propertyValue,
]
);
continue;
}
/** @var string[] $requestPropertyValue */
/** @var SearchFilter[]|Collection $existingFilterValues */
$existingFilterValuesKeyed = $search->filters()
->where('filter', $propertyName)
->get()
->keyBy('id');
// Iterate over values provided as request parameters
foreach ($propertyValue as $value) {
/** @var SearchFilter|null $valueFilter */
$valueFilter = $search->filters()
->where(
[
'filter' => $propertyName,
'value' => $value,
]
)
->first();
if ($valueFilter !== null) {
// Remove filter value pair from list to be deleted
$existingFilterValuesKeyed->forget($valueFilter->id);
} else {
// Add new filter/value pair
$search->filters()->updateOrCreate([
'filter' => $propertyName,
'value' => $value,
]);
}
}
// Delete filter value pairs for this filter that no longer exist in request parameters
foreach ($existingFilterValuesKeyed as $existingFilter) {
$existingFilter->delete();
}
}
/** @var Collection<int, SearchFilter> $filtersKeyed */
$filtersKeyed = $search->filters()->get()->keyBy('filter');
// wipe removed filters from this search
foreach ($filtersKeyed as $filterName => $filter) {
if (array_has($request, $prefix . $filterName)) {
continue;
}
// Remove all filter values for this filter
$search->filters()->where('filter', $filterName)->delete();
}
return $this;
}
/**
* @throws AuthorizationException
*/
public function fetchActivitySearch(
Search $search,
Request $request,
SearchTransformer $searchTransformer,
): JsonResponse {
$this->authorize('view', $search);
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withCollection(
$user->searches()->get(),
$searchTransformer
->withConsumer($user)
);
}
/**
* Deletes a saved search
*
* @param Request $request
* @param Search $search
*
* @throws Exception
*
* @return JsonResponse
*/
public function deleteActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('delete', $search);
// Orphan any AutomatedReports that use this search
$search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);
// Delete filters and the search itself
$search->filters()->delete();
$search->delete();
return $this->response->withOk();
}
public function live(Request $request, ElasticActivityRepository $repository): JsonResponse
{
$user = $this->getUserFromRequest($request);
$this->request->validate([
'sort_direction' => 'in:asc,desc',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
]);
$activities = $repository->getLiveCoachingEligibleActivities(
user: $user,
lookBackMinutes: self::LOOK_BACK,
limit: (int) $this->request->input('limit', 25),
page: (int) $this->request->input('page', 1),
sortBy: ['actual_start_time', 'scheduled_start_time'],
sortDirection: (string) $this->request->input('sort_direction', 'asc'),
);
$this->response
->getManager()
->parseIncludes(['organizer.group', 'prospect'])
->setSerializer(new JsonSerializer());
return $this->response->withCollection($activities, new ActivityTransformer());
}
/**
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function show(Activity $activity, ActivityService $activityService): JsonResponse
{
$this->authorize('show', $activity);
$user = $activity->getUser();
$team = $user->getTeam();
// Sync the opportunity with the latest data if possible.
if ($activity->opportunity_id) {
try {
$crmService = $this->providerRegistry->get($team->crm->provider);
if (! $user->isCrmRequired()) {
$crmService->setUser($team->getOwner());
} else {
$crmService->setUser($user);
}
$crmService->syncOpportunity($activity->opportunity->crm_provider_id);
} catch (Exception $exception) {
// Move on.
}
}
$activityData = $activityService->getActivityData($this->request->user(), $activity);
return response()->json($activityData);
}
public function createRecording(Activity $activity)
{
$this->authorize('record', $activity);
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Tell Twilio to start recording this activity.
if ($activity->recording_state === Activity::RECORDING_OFF) {
$job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withCreated();
}
return $this->response->errorGone('Activity is already recording.');
}
public function updateRecording(Request $request, Activity $activity)
{
$this->authorize('record', $activity);
$request->validate([
'preference' => 'boolean',
'state' => [
'string',
Rule::in([
Activity::RECORDING_IN_PROGRESS,
Activity::RECORDING_PAUSED,
]),
],
]);
if ($request->has('state')) {
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Toggle the recording state between paused and resumed.
if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {
$job = (new ToggleRecording($activity, $request->input('state')))
->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Recording is not toggleable.');
}
if ($request->has('preference')) {
$activity->update([
'recording_preference' => $request->input('preference') ? 1 : 0,
]);
return $this->response->withOk();
}
return $this->response->errorWrongArgs('Something went wrong');
}
public function stopRecording(Activity $activity)
{
$this->authorize('stopRecord', $activity);
// Tell Twilio to stop recording this activity.
if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {
$job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Activity is not recording.');
}
/**
* Add activity to this user's favorites playlist
*
* @throws AuthorizationException
*/
public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse
{
$this->authorize('favorite', $activity);
$user = $this->getUserFromRequest($this->request);
$favorite = $activity->wasFavoritedBy($user);
$name = $activity->activity_title ?? '';
// It needs to check at least one record.
if (! $favorite) {
$favoritePlaylist = $user->favoritePlaylist();
$playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(
$activity,
$user,
$favoritePlaylist
);
if ($playlistActivity !== null) {
$playlistActivity->update(
// Just update, don't sort.
['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],
);
} else {
$playlistActivity = $activity->playlistActivities()->create([
'playlist_id' => $favoritePlaylist->getId(),
'user_id' => $user->getId(),
'start_time' => 0,
'name' => mb_strimwidth($name, 0, 100),
]);
// Sort it on top.
$playlistActivity->update(
[
'sort' => $playlistActivityRepository->calculateNewSortOrder(
null,
$playlistActivity,
),
],
);
}
$playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);
return new JsonResponse([], JsonResponse::HTTP_CREATED);
}
return new JsonResponse(
[
'error' => [
'code' => AbstractResponse::CODE_CONFLICT,
'http_code' => JsonResponse::HTTP_CONFLICT,
'message' => 'Resource Already Exists',
],
],
JsonResponse::HTTP_CONFLICT,
);
}
/**
* Remove activity from this user's favorites playlist
*
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function unfavorite(Activity $activity)
{
$user = $t...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
32867
|
NULL
|
0
|
2026-05-13T09:42:43.897490+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665363897_m1.jpg...
|
PhpStorm
|
faVsco.js – ActivityController.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use Carbon\Carbon;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\In;
use Illuminate\Validation\ValidationException;
use InvalidArgumentException;
use Jiminny\Component\ActivityAnalytics;
use Jiminny\Component\ActivitySearch;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Queue\Constants;
use Jiminny\Contracts\ES\Events\UpdateSingleEntity;
use Jiminny\Contracts\ES\UpdateTargetEnum;
use Jiminny\Contracts\Nudge\NudgeFactoryInterface;
use Jiminny\Contracts\Playlist\PlaylistTrackFactoryInterface;
use Jiminny\Contracts\Repositories\PlaylistActivityRepository;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Enums\TeamSetting;
use Jiminny\Events\Activities\AiAutomation\ActivityProspectAdded;
use Jiminny\Events\Activities\Coaching\Coached;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Controllers\CommentContextInterface;
use Jiminny\Http\Responses\Api\AbstractResponse;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\ActivityCommentTransformer;
use Jiminny\Http\Transformers\ActivityTopicTriggerTransformer;
use Jiminny\Http\Transformers\ActivityTransformer;
use Jiminny\Http\Transformers\AvailabilityNotificationTransformer;
use Jiminny\Http\Transformers\CoachingFeedbackTransformer;
use Jiminny\Http\Transformers\CoachingSectionsTransformer;
use Jiminny\Http\Transformers\SearchTransformer;
use Jiminny\Http\Transformers\StatsTransformer;
use Jiminny\Jobs\Crm\SaveActivity;
use Jiminny\Jobs\Crm\UpdateStage;
use Jiminny\Jobs\Telephony\StartRecording;
use Jiminny\Jobs\Telephony\StopRecording;
use Jiminny\Jobs\Telephony\ToggleRecording;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\CoachingFeedback;
use Jiminny\Models\CoachingSection;
use Jiminny\Models\CoachingSectionCriterion;
use Jiminny\Models\CoachingSectionFeedback;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\LanguageDialect;
use Jiminny\Models\Lead;
use Jiminny\Models\Nudge;
use Jiminny\Models\PlaybookCategory;
use Jiminny\Models\Playlist;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\Track;
use Jiminny\Models\User;
use Jiminny\Repositories\CoachingFeedbackRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Rules\CrmReference;
use Jiminny\Rules\MultidimensionalArrayMaxCharRule;
use Jiminny\Services\ActivityService;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Services\PlaybackService;
use Jiminny\Services\UserService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
use Ramsey\Uuid\Uuid;
use Sentry;
use Symfony\Component\HttpFoundation;
final class ActivityController extends Controller implements CommentContextInterface
{
// Number of minutes to look back on activities. i.e. a timeout on activity duration.
private const int LOOK_BACK = 180;
public function __construct(
private ProviderRegistry $providerRegistry,
private ActivityService $activityService,
Response $response,
private UserService $userService,
private ActivitySearch\Service\ActivitySearch $activitySearch,
private NudgeFactoryInterface $nudgeFactory,
private ActivityCommentService $activityCommentService,
private LoggerInterface $logger,
private readonly CoachingFeedbackRepository $coachingFeedbackRepository,
private readonly TeamRepository $teamRepository,
) {
parent::__construct($response);
}
public static function getCommentImplementation(): string
{
return Comment::class;
}
public function delete()
{
$this->request->validate([
'*' => 'uuid:activities',
]);
$deletedIds = [];
foreach ($this->request->all() as $activityId) {
$activity = Activity::idOrUuId($activityId);
try {
if ($this->authorize('delete', $activity)) {
$activity->delete();
$deletedIds[] = $activityId;
\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);
}
} catch (AuthorizationException $authorizationException) {
// They didn't have permission.
}
}
return $this->response->withArray($deletedIds);
}
public function update(Request $request, Activity $activity)
{
$this->authorize('updateMetadata', $activity);
$request->validate([
'title' => 'string|max:250',
'category_id' => 'uuid:playbook_categories',
'language' => [
new In(
LanguageDialect::query()
->with('language')
->cursor()
->map(static function (LanguageDialect $languageDialect): string {
return $languageDialect->getLanguageLocale();
})
->all()
),
],
]);
if ($request->has('title')) {
$activity->title = $request->input('title');
}
if ($request->has('category_id')) {
$category = PlaybookCategory::uuid($request->input('category_id'));
if ($category->playbook->team_id !== $request->user()->team_id) {
return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
if ($request->has('language')) {
if (! $activity->isInProgress()) {
return $this->response->withError(
'Activity language can only be set while the meeting is in progress.',
400
);
}
$activity->setLanguageCode($request->input('language'));
}
$activity->save();
return $this->response->withOk();
}
// XXX: This should be merged with the update method.
/**
* @param Activity $activity
*
* @throws AuthorizationException
* @throws SocialAccountTokenInvalidException
*
* @return mixed
*/
public function summarize(Activity $activity): mixed
{
$this->logger->info('[Log Activity] Summarizing activity ', [
'activityId' => $activity->getUuid(),
'payload' => $this->request->all(),
]);
$this->authorize('update', $activity);
$this->logger->info('[Log Activity] Validating summary');
// Validate the payload.
$this->validateSummary($activity);
// All objects must belong to this team.
/** @var User $user */
$user = $this->request->user();
$team = $user->getTeam();
$crmService = $this->providerRegistry->get($team->crm->provider);
try {
$crmUser = $user;
if ($user->isCrmRequired() === false) {
$crmUser = $team->owner;
}
$crmService->setUser($crmUser);
} catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());
}
$rawEntities = $this->request->input('entities');
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid(
$this->request->input('layout_id')
);
// Delay execution of CRM jobs to avoid locking issues.
$jobDelay = 0;
// If we have arrived from a notification, mark it as read.
$notificationId = $this->request->input('nId');
if ($notificationId) {
$notification = $user->unreadNotifications->where('id', $notificationId)->first();
if ($notification) {
$notification->markAsRead();
}
}
$title = $this->request->input('title');
$prospects = $this->request->input('prospects');
$opportunityId = $this->request->input('opportunity_id');
$stageId = $this->request->input('stage_id');
$categoryId = $this->request->input('category_id');
$summary = $this->request->input('summary');
$crmProviderId = $this->request->input('crm_id');
$isInternal = $this->request->input('is_internal') ?? false;
$lead = null;
$category = null;
$account = null;
$contact = null;
$opportunity = null;
$stage = null;
$callStage = null;
foreach ($prospects as $prospectData) {
$objectId = $prospectData['id'];
if ($objectId === null) {
continue;
}
$objectType = $prospectData['type'];
$this->logger->info('debug', ['prospect_data' => $prospectData]);
try {
if ($objectType === null) {
$this->logger->info('no object type');
if ($crmService instanceof SupportsObjectTypeParseInterface) {
$objectType = $crmService->parseObjectType($objectId);
}
}
switch ($objectType) {
case 'lead':
$this->logger->info('Processing lead');
/** @var Lead|null $lead */
$lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();
// Lead does not exist locally, import it.
if ($lead === null) {
$this->logger->info('Lead does not exist locally');
/** @var Lead $lead */
$lead = $crmService->syncLead($objectId);
}
$this->logger->info('Lead found', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
if ($stageId === null) {
$this->logger->info('Stage ID is null');
// If it was not provided, just assume it is the current stage.
$callStage = $lead->stage;
break;
}
$this->logger->info('Looking for stage');
// Determine if they have changed the stage.
/** @var Stage $stage */
$stage = $team->crm->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_LEAD)
->firstOrFail();
$this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);
if ($lead->stage_id && $lead->stage_id !== $stage->id) {
$this->logger->info('Stage has changed');
// Storage current stage on activity.
$callStage = $lead->stage;
// The stage has changed, update in remote CRM.
dispatch(new UpdateStage($activity, $lead, $callStage, $stage));
$this->logger->info(
sprintf(
'[%s] User changing lead stage from %s to %s',
$crmService->getDisplayName(),
$callStage->getName(),
$stage->getName()
),
[
'user' => $user->getUuid(),
'lead' => $lead->getUuid(),
]
);
} else {
$this->logger->info('Stage has not changed');
// Stage remains as current.
$callStage = $stage;
}
break;
case 'account':
$this->logger->info('Processing account');
// If the object is not a lead, it should be an account.
$account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();
// Account does not exist locally, import it.
if ($account === null) {
$this->logger->info('Account does not exist locally');
$account = $crmService->syncAccount($objectId);
}
$this->logger->info('Account found', ['accountId' => $account->id]);
break;
case 'contact':
$this->logger->info('processing contact');
$contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$this->logger->info('contact does not exist locally');
$contact = $crmService->syncContact($objectId);
}
$this->logger->info('resolving account');
$account = $this->resolveAccount($team, $contact, $crmService, $prospects);
break;
}
// If they have specified an opportunity, retrieve this with stage.
if ($opportunityId) {
$this->logger->info('opportunity id is set');
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if ($opportunity === null) {
$this->logger->info('opportunity does not exist locally');
$opportunity = $crmService->syncOpportunity($opportunityId);
}
if ($stageId === null) {
$this->logger->info('stage id is null');
// If it was not provided, just assume it is the current stage.
$callStage = $opportunity->stage ?? null;
} else {
$this->logger->info('looking for stage');
/** @var ?Stage $opportunityStage */
$opportunityStage = $team->crm
->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
// There is a chance we still cannot import this opportunity.
if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {
$this->logger->info('opportunity stage has changed');
// Storage current stage on activity.
$callStage = $opportunity->stage;
dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));
$this->logger->info(
sprintf(
'[%s] User changing opportunity stage from %s to %s',
$crmService->getDisplayName(),
$callStage->name,
$opportunityStage->name
),
[
'userId' => $user->id_string,
'opportunityId' => $opportunity->id_string,
]
);
} else {
$this->logger->info('opportunity stage has not changed');
// Stage remains as current.
$callStage = $opportunityStage;
}
}
}
if ($crmProviderId) {
// Cast $crmProviderId to string otherwise it won't use database index for some records
$linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();
// Check if this activity has already been assigned to a different activity.
if ($linkedActivity && $linkedActivity->id !== $activity->id) {
throw new InvalidArgumentException(
'Sorry, the linked task has already been logged under a different call. '
. 'Please choose another linked task.'
);
}
}
} catch (InvalidArgumentException $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($exception->getMessage());
} catch (Exception $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorInternalError(
'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'
);
}
}
if ($categoryId) {
$category = PlaybookCategory::uuid($categoryId);
if ($category->playbook->team_id !== $team->id) {
throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
$this->logger->info('Prospect data', [
'lead_id' => $lead?->getId(),
'account_id' => $account?->getId(),
'contact_id' => $contact?->getId(),
'opportunity_id' => $opportunity?->getId(),
'stage_id' => $stage?->getId(),
]);
if ($title) {
$activity->title = $title;
}
if ($summary) {
$activity->summary = $summary;
}
if ($crmProviderId) {
$activity->crm_provider_id = $crmProviderId;
}
if ($callStage) {
$this->logger->info('Setting stage id', ['stageId' => $callStage->id]);
$activity->stage_id = $callStage->id;
}
if ($lead) {
$this->logger->info('Setting lead id', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
// If we are changed from an account > lead, unset the account data.
$this->logger->info('Unsetting account id, opportunity id, contact id, value');
$activity->account_id = null;
$activity->opportunity_id = null;
$activity->contact_id = null;
$activity->value = null;
}
if ($account) {
$this->logger->info('Setting account id', ['accountId' => $account->id]);
$activity->account_id = $account->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('unsetting lead id');
$activity->lead_id = null;
// Unset the contact if switching different accounts. Will be set up below if still applicable.
if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {
$this->logger->info('Unsetting contact id');
$activity->contact_id = null;
}
}
if ($opportunity) {
$this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);
$this->logger->info('unsetting lead id');
$activity->opportunity_id = $opportunity->id;
$activity->value = $opportunity->value;
// If we are changed from an lead > account, unset the lead data.
$activity->lead_id = null;
}
if ($contact) {
$this->logger->info('setting contact id', ['contactId' => $contact->id]);
$activity->contact_id = $contact->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('Unsetting lead id');
$activity->lead_id = null;
}
$activity->is_internal = $isInternal;
$activity->save();
$activity->refresh();
$this->logger->notice('Activity saved', [
'activity_id' => $activity->getId(),
'lead_id' => $activity->lead_id,
'account_id' => $activity->account_id,
'contact_id' => $activity->contact_id,
'opportunity_id' => $activity->opportunity_id,
'stage_id' => $activity->stage_id,
'crm_provider_id' => $activity->getCrmProviderId(),
]);
// Store entities as field data on the activity.
$updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);
if ($activity->isLoggable()) {
// Follow-up Task or Event data.
$followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);
$this->logger->info('CRM LOG manual log triggered', [
'activityId' => $activity->getUuid(),
'followupData' => $followupData,
'userId' => $user->getUuid(),
]);
// Store data in the CRM.
// ++add check for crm_required
$job = new SaveActivity($activity, $followupData);
if ($updatedData) {
$job->delay(Carbon::now()->addMinutes($jobDelay));
}
dispatch($job);
// Manually dispatch log for Opportunity or Prospect added
if ($activity->hasOpportunity() || $activity->hasProspect()) {
event(new ActivityProspectAdded(
activity: $activity,
eventSource: 'manually-log-crm-data'
));
}
}
return $this->response->withOk();
}
/**
* Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.
*
* @param ServiceInterface $service
* @param Activity $activity
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array
{
$updatedData = [];
$existingData = $activity->data()->get();
// We need to delete any existing data to overwrite with latest values.
$activity->data()->delete();
$layoutEntities = $layout->entities()
->with('field', 'parent')
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->get();
/** @var LayoutEntity $entity */
foreach ($layoutEntities as $entity) {
// If the user has provided a value for this entity
if (array_key_exists($entity->id_string, $entities)) {
$value = $entities[$entity->id_string];
// Convert raw data into values that the CRM can consume.
if ($value) {
$value = $service->normalizeValue($entity->field->type, $value);
}
// Check the field is part of the activity-summary section.
if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {
// This is the internal database ID, not the external CRM ID.
$objectId = null;
switch ($entity->field->object_type) {
case Field::OBJECT_ACCOUNT:
$objectId = $activity->account_id;
break;
case Field::OBJECT_CONTACT:
$objectId = $activity->contact_id;
break;
case Field::OBJECT_OPPORTUNITY:
$objectId = $activity->opportunity_id;
break;
case Field::OBJECT_LEAD:
$objectId = $activity->lead_id;
break;
case Field::OBJECT_TASK:
case Field::OBJECT_EVENT:
$objectId = $activity->id;
break;
}
if ($objectId) {
/** @var FieldData $data */
$data = $activity->data()->create([
'crm_layout_entity_id' => $entity->id,
'crm_field_id' => $entity->crm_field_id,
'object_type' => $entity->field->object_type,
'object_id' => $objectId,
'value' => $value,
]);
// Never send read-only field data to the CRM.
if ($entity->read_only === false && $entity->is_visible) {
$existingValue = $existingData
->where('crm_layout_entity_id', $entity->id)
->where('crm_field_id', $entity->crm_field_id)
->where('object_type', $entity->field->object_type)
->where('object_id', $objectId)
->first();
// If the field was actually changed, we need to reflect this in the CRM too.
if ($existingValue === null || $existingValue->value !== $value) {
$updatedData[] = $data->id;
}
}
}
}
}
}
return $updatedData;
}
/**
* Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.
*
* @param ServiceInterface $crmService
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array
{
$fieldData = [];
foreach ($entities as $entityId => $value) {
// Only bother with fields that have a value.
if ($value) {
// Extract the entity from the UUID. Check the field is valid and part of the follow-up section.
$entity = $layout->entities()
->uuid($entityId, false)
->whereHas('parent', function ($query) {
$query->where('label', 'follow-up');
})
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->first();
if ($entity) {
// Convert raw data into values that the CRM can consume.
$value = $crmService->normalizeValue($entity->field->type, $value);
// Add the field and value to the payload.
$fieldData += [
$entity->field->crm_provider_id => $value,
];
}
}
}
return $fieldData;
}
/**
* @param Activity $activity
*/
private function validateSummary(Activity $activity): void
{
$team = $activity->user->team;
$crmProvider = $team->crm->provider;
$attributes = [];
$rules = [
'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,
'title' => 'string|max:250',
'prospects' => 'required|array',
'opportunity_id' => new CrmReference($crmProvider),
'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',
'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator
'summary' => 'max:50000',
'nId' => 'exists:notifications,id',
'crm_id' => new CrmReference($crmProvider),
'entities' => 'array',
'is_internal' => 'boolean',
];
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));
// Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.
$entities = $layout->entities()
->where('read_only', 0)
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->whereHas('parent', function ($query) use ($activity) {
if ($activity->isLoggable() === false) {
$query->where('label', '<>', 'follow-up');
}
});
$isInternal = $this->request->input('is_internal', false);
foreach ($entities->get() as $entity) {
$rules += $this->buildFieldValidator($entity, $isInternal);
$attributes += $this->buildFieldMessage($entity);
}
$this->request->validate($rules, [], $attributes);
}
private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array
{
return [
'entities.' . $entity->id_string => $entity->getValidator($isInternal),
];
}
/**
* @param LayoutEntity $entity
*
* @return array
*/
private function buildFieldMessage(LayoutEntity $entity): array
{
$label = $entity->label;
if ($label === null) {
$label = $entity->field->label;
}
return [
'entities.' . $entity->id_string => $label,
];
}
public function search(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->debugLog(
$user,
'User extracted from request',
['user' => $user->getId(), 'tz' => $user->getTimezone()]
);
$searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());
$this->debugLog(
$user,
'ActivitySearch criteria built',
['searchCriteria' => $searchCriteria]
);
$filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);
$this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);
$this->validateSearch($request, $filterSet);
$this->debugLog($user, 'Request validated');
$searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);
/** @var Collection<Activity> $activities */
$activities = $searchResponse['results'];
$this->debugLog($user, 'Activities ES response extracted');
$hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(
$user->getTeamId(),
TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),
);
if ($hideInternalMeetingsSetting?->getValue() === '1') {
$activities = $activities->filter(function (Activity $activity) {
if ($activity->is_internal && empty($activity->actual_start_time)) {
return false;
}
return true;
});
}
$this->debugLog($user, 'Internal meetings (?!) filtered');
$this->response->getManager()
->parseIncludes([
'category',
'organizer.group',
'prospect',
'stage',
'opportunity',
'stats',
'scorecards',
'masterTrack',
'activeParticipants',
'notification',
])
->setSerializer(new JsonSerializer());
$transformerExcludes = $this->request->input('exclude');
if ($transformerExcludes) {
$this->response->getManager()->parseExcludes($transformerExcludes);
}
$this->debugLog($user, 'Response Manager (?!) applied');
$transformer = new ActivityTransformer();
$transformer->setConsumer($user);
$this->debugLog($user, 'Activity Transformer added');
$resource = new \League\Fractal\Resource\Collection($activities, $transformer);
$page = $searchCriteria->getPageNumber();
$this->debugLog($user, 'Search criteria page number called', ['page' => $page]);
$histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');
$this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);
return $this->response->withArray([
'pagination' => [
'total' => $searchResponse['totalHits'],
'current' => $page,
'prev' => max($page - 1, 1),
'next' => $page + 1,
],
'results' => $this->response->getManager()->createData($resource)->toArray(),
'histogram' => $histogram,
]);
}
private function debugLog(User $user, string $logMessage, ?array $context = []): void
{
// Debug for Learning People Only
if ($user->getTeamId() !== 260) {
return;
}
Log::notice(
sprintf('[activity-search-controller] %s', $logMessage),
$context
);
}
/** @throws ValidationException */
private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void
{
$rules = [
'exclude' => 'array',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
];
if ($prefix !== null && mb_strpos($prefix, '.') !== false) {
$rules[rtrim($prefix, '.')] = sprintf(
'required|array|max:%d',
$filterSet->count()
);
}
$validationRules = $filterSet->getValidationRules($prefix)
->merge($rules)
->all();
$request->validate($validationRules);
}
public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$search = $this->updateOrCreateActivitySearch($request);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function updateActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('update', $search);
$this->updateOrCreateActivitySearch($request, $search);
return $this->response->withOk();
}
private function storeNamedSearchFilters(
Collection $request,
Search $search,
FilterDefinitionCollection $filterSet,
?string $prefix = null,
): self {
$arrayTypeProperties = $filterSet
->getPropertyTypes([
FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,
])
->all();
$supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);
foreach ($supportedRequestProperties as $requestPropertyName) {
if (! array_has($request, $requestPropertyName)) {
continue;
}
/** @var string|string[] $propertyValue */
$propertyValue = array_get($request, $requestPropertyName);
$propertyName = $prefix === null
? $requestPropertyName
: mb_substr($requestPropertyName, mb_strlen($prefix));
$isArrayType = array_has($arrayTypeProperties, $propertyName);
if (! $isArrayType) {
/** @var string $requestPropertyValue */
$search->filters()->updateOrCreate(
[
'filter' => $propertyName,
],
[
'value' => $propertyValue,
]
);
continue;
}
/** @var string[] $requestPropertyValue */
/** @var SearchFilter[]|Collection $existingFilterValues */
$existingFilterValuesKeyed = $search->filters()
->where('filter', $propertyName)
->get()
->keyBy('id');
// Iterate over values provided as request parameters
foreach ($propertyValue as $value) {
/** @var SearchFilter|null $valueFilter */
$valueFilter = $search->filters()
->where(
[
'filter' => $propertyName,
'value' => $value,
]
)
->first();
if ($valueFilter !== null) {
// Remove filter value pair from list to be deleted
$existingFilterValuesKeyed->forget($valueFilter->id);
} else {
// Add new filter/value pair
$search->filters()->updateOrCreate([
'filter' => $propertyName,
'value' => $value,
]);
}
}
// Delete filter value pairs for this filter that no longer exist in request parameters
foreach ($existingFilterValuesKeyed as $existingFilter) {
$existingFilter->delete();
}
}
/** @var Collection<int, SearchFilter> $filtersKeyed */
$filtersKeyed = $search->filters()->get()->keyBy('filter');
// wipe removed filters from this search
foreach ($filtersKeyed as $filterName => $filter) {
if (array_has($request, $prefix . $filterName)) {
continue;
}
// Remove all filter values for this filter
$search->filters()->where('filter', $filterName)->delete();
}
return $this;
}
/**
* @throws AuthorizationException
*/
public function fetchActivitySearch(
Search $search,
Request $request,
SearchTransformer $searchTransformer,
): JsonResponse {
$this->authorize('view', $search);
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withCollection(
$user->searches()->get(),
$searchTransformer
->withConsumer($user)
);
}
/**
* Deletes a saved search
*
* @param Request $request
* @param Search $search
*
* @throws Exception
*
* @return JsonResponse
*/
public function deleteActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('delete', $search);
// Orphan any AutomatedReports that use this search
$search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);
// Delete filters and the search itself
$search->filters()->delete();
$search->delete();
return $this->response->withOk();
}
public function live(Request $request, ElasticActivityRepository $repository): JsonResponse
{
$user = $this->getUserFromRequest($request);
$this->request->validate([
'sort_direction' => 'in:asc,desc',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
]);
$activities = $repository->getLiveCoachingEligibleActivities(
user: $user,
lookBackMinutes: self::LOOK_BACK,
limit: (int) $this->request->input('limit', 25),
page: (int) $this->request->input('page', 1),
sortBy: ['actual_start_time', 'scheduled_start_time'],
sortDirection: (string) $this->request->input('sort_direction', 'asc'),
);
$this->response
->getManager()
->parseIncludes(['organizer.group', 'prospect'])
->setSerializer(new JsonSerializer());
return $this->response->withCollection($activities, new ActivityTransformer());
}
/**
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function show(Activity $activity, ActivityService $activityService): JsonResponse
{
$this->authorize('show', $activity);
$user = $activity->getUser();
$team = $user->getTeam();
// Sync the opportunity with the latest data if possible.
if ($activity->opportunity_id) {
try {
$crmService = $this->providerRegistry->get($team->crm->provider);
if (! $user->isCrmRequired()) {
$crmService->setUser($team->getOwner());
} else {
$crmService->setUser($user);
}
$crmService->syncOpportunity($activity->opportunity->crm_provider_id);
} catch (Exception $exception) {
// Move on.
}
}
$activityData = $activityService->getActivityData($this->request->user(), $activity);
return response()->json($activityData);
}
public function createRecording(Activity $activity)
{
$this->authorize('record', $activity);
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Tell Twilio to start recording this activity.
if ($activity->recording_state === Activity::RECORDING_OFF) {
$job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withCreated();
}
return $this->response->errorGone('Activity is already recording.');
}
public function updateRecording(Request $request, Activity $activity)
{
$this->authorize('record', $activity);
$request->validate([
'preference' => 'boolean',
'state' => [
'string',
Rule::in([
Activity::RECORDING_IN_PROGRESS,
Activity::RECORDING_PAUSED,
]),
],
]);
if ($request->has('state')) {
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Toggle the recording state between paused and resumed.
if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {
$job = (new ToggleRecording($activity, $request->input('state')))
->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Recording is not toggleable.');
}
if ($request->has('preference')) {
$activity->update([
'recording_preference' => $request->input('preference') ? 1 : 0,
]);
return $this->response->withOk();
}
return $this->response->errorWrongArgs('Something went wrong');
}
public function stopRecording(Activity $activity)
{
$this->authorize('stopRecord', $activity);
// Tell Twilio to stop recording this activity.
if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {
$job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Activity is not recording.');
}
/**
* Add activity to this user's favorites playlist
*
* @throws AuthorizationException
*/
public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse
{
$this->authorize('favorite', $activity);
$user = $this->getUserFromRequest($this->request);
$favorite = $activity->wasFavoritedBy($user);
$name = $activity->activity_title ?? '';
// It needs to check at least one record.
if (! $favorite) {
$favoritePlaylist = $user->favoritePlaylist();
$playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(
$activity,
$user,
$favoritePlaylist
);
if ($playlistActivity !== null) {
$playlistActivity->update(
// Just update, don't sort.
['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],
);
} else {
$playlistActivity = $activity->playlistActivities()->create([
'playlist_id' => $favoritePlaylist->getId(),
'user_id' => $user->getId(),
'start_time' => 0,
'name' => mb_strimwidth($name, 0, 100),
]);
// Sort it on top.
$playlistActivity->update(
[
'sort' => $playlistActivityRepository->calculateNewSortOrder(
null,
$playlistActivity,
),
],
);
}
$playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);
return new JsonResponse([], JsonResponse::HTTP_CREATED);
}
return new JsonResponse(
[
'error' => [
'code' => AbstractResponse::CODE_CONFLICT,
'http_code' => JsonResponse::HTTP_CONFLICT,
'message' => 'Resource Already Exists',
],
],
JsonResponse::HTTP_CONFLICT,
);
}
/**
* Remove activity from this user's favorites playlist
*
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function unfavorite(Activity $activity)
{
$user = $t...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"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":"Analyzing…","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 Carbon\\Carbon;\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Exception;\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Validation\\Rule;\nuse Illuminate\\Validation\\Rules\\In;\nuse Illuminate\\Validation\\ValidationException;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ActivityAnalytics;\nuse Jiminny\\Component\\ActivitySearch;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Contracts\\ES\\Events\\UpdateSingleEntity;\nuse Jiminny\\Contracts\\ES\\UpdateTargetEnum;\nuse Jiminny\\Contracts\\Nudge\\NudgeFactoryInterface;\nuse Jiminny\\Contracts\\Playlist\\PlaylistTrackFactoryInterface;\nuse Jiminny\\Contracts\\Repositories\\PlaylistActivityRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Enums\\TeamSetting;\nuse Jiminny\\Events\\Activities\\AiAutomation\\ActivityProspectAdded;\nuse Jiminny\\Events\\Activities\\Coaching\\Coached;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Controllers\\CommentContextInterface;\nuse Jiminny\\Http\\Responses\\Api\\AbstractResponse;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\ActivityCommentTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTopicTriggerTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTransformer;\nuse Jiminny\\Http\\Transformers\\AvailabilityNotificationTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingFeedbackTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingSectionsTransformer;\nuse Jiminny\\Http\\Transformers\\SearchTransformer;\nuse Jiminny\\Http\\Transformers\\StatsTransformer;\nuse Jiminny\\Jobs\\Crm\\SaveActivity;\nuse Jiminny\\Jobs\\Crm\\UpdateStage;\nuse Jiminny\\Jobs\\Telephony\\StartRecording;\nuse Jiminny\\Jobs\\Telephony\\StopRecording;\nuse Jiminny\\Jobs\\Telephony\\ToggleRecording;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\CoachingFeedback;\nuse Jiminny\\Models\\CoachingSection;\nuse Jiminny\\Models\\CoachingSectionCriterion;\nuse Jiminny\\Models\\CoachingSectionFeedback;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\LanguageDialect;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Nudge;\nuse Jiminny\\Models\\PlaybookCategory;\nuse Jiminny\\Models\\Playlist;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\Track;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\CoachingFeedbackRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Rules\\MultidimensionalArrayMaxCharRule;\nuse Jiminny\\Services\\ActivityService;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Services\\PlaybackService;\nuse Jiminny\\Services\\UserService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\nuse Ramsey\\Uuid\\Uuid;\nuse Sentry;\nuse Symfony\\Component\\HttpFoundation;\n\nfinal class ActivityController extends Controller implements CommentContextInterface\n{\n // Number of minutes to look back on activities. i.e. a timeout on activity duration.\n private const int LOOK_BACK = 180;\n\n public function __construct(\n private ProviderRegistry $providerRegistry,\n private ActivityService $activityService,\n Response $response,\n private UserService $userService,\n private ActivitySearch\\Service\\ActivitySearch $activitySearch,\n private NudgeFactoryInterface $nudgeFactory,\n private ActivityCommentService $activityCommentService,\n private LoggerInterface $logger,\n private readonly CoachingFeedbackRepository $coachingFeedbackRepository,\n private readonly TeamRepository $teamRepository,\n ) {\n parent::__construct($response);\n }\n\n public static function getCommentImplementation(): string\n {\n return Comment::class;\n }\n\n public function delete()\n {\n $this->request->validate([\n '*' => 'uuid:activities',\n ]);\n\n $deletedIds = [];\n foreach ($this->request->all() as $activityId) {\n $activity = Activity::idOrUuId($activityId);\n\n try {\n if ($this->authorize('delete', $activity)) {\n $activity->delete();\n $deletedIds[] = $activityId;\n\n \\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n }\n } catch (AuthorizationException $authorizationException) {\n // They didn't have permission.\n }\n }\n\n return $this->response->withArray($deletedIds);\n }\n\n public function update(Request $request, Activity $activity)\n {\n $this->authorize('updateMetadata', $activity);\n\n $request->validate([\n 'title' => 'string|max:250',\n 'category_id' => 'uuid:playbook_categories',\n 'language' => [\n new In(\n LanguageDialect::query()\n ->with('language')\n ->cursor()\n ->map(static function (LanguageDialect $languageDialect): string {\n return $languageDialect->getLanguageLocale();\n })\n ->all()\n ),\n ],\n ]);\n\n if ($request->has('title')) {\n $activity->title = $request->input('title');\n }\n\n if ($request->has('category_id')) {\n $category = PlaybookCategory::uuid($request->input('category_id'));\n\n if ($category->playbook->team_id !== $request->user()->team_id) {\n return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n if ($request->has('language')) {\n if (! $activity->isInProgress()) {\n return $this->response->withError(\n 'Activity language can only be set while the meeting is in progress.',\n 400\n );\n }\n\n $activity->setLanguageCode($request->input('language'));\n }\n\n $activity->save();\n\n return $this->response->withOk();\n }\n\n // XXX: This should be merged with the update method.\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws SocialAccountTokenInvalidException\n *\n * @return mixed\n */\n public function summarize(Activity $activity): mixed\n {\n $this->logger->info('[Log Activity] Summarizing activity ', [\n 'activityId' => $activity->getUuid(),\n 'payload' => $this->request->all(),\n ]);\n $this->authorize('update', $activity);\n\n $this->logger->info('[Log Activity] Validating summary');\n // Validate the payload.\n $this->validateSummary($activity);\n\n // All objects must belong to this team.\n /** @var User $user */\n $user = $this->request->user();\n $team = $user->getTeam();\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n try {\n $crmUser = $user;\n if ($user->isCrmRequired() === false) {\n $crmUser = $team->owner;\n }\n $crmService->setUser($crmUser);\n } catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());\n }\n\n $rawEntities = $this->request->input('entities');\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid(\n $this->request->input('layout_id')\n );\n\n // Delay execution of CRM jobs to avoid locking issues.\n $jobDelay = 0;\n\n // If we have arrived from a notification, mark it as read.\n $notificationId = $this->request->input('nId');\n if ($notificationId) {\n $notification = $user->unreadNotifications->where('id', $notificationId)->first();\n\n if ($notification) {\n $notification->markAsRead();\n }\n }\n\n $title = $this->request->input('title');\n $prospects = $this->request->input('prospects');\n $opportunityId = $this->request->input('opportunity_id');\n $stageId = $this->request->input('stage_id');\n $categoryId = $this->request->input('category_id');\n $summary = $this->request->input('summary');\n $crmProviderId = $this->request->input('crm_id');\n $isInternal = $this->request->input('is_internal') ?? false;\n\n $lead = null;\n $category = null;\n $account = null;\n $contact = null;\n $opportunity = null;\n $stage = null;\n $callStage = null;\n\n foreach ($prospects as $prospectData) {\n $objectId = $prospectData['id'];\n\n if ($objectId === null) {\n continue;\n }\n\n $objectType = $prospectData['type'];\n $this->logger->info('debug', ['prospect_data' => $prospectData]);\n\n try {\n if ($objectType === null) {\n $this->logger->info('no object type');\n if ($crmService instanceof SupportsObjectTypeParseInterface) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n }\n\n switch ($objectType) {\n case 'lead':\n $this->logger->info('Processing lead');\n /** @var Lead|null $lead */\n $lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();\n\n // Lead does not exist locally, import it.\n if ($lead === null) {\n $this->logger->info('Lead does not exist locally');\n /** @var Lead $lead */\n $lead = $crmService->syncLead($objectId);\n }\n\n $this->logger->info('Lead found', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n if ($stageId === null) {\n $this->logger->info('Stage ID is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $lead->stage;\n\n break;\n }\n\n $this->logger->info('Looking for stage');\n // Determine if they have changed the stage.\n /** @var Stage $stage */\n $stage = $team->crm->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_LEAD)\n ->firstOrFail();\n\n $this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);\n if ($lead->stage_id && $lead->stage_id !== $stage->id) {\n $this->logger->info('Stage has changed');\n // Storage current stage on activity.\n $callStage = $lead->stage;\n\n // The stage has changed, update in remote CRM.\n dispatch(new UpdateStage($activity, $lead, $callStage, $stage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing lead stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->getName(),\n $stage->getName()\n ),\n [\n 'user' => $user->getUuid(),\n 'lead' => $lead->getUuid(),\n ]\n );\n } else {\n $this->logger->info('Stage has not changed');\n // Stage remains as current.\n $callStage = $stage;\n }\n\n break;\n\n case 'account':\n $this->logger->info('Processing account');\n // If the object is not a lead, it should be an account.\n $account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();\n\n // Account does not exist locally, import it.\n if ($account === null) {\n $this->logger->info('Account does not exist locally');\n $account = $crmService->syncAccount($objectId);\n }\n\n $this->logger->info('Account found', ['accountId' => $account->id]);\n\n break;\n case 'contact':\n $this->logger->info('processing contact');\n $contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $this->logger->info('contact does not exist locally');\n $contact = $crmService->syncContact($objectId);\n }\n\n $this->logger->info('resolving account');\n $account = $this->resolveAccount($team, $contact, $crmService, $prospects);\n\n break;\n }\n\n // If they have specified an opportunity, retrieve this with stage.\n if ($opportunityId) {\n $this->logger->info('opportunity id is set');\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if ($opportunity === null) {\n $this->logger->info('opportunity does not exist locally');\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n if ($stageId === null) {\n $this->logger->info('stage id is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $opportunity->stage ?? null;\n } else {\n $this->logger->info('looking for stage');\n /** @var ?Stage $opportunityStage */\n $opportunityStage = $team->crm\n ->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n // There is a chance we still cannot import this opportunity.\n if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {\n $this->logger->info('opportunity stage has changed');\n // Storage current stage on activity.\n $callStage = $opportunity->stage;\n\n dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing opportunity stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->name,\n $opportunityStage->name\n ),\n [\n 'userId' => $user->id_string,\n 'opportunityId' => $opportunity->id_string,\n ]\n );\n } else {\n $this->logger->info('opportunity stage has not changed');\n // Stage remains as current.\n $callStage = $opportunityStage;\n }\n }\n }\n\n if ($crmProviderId) {\n // Cast $crmProviderId to string otherwise it won't use database index for some records\n $linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();\n\n // Check if this activity has already been assigned to a different activity.\n if ($linkedActivity && $linkedActivity->id !== $activity->id) {\n throw new InvalidArgumentException(\n 'Sorry, the linked task has already been logged under a different call. '\n . 'Please choose another linked task.'\n );\n }\n }\n } catch (InvalidArgumentException $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($exception->getMessage());\n } catch (Exception $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorInternalError(\n 'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'\n );\n }\n }\n\n if ($categoryId) {\n $category = PlaybookCategory::uuid($categoryId);\n\n if ($category->playbook->team_id !== $team->id) {\n throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n $this->logger->info('Prospect data', [\n 'lead_id' => $lead?->getId(),\n 'account_id' => $account?->getId(),\n 'contact_id' => $contact?->getId(),\n 'opportunity_id' => $opportunity?->getId(),\n 'stage_id' => $stage?->getId(),\n ]);\n\n if ($title) {\n $activity->title = $title;\n }\n\n if ($summary) {\n $activity->summary = $summary;\n }\n\n if ($crmProviderId) {\n $activity->crm_provider_id = $crmProviderId;\n }\n\n if ($callStage) {\n $this->logger->info('Setting stage id', ['stageId' => $callStage->id]);\n $activity->stage_id = $callStage->id;\n }\n\n if ($lead) {\n $this->logger->info('Setting lead id', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n // If we are changed from an account > lead, unset the account data.\n $this->logger->info('Unsetting account id, opportunity id, contact id, value');\n $activity->account_id = null;\n $activity->opportunity_id = null;\n $activity->contact_id = null;\n $activity->value = null;\n }\n\n if ($account) {\n $this->logger->info('Setting account id', ['accountId' => $account->id]);\n $activity->account_id = $account->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('unsetting lead id');\n $activity->lead_id = null;\n\n // Unset the contact if switching different accounts. Will be set up below if still applicable.\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {\n $this->logger->info('Unsetting contact id');\n $activity->contact_id = null;\n }\n }\n\n if ($opportunity) {\n $this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);\n $this->logger->info('unsetting lead id');\n $activity->opportunity_id = $opportunity->id;\n $activity->value = $opportunity->value;\n\n // If we are changed from an lead > account, unset the lead data.\n $activity->lead_id = null;\n }\n\n if ($contact) {\n $this->logger->info('setting contact id', ['contactId' => $contact->id]);\n $activity->contact_id = $contact->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('Unsetting lead id');\n $activity->lead_id = null;\n }\n\n $activity->is_internal = $isInternal;\n $activity->save();\n $activity->refresh();\n\n $this->logger->notice('Activity saved', [\n 'activity_id' => $activity->getId(),\n 'lead_id' => $activity->lead_id,\n 'account_id' => $activity->account_id,\n 'contact_id' => $activity->contact_id,\n 'opportunity_id' => $activity->opportunity_id,\n 'stage_id' => $activity->stage_id,\n 'crm_provider_id' => $activity->getCrmProviderId(),\n ]);\n\n // Store entities as field data on the activity.\n $updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);\n\n if ($activity->isLoggable()) {\n // Follow-up Task or Event data.\n $followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);\n\n $this->logger->info('CRM LOG manual log triggered', [\n 'activityId' => $activity->getUuid(),\n 'followupData' => $followupData,\n 'userId' => $user->getUuid(),\n ]);\n\n // Store data in the CRM.\n // ++add check for crm_required\n $job = new SaveActivity($activity, $followupData);\n\n if ($updatedData) {\n $job->delay(Carbon::now()->addMinutes($jobDelay));\n }\n\n dispatch($job);\n\n // Manually dispatch log for Opportunity or Prospect added\n if ($activity->hasOpportunity() || $activity->hasProspect()) {\n event(new ActivityProspectAdded(\n activity: $activity,\n eventSource: 'manually-log-crm-data'\n ));\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.\n *\n * @param ServiceInterface $service\n * @param Activity $activity\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array\n {\n $updatedData = [];\n $existingData = $activity->data()->get();\n\n // We need to delete any existing data to overwrite with latest values.\n $activity->data()->delete();\n\n $layoutEntities = $layout->entities()\n ->with('field', 'parent')\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->get();\n\n /** @var LayoutEntity $entity */\n foreach ($layoutEntities as $entity) {\n // If the user has provided a value for this entity\n if (array_key_exists($entity->id_string, $entities)) {\n $value = $entities[$entity->id_string];\n\n // Convert raw data into values that the CRM can consume.\n if ($value) {\n $value = $service->normalizeValue($entity->field->type, $value);\n }\n\n // Check the field is part of the activity-summary section.\n if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {\n // This is the internal database ID, not the external CRM ID.\n $objectId = null;\n\n switch ($entity->field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $objectId = $activity->account_id;\n\n break;\n\n case Field::OBJECT_CONTACT:\n $objectId = $activity->contact_id;\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n $objectId = $activity->opportunity_id;\n\n break;\n\n case Field::OBJECT_LEAD:\n $objectId = $activity->lead_id;\n\n break;\n\n case Field::OBJECT_TASK:\n case Field::OBJECT_EVENT:\n $objectId = $activity->id;\n\n break;\n }\n\n if ($objectId) {\n /** @var FieldData $data */\n $data = $activity->data()->create([\n 'crm_layout_entity_id' => $entity->id,\n 'crm_field_id' => $entity->crm_field_id,\n 'object_type' => $entity->field->object_type,\n 'object_id' => $objectId,\n 'value' => $value,\n ]);\n\n // Never send read-only field data to the CRM.\n if ($entity->read_only === false && $entity->is_visible) {\n $existingValue = $existingData\n ->where('crm_layout_entity_id', $entity->id)\n ->where('crm_field_id', $entity->crm_field_id)\n ->where('object_type', $entity->field->object_type)\n ->where('object_id', $objectId)\n ->first();\n\n // If the field was actually changed, we need to reflect this in the CRM too.\n if ($existingValue === null || $existingValue->value !== $value) {\n $updatedData[] = $data->id;\n }\n }\n }\n }\n }\n }\n\n return $updatedData;\n }\n\n /**\n * Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.\n *\n * @param ServiceInterface $crmService\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array\n {\n $fieldData = [];\n foreach ($entities as $entityId => $value) {\n // Only bother with fields that have a value.\n if ($value) {\n // Extract the entity from the UUID. Check the field is valid and part of the follow-up section.\n $entity = $layout->entities()\n ->uuid($entityId, false)\n ->whereHas('parent', function ($query) {\n $query->where('label', 'follow-up');\n })\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->first();\n\n if ($entity) {\n // Convert raw data into values that the CRM can consume.\n $value = $crmService->normalizeValue($entity->field->type, $value);\n\n // Add the field and value to the payload.\n $fieldData += [\n $entity->field->crm_provider_id => $value,\n ];\n }\n }\n }\n\n return $fieldData;\n }\n\n /**\n * @param Activity $activity\n */\n private function validateSummary(Activity $activity): void\n {\n $team = $activity->user->team;\n $crmProvider = $team->crm->provider;\n $attributes = [];\n\n $rules = [\n 'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,\n 'title' => 'string|max:250',\n 'prospects' => 'required|array',\n 'opportunity_id' => new CrmReference($crmProvider),\n 'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',\n 'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator\n 'summary' => 'max:50000',\n 'nId' => 'exists:notifications,id',\n 'crm_id' => new CrmReference($crmProvider),\n 'entities' => 'array',\n 'is_internal' => 'boolean',\n ];\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));\n\n // Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.\n $entities = $layout->entities()\n ->where('read_only', 0)\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->whereHas('parent', function ($query) use ($activity) {\n if ($activity->isLoggable() === false) {\n $query->where('label', '<>', 'follow-up');\n }\n });\n\n $isInternal = $this->request->input('is_internal', false);\n\n foreach ($entities->get() as $entity) {\n $rules += $this->buildFieldValidator($entity, $isInternal);\n $attributes += $this->buildFieldMessage($entity);\n }\n\n $this->request->validate($rules, [], $attributes);\n }\n\n private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array\n {\n return [\n 'entities.' . $entity->id_string => $entity->getValidator($isInternal),\n ];\n }\n\n /**\n * @param LayoutEntity $entity\n *\n * @return array\n */\n private function buildFieldMessage(LayoutEntity $entity): array\n {\n $label = $entity->label;\n if ($label === null) {\n $label = $entity->field->label;\n }\n\n return [\n 'entities.' . $entity->id_string => $label,\n ];\n }\n\n public function search(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->debugLog(\n $user,\n 'User extracted from request',\n ['user' => $user->getId(), 'tz' => $user->getTimezone()]\n );\n\n $searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());\n\n $this->debugLog(\n $user,\n 'ActivitySearch criteria built',\n ['searchCriteria' => $searchCriteria]\n );\n\n $filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);\n\n $this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);\n\n $this->validateSearch($request, $filterSet);\n\n $this->debugLog($user, 'Request validated');\n\n $searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);\n\n /** @var Collection<Activity> $activities */\n $activities = $searchResponse['results'];\n\n $this->debugLog($user, 'Activities ES response extracted');\n\n $hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(\n $user->getTeamId(),\n TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),\n );\n\n if ($hideInternalMeetingsSetting?->getValue() === '1') {\n $activities = $activities->filter(function (Activity $activity) {\n if ($activity->is_internal && empty($activity->actual_start_time)) {\n return false;\n }\n\n return true;\n });\n }\n\n $this->debugLog($user, 'Internal meetings (?!) filtered');\n\n $this->response->getManager()\n ->parseIncludes([\n 'category',\n 'organizer.group',\n 'prospect',\n 'stage',\n 'opportunity',\n 'stats',\n 'scorecards',\n 'masterTrack',\n 'activeParticipants',\n 'notification',\n ])\n ->setSerializer(new JsonSerializer());\n\n $transformerExcludes = $this->request->input('exclude');\n if ($transformerExcludes) {\n $this->response->getManager()->parseExcludes($transformerExcludes);\n }\n\n $this->debugLog($user, 'Response Manager (?!) applied');\n\n $transformer = new ActivityTransformer();\n $transformer->setConsumer($user);\n\n $this->debugLog($user, 'Activity Transformer added');\n\n $resource = new \\League\\Fractal\\Resource\\Collection($activities, $transformer);\n $page = $searchCriteria->getPageNumber();\n\n $this->debugLog($user, 'Search criteria page number called', ['page' => $page]);\n\n $histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');\n\n $this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);\n\n return $this->response->withArray([\n 'pagination' => [\n 'total' => $searchResponse['totalHits'],\n 'current' => $page,\n 'prev' => max($page - 1, 1),\n 'next' => $page + 1,\n ],\n 'results' => $this->response->getManager()->createData($resource)->toArray(),\n 'histogram' => $histogram,\n ]);\n }\n\n private function debugLog(User $user, string $logMessage, ?array $context = []): void\n {\n // Debug for Learning People Only\n if ($user->getTeamId() !== 260) {\n return;\n }\n\n Log::notice(\n sprintf('[activity-search-controller] %s', $logMessage),\n $context\n );\n }\n\n /** @throws ValidationException */\n private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void\n {\n $rules = [\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ];\n\n if ($prefix !== null && mb_strpos($prefix, '.') !== false) {\n $rules[rtrim($prefix, '.')] = sprintf(\n 'required|array|max:%d',\n $filterSet->count()\n );\n }\n\n $validationRules = $filterSet->getValidationRules($prefix)\n ->merge($rules)\n ->all();\n\n $request->validate($validationRules);\n }\n\n public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $search = $this->updateOrCreateActivitySearch($request);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function updateActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('update', $search);\n\n $this->updateOrCreateActivitySearch($request, $search);\n\n return $this->response->withOk();\n }\n\n private function storeNamedSearchFilters(\n Collection $request,\n Search $search,\n FilterDefinitionCollection $filterSet,\n ?string $prefix = null,\n ): self {\n $arrayTypeProperties = $filterSet\n ->getPropertyTypes([\n FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,\n ])\n ->all();\n\n $supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);\n\n foreach ($supportedRequestProperties as $requestPropertyName) {\n if (! array_has($request, $requestPropertyName)) {\n continue;\n }\n\n /** @var string|string[] $propertyValue */\n $propertyValue = array_get($request, $requestPropertyName);\n $propertyName = $prefix === null\n ? $requestPropertyName\n : mb_substr($requestPropertyName, mb_strlen($prefix));\n\n $isArrayType = array_has($arrayTypeProperties, $propertyName);\n\n if (! $isArrayType) {\n /** @var string $requestPropertyValue */\n\n $search->filters()->updateOrCreate(\n [\n 'filter' => $propertyName,\n ],\n [\n 'value' => $propertyValue,\n ]\n );\n\n continue;\n }\n\n /** @var string[] $requestPropertyValue */\n\n /** @var SearchFilter[]|Collection $existingFilterValues */\n $existingFilterValuesKeyed = $search->filters()\n ->where('filter', $propertyName)\n ->get()\n ->keyBy('id');\n\n // Iterate over values provided as request parameters\n foreach ($propertyValue as $value) {\n /** @var SearchFilter|null $valueFilter */\n $valueFilter = $search->filters()\n ->where(\n [\n 'filter' => $propertyName,\n 'value' => $value,\n ]\n )\n ->first();\n\n if ($valueFilter !== null) {\n // Remove filter value pair from list to be deleted\n $existingFilterValuesKeyed->forget($valueFilter->id);\n } else {\n // Add new filter/value pair\n $search->filters()->updateOrCreate([\n 'filter' => $propertyName,\n 'value' => $value,\n ]);\n }\n }\n\n // Delete filter value pairs for this filter that no longer exist in request parameters\n foreach ($existingFilterValuesKeyed as $existingFilter) {\n $existingFilter->delete();\n }\n }\n\n /** @var Collection<int, SearchFilter> $filtersKeyed */\n $filtersKeyed = $search->filters()->get()->keyBy('filter');\n\n // wipe removed filters from this search\n foreach ($filtersKeyed as $filterName => $filter) {\n if (array_has($request, $prefix . $filterName)) {\n continue;\n }\n\n // Remove all filter values for this filter\n $search->filters()->where('filter', $filterName)->delete();\n }\n\n return $this;\n }\n\n /**\n * @throws AuthorizationException\n */\n public function fetchActivitySearch(\n Search $search,\n Request $request,\n SearchTransformer $searchTransformer,\n ): JsonResponse {\n $this->authorize('view', $search);\n\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection(\n $user->searches()->get(),\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n /**\n * Deletes a saved search\n *\n * @param Request $request\n * @param Search $search\n *\n * @throws Exception\n *\n * @return JsonResponse\n */\n public function deleteActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('delete', $search);\n\n // Orphan any AutomatedReports that use this search\n $search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);\n\n // Delete filters and the search itself\n $search->filters()->delete();\n $search->delete();\n\n return $this->response->withOk();\n }\n\n public function live(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n $user = $this->getUserFromRequest($request);\n\n $this->request->validate([\n 'sort_direction' => 'in:asc,desc',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ]);\n\n $activities = $repository->getLiveCoachingEligibleActivities(\n user: $user,\n lookBackMinutes: self::LOOK_BACK,\n limit: (int) $this->request->input('limit', 25),\n page: (int) $this->request->input('page', 1),\n sortBy: ['actual_start_time', 'scheduled_start_time'],\n sortDirection: (string) $this->request->input('sort_direction', 'asc'),\n );\n\n $this->response\n ->getManager()\n ->parseIncludes(['organizer.group', 'prospect'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($activities, new ActivityTransformer());\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function show(Activity $activity, ActivityService $activityService): JsonResponse\n {\n $this->authorize('show', $activity);\n\n $user = $activity->getUser();\n $team = $user->getTeam();\n\n // Sync the opportunity with the latest data if possible.\n if ($activity->opportunity_id) {\n try {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n if (! $user->isCrmRequired()) {\n $crmService->setUser($team->getOwner());\n } else {\n $crmService->setUser($user);\n }\n\n $crmService->syncOpportunity($activity->opportunity->crm_provider_id);\n } catch (Exception $exception) {\n // Move on.\n }\n }\n\n $activityData = $activityService->getActivityData($this->request->user(), $activity);\n\n return response()->json($activityData);\n }\n\n public function createRecording(Activity $activity)\n {\n $this->authorize('record', $activity);\n\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Tell Twilio to start recording this activity.\n if ($activity->recording_state === Activity::RECORDING_OFF) {\n $job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withCreated();\n }\n\n return $this->response->errorGone('Activity is already recording.');\n }\n\n public function updateRecording(Request $request, Activity $activity)\n {\n $this->authorize('record', $activity);\n\n $request->validate([\n 'preference' => 'boolean',\n 'state' => [\n 'string',\n Rule::in([\n Activity::RECORDING_IN_PROGRESS,\n Activity::RECORDING_PAUSED,\n ]),\n ],\n ]);\n\n if ($request->has('state')) {\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Toggle the recording state between paused and resumed.\n if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {\n $job = (new ToggleRecording($activity, $request->input('state')))\n ->onQueue(Constants::QUEUE_CONFERENCES);\n\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Recording is not toggleable.');\n }\n\n if ($request->has('preference')) {\n $activity->update([\n 'recording_preference' => $request->input('preference') ? 1 : 0,\n ]);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorWrongArgs('Something went wrong');\n }\n\n public function stopRecording(Activity $activity)\n {\n $this->authorize('stopRecord', $activity);\n\n // Tell Twilio to stop recording this activity.\n if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {\n $job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Activity is not recording.');\n }\n\n /**\n * Add activity to this user's favorites playlist\n *\n * @throws AuthorizationException\n */\n public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse\n {\n $this->authorize('favorite', $activity);\n\n $user = $this->getUserFromRequest($this->request);\n $favorite = $activity->wasFavoritedBy($user);\n $name = $activity->activity_title ?? '';\n\n // It needs to check at least one record.\n if (! $favorite) {\n $favoritePlaylist = $user->favoritePlaylist();\n\n $playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(\n $activity,\n $user,\n $favoritePlaylist\n );\n\n if ($playlistActivity !== null) {\n $playlistActivity->update(\n // Just update, don't sort.\n ['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],\n );\n } else {\n $playlistActivity = $activity->playlistActivities()->create([\n 'playlist_id' => $favoritePlaylist->getId(),\n 'user_id' => $user->getId(),\n 'start_time' => 0,\n 'name' => mb_strimwidth($name, 0, 100),\n ]);\n // Sort it on top.\n $playlistActivity->update(\n [\n 'sort' => $playlistActivityRepository->calculateNewSortOrder(\n null,\n $playlistActivity,\n ),\n ],\n );\n }\n\n $playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);\n\n return new JsonResponse([], JsonResponse::HTTP_CREATED);\n }\n\n return new JsonResponse(\n [\n 'error' => [\n 'code' => AbstractResponse::CODE_CONFLICT,\n 'http_code' => JsonResponse::HTTP_CONFLICT,\n 'message' => 'Resource Already Exists',\n ],\n ],\n JsonResponse::HTTP_CONFLICT,\n );\n }\n\n /**\n * Remove activity from this user's favorites playlist\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unfavorite(Activity $activity)\n {\n $user = $this->request->user();\n\n $favorites = $activity->favoritedBy($user);\n\n if ($favorites && $favorites->isEmpty()) {\n return $this->response->errorNotFound('Favorite not found.');\n }\n\n $this->authorize('unfavorite', [$activity, $favorites]);\n\n // When you unfavorite an activity,\n // it should remove all the activities in it, including snippets.\n $isDeleted = $favorites->each(function ($favorite) {\n $favorite->forceDelete();\n });\n\n if ($isDeleted) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not remove favorite.');\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function notify(Activity $activity)\n {\n $this->authorize('notify', $activity);\n\n $user = $this->request->user();\n\n $existingNotification = $activity->availabilityNotifications()\n ->where('user_id', $user->id)\n ->exists();\n\n if ($existingNotification) {\n return $this->response->errorWrongArgs('Notification is already configured.');\n }\n\n $notification = Activity\\AvailabilityNotification::create([\n 'user_id' => $user->id,\n 'activity_id' => $activity->id,\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($notification, new AvailabilityNotificationTransformer());\n }\n\n /**\n * @param Activity $activity\n * @param Activity\\AvailabilityNotification $notification\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unnotify(Activity $activity, Activity\\AvailabilityNotification $notification)\n {\n $this->authorize('unnotify', [$activity, $notification]);\n\n if ($notification->sent_at || $notification->delete()) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not delete notification.');\n }\n\n public function play(Request $request, Activity $activity)\n {\n $this->authorize('stream', $activity);\n\n $request->validate([\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $activity->plays()->create([\n 'user_id' => $user->getId(),\n 'start_time' => $request->input('start_time'),\n ]);\n\n return $this->response->withCreated();\n }\n\n /**\n * @param Activity $activity\n *\n * @return mixed\n */\n public function comment(Activity $activity)\n {\n return $this->newComment($activity);\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @return mixed\n */\n public function replyComment(Activity $activity, Comment $comment)\n {\n return $this->newComment($activity, $comment);\n }\n\n /**\n * @param Activity $activity\n * @param Comment|null $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n protected function newComment(Activity $activity, ?Comment $comment = null)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n 'type' => 'integer|between:0,3',\n 'visibility' => sprintf('nullable|integer|between:1,%d', count(Comment::getVisibilityLevels())),\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n $threadStartId = null;\n if ($comment) {\n $threadStartId = $comment->thread_start_id ?: $comment->id;\n }\n\n try {\n $newComment = Comment::create([\n 'parent_comment_id' => $comment->id ?? null,\n 'thread_start_id' => $threadStartId,\n 'activity_id' => $activity->id,\n 'user_id' => $this->request->user()->id,\n 'comment' => trim($this->request->input('comment')),\n 'start_time' => $this->request->input('start_time', 0),\n 'end_time' => $this->request->input('end_time', 0),\n 'type' => $this->request->input('type', Comment::TYPE_NEUTRAL),\n 'visibility' => $this->request->input('visibility', Comment::VISIBILITY_PUBLIC),\n ]);\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($newComment, new ActivityCommentTransformer());\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not create comment.' . $exception->getMessage());\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function updateComment(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n try {\n $comment->update([\n 'comment' => trim($this->request->input('comment')),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment.');\n }\n }\n\n public function updateCommentVisibility(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'visibility' => sprintf('integer|between:1,%d', count(Comment::getVisibilityLevels())),\n ]);\n\n $visibility = $this->request->input('visibility');\n\n if ($comment->parent !== null) {\n return $this->response->errorWrongArgs('Comment visibility can only be updated on top level comments.');\n }\n\n try {\n $this->activityCommentService->updateCommentVisibility($comment, $visibility);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment\\'s visibility.');\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function deleteComment(Activity $activity, Comment $comment)\n {\n $this->authorize('deleteComment', [$activity, $comment]);\n\n // Delete comment and any children.\n $comment->delete();\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function fetchComments()\n {\n $user = $this->request->user();\n $this->request->validate([\n 'forUserId' => 'uuid:users,team_id,' . $user->team_id,\n 'types' => 'array',\n 'types.*' => 'integer|between:0,3',\n ]);\n $forUser = null;\n\n $types = [Comment::TYPE_NEUTRAL, Comment::TYPE_GAME_CHANGER, Comment::TYPE_POSITIVE];\n $user = $this->request->user();\n if ($this->request->has('forUserId')) {\n $forUser = $user->team->users()->uuid($this->request->input('forUserId'));\n }\n\n $comments = Comment::query()\n ->whereHas('activity', static function (Builder $builder) use ($user, $forUser): void {\n $builder\n // I left feedback on my own activity; or\n ->where('activities.user_id', $user->getId());\n if ($forUser) {\n // I left feedback on any activity for this user.\n $builder->orWhere([\n 'user_id' => $user->getId(),\n 'activities.user_id' => $forUser->getId(),\n ]);\n }\n })\n ->whereIn('type', $this->request->input('types', $types))\n ->orderBy('created_at', 'desc')\n ->get();\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity', 'user'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($comments, new ActivityCommentTransformer());\n }\n\n public function deleteCoachingFeedback(Activity $activity, CoachingFeedback $coachingFeedback)\n {\n $this->authorize('deleteCoachingFeedback', [$activity, $coachingFeedback]);\n $activity = $coachingFeedback->getActivity();\n\n if ($coachingFeedback->delete()) {\n event(new UpdateSingleEntity(\n entityId: $activity->getId(),\n updateTarget: UpdateTargetEnum::ACTIVITY,\n purpose: 'delete-coaching-feedback',\n ));\n\n return $this->response->withOk();\n }\n\n return $this->response->withError('Delete operation failed. Contact support.', 500);\n }\n\n /**\n * Add new or update Coaching feedback\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws \\Illuminate\\Validation\\ValidationException\n *\n * @return mixed\n */\n public function putCoachingFeedback(Request $request, Activity $activity)\n {\n $user = $request->user();\n\n if (! $user instanceof User) {\n abort(403);\n }\n $teamId = $user->getTeamId();\n\n $this->authorize('coach', $activity);\n\n $this->request->validate([\n 'coach_id' => 'required|uuid:users,team_id,' . $teamId,\n 'coachee_id' => 'required|uuid:users,team_id,' . $teamId,\n 'visibility' => ['required', Rule::in(CoachingFeedback::VISIBILITIES)],\n 'coaching_sections.*.uuid' => 'required|uuid:coaching_sections',\n 'coaching_sections.*.score' => ['required', Rule::in(CoachingSectionFeedback::SCORES)],\n 'coaching_sections.*.summary' => 'string|max:10000',\n 'coaching_sections.*.criteria.*.uuid' => 'required|uuid:coaching_section_criteria',\n 'coaching_sections.*.criteria.*.note' => 'required|string|max:10000',\n 'sharedWithUsers' => [\n 'required_if:visibility,' . CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS,\n 'array',\n ],\n 'sharedWithUsers.*' => [\n 'uuid:users,team_id,' . $teamId,\n ],\n ]);\n\n /** @var User $coach */\n $coach = User::uuid($this->request->input('coach_id'));\n /** @var User $coachee */\n $coachee = User::uuid($this->request->input('coachee_id'));\n $coachingSectionFeedbacks = $this->request->input('coaching_sections');\n\n $previousRecord = $this->coachingFeedbackRepository->getOneForActivityByCoacheeAndCoach(\n $coachee->getId(),\n $coach->getId(),\n $activity->getId()\n );\n $recordIsNew = false;\n if ($previousRecord === null) {\n $recordIsNew = true;\n }\n\n if (! $coachee->isSameTeamId($coach)) {\n return $this->response->errorForbidden('User not member of your team.');\n }\n\n if (! is_array($coachingSectionFeedbacks) || count($coachingSectionFeedbacks) < 1) {\n return $this->response->withError('At least one Coaching Framework Section shall be scored.', 422);\n }\n\n if (! $activity->participants()->where('participants.user_id', $coachee->id)->exists()) {\n return $this->response->withError('Coached user did not participate activity.', 422);\n }\n\n $visibility = $this->request->input('visibility');\n\n $shouldSendNotification = $recordIsNew;\n if ($recordIsNew === false && $visibility !== $previousRecord->getVisibility()) {\n $shouldSendNotification = true;\n }\n\n /**\n * Create CoachingFeedback\n *\n * @var CoachingFeedback $coachingFeedback\n */\n $coachingFeedback = $activity->coachingFeedbacks()->updateOrCreate(\n [\n 'coach_id' => $coach->id,\n 'coachee_id' => $coachee->id,\n ],\n [\n 'framework_id' => $activity->category->id,\n 'visibility' => $visibility,\n ]\n );\n\n $sharedUserIds = [];\n if ($visibility === CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS) {\n foreach ($this->request->input('sharedWithUsers') as $sharedWithUserUuid) {\n /** @var User $user */\n $user = User::uuid($sharedWithUserUuid);\n $sharedUserIds[] = $user->getId();\n }\n }\n\n $syncResult = $coachingFeedback->customAccessUsers()->sync($sharedUserIds);\n\n $scores = [];\n\n\n /**\n * Create CoachingSectionsFeedbacks.\n *\n * @var CoachingSectionFeedback $coachingSectionFeedback\n */\n foreach ($coachingSectionFeedbacks as $coachingSectionFeedbackInput) {\n $coachingSection = CoachingSection::uuid($coachingSectionFeedbackInput['uuid']);\n $coachingSectionFeedback = $coachingFeedback->sectionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_id' => $coachingSection->id,\n ],\n [\n 'score' => array_get($coachingSectionFeedbackInput, 'score'),\n 'summary' => array_get($coachingSectionFeedbackInput, 'summary') ?? '',\n ]\n );\n\n $scores[] = array_get($coachingSectionFeedbackInput, 'score');\n\n $criteria = array_get($coachingSectionFeedbackInput, 'criteria');\n if (is_array($criteria) && ! empty($criteria)) {\n foreach ($criteria as $criteriaFeedbackInput) {\n $coachingSectionFeedback->criterionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_criterion_id' => CoachingSectionCriterion::uuid(array_get($criteriaFeedbackInput, 'uuid'))\n ->id,\n ],\n ['note' => array_get($criteriaFeedbackInput, 'note')],\n );\n }\n }\n }\n\n $coachingFeedback->average_score = array_sum($scores) / count($scores);\n\n if ($recordIsNew === false && $coachingFeedback->getAverageScore() !== $previousRecord->getAverageScore()) {\n $shouldSendNotification = true;\n }\n if (! empty($syncResult['attached']) || ! empty($syncResult['detached']) || ! empty($syncResult['updated'])) {\n $shouldSendNotification = true;\n }\n\n $coachingFeedback->save();\n // ensure updated at for coaching feedback on section feedback summary added.\n $coachingFeedback->touch();\n\n if ($shouldSendNotification) {\n event(new Coached($coachingFeedback));\n }\n\n Datadog::increment('jiminny.activity.score.update', 1, ['company' => $activity->user->team->slug]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n $coachingFeedbackTransformer = new CoachingFeedbackTransformer();\n $coachingFeedbackTransformer->setConsumer($this->getUserFromRequest($request));\n\n return $this->response->withItem($coachingFeedback, $coachingFeedbackTransformer);\n }\n\n\n /**\n * Retrieve category criteria for coaching.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachingSections(Activity $activity)\n {\n $this->authorize('coach', $activity);\n\n if ($activity->category === null) {\n return $this->response->errorUnprocessable('Category has not yet been assigned.');\n }\n\n $criteria = $activity\n ->category\n ->coachingSections()\n ->where('is_enabled', 1)\n ->orderBy('sequence', 'asc');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($criteria->get(), new CoachingSectionsTransformer());\n }\n\n /**\n * @throws AuthorizationException\n * @throws ValidationException\n *\n * @return mixed\n */\n public function addToPlaylist(Activity $activity, PlaylistTrackFactoryInterface $playlistTrackFactory)\n {\n $this->request->validate([\n 'playlists' => 'required|array',\n 'playlists.*' => 'uuid:playlists',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'name' => 'required|max:100',\n ]);\n\n $this->authorize('addToPlaylist', [$activity, $this->request->input('playlists')]);\n\n $startTime = $this->request->input('start_time');\n $endTime = $this->request->input('end_time');\n $name = $this->request->input('name');\n /** @var User $user */\n $user = $this->request->user();\n\n // Get playlist by uuid.\n foreach ($this->request->input('playlists') as $playlistId) {\n // Pull out the playlist model.\n $playlist = Playlist::uuid($playlistId);\n\n $playlistTrackFactory->createTrack($playlist, $user, [\n 'name' => $name,\n 'activity' => $activity,\n 'start_time' => $startTime,\n 'end_time' => $endTime,\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function share(Request $request, Activity $activity): JsonResponse\n {\n $this->authorize('share', $activity);\n\n $request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'recipients.*.type' => 'in:user,group',\n 'recipients.*.id' => 'string|max:40',\n 'share' => 'string|max:255',\n ]);\n\n $user = $request->user();\n\n $recipients = $request->get('recipients');\n $users = $this->userService->convertRecipientsToUsers($user, $recipients);\n\n $shareData = [\n 'from_user_id' => $user->id,\n 'note' => $request->input('note'),\n 'start_time' => $request->input('start_time'),\n 'end_time' => $request->input('end_time'),\n ];\n\n // Create a share object against a notification provider channel\n if ($request->input('share')) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'notification_provider_channel' => $request->input('share'),\n ]\n )\n );\n\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n\n // Create a share object against each recipient\n foreach ($users as $recipient) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'to_user_id' => $recipient->id,\n ]\n )\n );\n\n // If parent_share_id has been selected yet\n if (! isset($shareData['parent_share_id'])) {\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachRequest(Activity $activity)\n {\n $this->authorize('coachRequest', $activity);\n\n $this->request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'coachers.*.type' => 'required|in:user',\n 'coachers.*.id' => 'required',\n ]);\n\n $coachers = $this->request->get('coachers');\n $user = $this->request->user();\n $users = $this->userService->convertRecipientsToUsers($user, $coachers);\n\n foreach ($users as $coacher) {\n CoachRequest::create([\n 'user_id' => $coacher->id,\n 'activity_id' => $activity->id,\n 'note' => $this->request->get('note'),\n 'start_time' => $this->request->get('start_time'),\n 'end_time' => $this->request->get('end_time'),\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function createActivityTopicTriggers(Activity $activity, LoggerInterface $logger): HttpFoundation\\JsonResponse\n {\n $this->authorize('analyzeTopicTriggers', $activity);\n\n if (! $activity->hasTranscription()) {\n return new HttpFoundation\\JsonResponse(\n [\n 'error' => 'Transcription not found.',\n ],\n JsonResponse::HTTP_NOT_FOUND\n );\n }\n\n $logger->info(__METHOD__ . ': queued for analysis', [\n 'activity' => $activity->id_string,\n ]);\n\n dispatch(new ActivityAnalytics\\Job\\AnalyzeActivityTopicTriggers($activity));\n\n return new HttpFoundation\\JsonResponse(null, JsonResponse::HTTP_CREATED);\n }\n\n public function fetchActivityTopicTriggers(\n Activity $activity,\n LoggerInterface $logger,\n ActivityTopicTriggerTransformer $transformer\n ): HttpFoundation\\JsonResponse {\n $this->authorize('fetchTopicTriggers', $activity);\n\n $logger->debug(__METHOD__, [\n 'activity' => $activity->id_string,\n ]);\n\n if (! $activity->isProcessed()) {\n return new HttpFoundation\\JsonResponse([]);\n }\n\n $payload = [];\n\n if ($activity->hasTopicTriggers()) {\n $payload = $activity->getTopicTriggersSorted()\n ->map(\n static fn (Activity\\TopicTrigger $activityTopicTrigger): array\n => $transformer->transform($activityTopicTrigger)\n )\n ->values()\n ->all();\n }\n\n return new HttpFoundation\\JsonResponse($payload);\n }\n\n /**\n * @param Activity $activity\n * @param StatsTransformer $statsTransformer\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function stats(Activity $activity, StatsTransformer $statsTransformer)\n {\n $this->authorize('stream', $activity);\n\n if (! $activity->hasTranscription()) {\n return $this->response->errorNotFound('Waveform data is not yet generated.');\n }\n\n $this->response\n ->getManager()\n ->parseIncludes(['wavedata'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($activity, $statsTransformer);\n }\n\n public function destroy(Activity $activity)\n {\n $this->authorize('delete', $activity);\n\n $activity->delete();\n\n \\Log::info('Soft delete activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n\n return $this->response->withNoContent();\n }\n\n public function note(Activity $activity)\n {\n $this->authorize('note', $activity);\n\n $this->request->validate([\n 'note' => 'required|min:1|max:2000',\n 'time' => 'required|numeric|min:0|max:86400',\n ]);\n\n $note = $this->request->input('note');\n $time = $this->request->input('time');\n\n $this->activityService->setActivity($activity);\n $this->activityService->takeNote($this->getUser(), $note, $time);\n\n return $this->response->withCreated();\n }\n\n /**\n * Mark an activity as private.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPrivate(Activity $activity)\n {\n $this->authorize('markAsPrivate', $activity);\n\n if ($activity->is_private === false) {\n $activity->is_private = true;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * Mark an activity as public.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPublic(Activity $activity)\n {\n $this->authorize('markAsPublic', $activity);\n\n if ($activity->is_private) {\n $activity->is_private = false;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws LogicException\n */\n public function fetchCloudFrontS3MediaKeys(Activity $activity, PlaybackService $playbackService): JsonResponse\n {\n $masterTrack = $activity->masterTrack()->first();\n\n if (! $masterTrack instanceof Track) {\n throw new LogicException(sprintf('Master track not found for activity \"%s\"', $activity->getUuid()));\n }\n\n return $this->response->withArray(\n $playbackService->generateCookies(\n $masterTrack,\n $this->request->ip(),\n ),\n );\n }\n\n /**\n * @throws ValidationException\n */\n private function updateOrCreateActivitySearch(Request $request, ?Search $search = null): Search\n {\n $request->validate([\n 'name' => 'required|string|min:2|max:100',\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $searchName = $request->input('name');\n\n if ($search !== null) {\n $search->update([\n 'name' => $searchName,\n ]);\n\n return $search;\n }\n\n $request->validate([\n 'filters' => ['required', 'array', new MultidimensionalArrayMaxCharRule(limit: 255)],\n 'nudges' => 'array|max:' . count(Nudge::MAP_CHANNEL),\n 'nudges.*.channel' => 'required|in:' . implode(',', Nudge::MAP_CHANNEL),\n 'nudges.*.frequency' => 'required|in:' . implode(',', Nudge::MAP_FREQUENCY),\n 'nudges.*.expiresAt' => [\n 'required',\n 'date',\n 'after:today',\n 'before_or_equal:' . now()->addYear()->format('Y-m-d'),\n ],\n ]);\n\n $searchCriteria = Criteria::createFromRequest(\n Collection::make($request->input('filters', []))->all(),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($searchCriteria, $user);\n $this->validateSearch($request, $filterSet, 'filters.');\n\n /** @var Search $search */\n $search = Search::create([\n 'name' => $searchName,\n 'uuid' => Uuid::uuid4()->toString(),\n 'user_id' => $user->getId(),\n ]);\n\n Collection::make($request->input('nudges', []))\n ->each(fn (array $attributes): Nudge => $this->nudgeFactory->createNudge($search, $attributes));\n\n $this->storeNamedSearchFilters(Collection::make($request->all()), $search, $filterSet, 'filters.');\n\n return $search;\n }\n\n private function resolveAccount(\n Team $team,\n Contact $contact,\n ServiceInterface $crmService,\n array $prospects,\n ): ?Account {\n $this->logger->info('Resolving account from contact');\n $account = $contact->getAccount();\n\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS)) {\n $this->logger->info('Team does not have feature to link activity to multiple prospects');\n\n return $account;\n }\n\n $this->logger->info('Resolving account from prospect data');\n $accountData = array_filter(\n $prospects,\n static fn (array $prospectData): bool => $prospectData['type'] === 'account'\n );\n\n if (! empty($accountData)) {\n $this->logger->info('Found account data in prospects');\n $accountData = reset($accountData);\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountData['id'])->first();\n\n if (! $account instanceof Account) {\n $this->logger->info('Account not found in database, syncing from CRM');\n $account = $crmService->syncAccount($accountData['id']);\n }\n }\n\n $this->logger->info('Resolved account', ['account' => $account->getId()]);\n\n return $account;\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Http\\Controllers\\API;\n\nuse Carbon\\Carbon;\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Exception;\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Validation\\Rule;\nuse Illuminate\\Validation\\Rules\\In;\nuse Illuminate\\Validation\\ValidationException;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ActivityAnalytics;\nuse Jiminny\\Component\\ActivitySearch;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Contracts\\ES\\Events\\UpdateSingleEntity;\nuse Jiminny\\Contracts\\ES\\UpdateTargetEnum;\nuse Jiminny\\Contracts\\Nudge\\NudgeFactoryInterface;\nuse Jiminny\\Contracts\\Playlist\\PlaylistTrackFactoryInterface;\nuse Jiminny\\Contracts\\Repositories\\PlaylistActivityRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Enums\\TeamSetting;\nuse Jiminny\\Events\\Activities\\AiAutomation\\ActivityProspectAdded;\nuse Jiminny\\Events\\Activities\\Coaching\\Coached;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Controllers\\CommentContextInterface;\nuse Jiminny\\Http\\Responses\\Api\\AbstractResponse;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\ActivityCommentTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTopicTriggerTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTransformer;\nuse Jiminny\\Http\\Transformers\\AvailabilityNotificationTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingFeedbackTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingSectionsTransformer;\nuse Jiminny\\Http\\Transformers\\SearchTransformer;\nuse Jiminny\\Http\\Transformers\\StatsTransformer;\nuse Jiminny\\Jobs\\Crm\\SaveActivity;\nuse Jiminny\\Jobs\\Crm\\UpdateStage;\nuse Jiminny\\Jobs\\Telephony\\StartRecording;\nuse Jiminny\\Jobs\\Telephony\\StopRecording;\nuse Jiminny\\Jobs\\Telephony\\ToggleRecording;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\CoachingFeedback;\nuse Jiminny\\Models\\CoachingSection;\nuse Jiminny\\Models\\CoachingSectionCriterion;\nuse Jiminny\\Models\\CoachingSectionFeedback;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\LanguageDialect;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Nudge;\nuse Jiminny\\Models\\PlaybookCategory;\nuse Jiminny\\Models\\Playlist;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\Track;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\CoachingFeedbackRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Rules\\MultidimensionalArrayMaxCharRule;\nuse Jiminny\\Services\\ActivityService;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Services\\PlaybackService;\nuse Jiminny\\Services\\UserService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\nuse Ramsey\\Uuid\\Uuid;\nuse Sentry;\nuse Symfony\\Component\\HttpFoundation;\n\nfinal class ActivityController extends Controller implements CommentContextInterface\n{\n // Number of minutes to look back on activities. i.e. a timeout on activity duration.\n private const int LOOK_BACK = 180;\n\n public function __construct(\n private ProviderRegistry $providerRegistry,\n private ActivityService $activityService,\n Response $response,\n private UserService $userService,\n private ActivitySearch\\Service\\ActivitySearch $activitySearch,\n private NudgeFactoryInterface $nudgeFactory,\n private ActivityCommentService $activityCommentService,\n private LoggerInterface $logger,\n private readonly CoachingFeedbackRepository $coachingFeedbackRepository,\n private readonly TeamRepository $teamRepository,\n ) {\n parent::__construct($response);\n }\n\n public static function getCommentImplementation(): string\n {\n return Comment::class;\n }\n\n public function delete()\n {\n $this->request->validate([\n '*' => 'uuid:activities',\n ]);\n\n $deletedIds = [];\n foreach ($this->request->all() as $activityId) {\n $activity = Activity::idOrUuId($activityId);\n\n try {\n if ($this->authorize('delete', $activity)) {\n $activity->delete();\n $deletedIds[] = $activityId;\n\n \\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n }\n } catch (AuthorizationException $authorizationException) {\n // They didn't have permission.\n }\n }\n\n return $this->response->withArray($deletedIds);\n }\n\n public function update(Request $request, Activity $activity)\n {\n $this->authorize('updateMetadata', $activity);\n\n $request->validate([\n 'title' => 'string|max:250',\n 'category_id' => 'uuid:playbook_categories',\n 'language' => [\n new In(\n LanguageDialect::query()\n ->with('language')\n ->cursor()\n ->map(static function (LanguageDialect $languageDialect): string {\n return $languageDialect->getLanguageLocale();\n })\n ->all()\n ),\n ],\n ]);\n\n if ($request->has('title')) {\n $activity->title = $request->input('title');\n }\n\n if ($request->has('category_id')) {\n $category = PlaybookCategory::uuid($request->input('category_id'));\n\n if ($category->playbook->team_id !== $request->user()->team_id) {\n return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n if ($request->has('language')) {\n if (! $activity->isInProgress()) {\n return $this->response->withError(\n 'Activity language can only be set while the meeting is in progress.',\n 400\n );\n }\n\n $activity->setLanguageCode($request->input('language'));\n }\n\n $activity->save();\n\n return $this->response->withOk();\n }\n\n // XXX: This should be merged with the update method.\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws SocialAccountTokenInvalidException\n *\n * @return mixed\n */\n public function summarize(Activity $activity): mixed\n {\n $this->logger->info('[Log Activity] Summarizing activity ', [\n 'activityId' => $activity->getUuid(),\n 'payload' => $this->request->all(),\n ]);\n $this->authorize('update', $activity);\n\n $this->logger->info('[Log Activity] Validating summary');\n // Validate the payload.\n $this->validateSummary($activity);\n\n // All objects must belong to this team.\n /** @var User $user */\n $user = $this->request->user();\n $team = $user->getTeam();\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n try {\n $crmUser = $user;\n if ($user->isCrmRequired() === false) {\n $crmUser = $team->owner;\n }\n $crmService->setUser($crmUser);\n } catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());\n }\n\n $rawEntities = $this->request->input('entities');\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid(\n $this->request->input('layout_id')\n );\n\n // Delay execution of CRM jobs to avoid locking issues.\n $jobDelay = 0;\n\n // If we have arrived from a notification, mark it as read.\n $notificationId = $this->request->input('nId');\n if ($notificationId) {\n $notification = $user->unreadNotifications->where('id', $notificationId)->first();\n\n if ($notification) {\n $notification->markAsRead();\n }\n }\n\n $title = $this->request->input('title');\n $prospects = $this->request->input('prospects');\n $opportunityId = $this->request->input('opportunity_id');\n $stageId = $this->request->input('stage_id');\n $categoryId = $this->request->input('category_id');\n $summary = $this->request->input('summary');\n $crmProviderId = $this->request->input('crm_id');\n $isInternal = $this->request->input('is_internal') ?? false;\n\n $lead = null;\n $category = null;\n $account = null;\n $contact = null;\n $opportunity = null;\n $stage = null;\n $callStage = null;\n\n foreach ($prospects as $prospectData) {\n $objectId = $prospectData['id'];\n\n if ($objectId === null) {\n continue;\n }\n\n $objectType = $prospectData['type'];\n $this->logger->info('debug', ['prospect_data' => $prospectData]);\n\n try {\n if ($objectType === null) {\n $this->logger->info('no object type');\n if ($crmService instanceof SupportsObjectTypeParseInterface) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n }\n\n switch ($objectType) {\n case 'lead':\n $this->logger->info('Processing lead');\n /** @var Lead|null $lead */\n $lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();\n\n // Lead does not exist locally, import it.\n if ($lead === null) {\n $this->logger->info('Lead does not exist locally');\n /** @var Lead $lead */\n $lead = $crmService->syncLead($objectId);\n }\n\n $this->logger->info('Lead found', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n if ($stageId === null) {\n $this->logger->info('Stage ID is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $lead->stage;\n\n break;\n }\n\n $this->logger->info('Looking for stage');\n // Determine if they have changed the stage.\n /** @var Stage $stage */\n $stage = $team->crm->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_LEAD)\n ->firstOrFail();\n\n $this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);\n if ($lead->stage_id && $lead->stage_id !== $stage->id) {\n $this->logger->info('Stage has changed');\n // Storage current stage on activity.\n $callStage = $lead->stage;\n\n // The stage has changed, update in remote CRM.\n dispatch(new UpdateStage($activity, $lead, $callStage, $stage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing lead stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->getName(),\n $stage->getName()\n ),\n [\n 'user' => $user->getUuid(),\n 'lead' => $lead->getUuid(),\n ]\n );\n } else {\n $this->logger->info('Stage has not changed');\n // Stage remains as current.\n $callStage = $stage;\n }\n\n break;\n\n case 'account':\n $this->logger->info('Processing account');\n // If the object is not a lead, it should be an account.\n $account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();\n\n // Account does not exist locally, import it.\n if ($account === null) {\n $this->logger->info('Account does not exist locally');\n $account = $crmService->syncAccount($objectId);\n }\n\n $this->logger->info('Account found', ['accountId' => $account->id]);\n\n break;\n case 'contact':\n $this->logger->info('processing contact');\n $contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $this->logger->info('contact does not exist locally');\n $contact = $crmService->syncContact($objectId);\n }\n\n $this->logger->info('resolving account');\n $account = $this->resolveAccount($team, $contact, $crmService, $prospects);\n\n break;\n }\n\n // If they have specified an opportunity, retrieve this with stage.\n if ($opportunityId) {\n $this->logger->info('opportunity id is set');\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if ($opportunity === null) {\n $this->logger->info('opportunity does not exist locally');\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n if ($stageId === null) {\n $this->logger->info('stage id is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $opportunity->stage ?? null;\n } else {\n $this->logger->info('looking for stage');\n /** @var ?Stage $opportunityStage */\n $opportunityStage = $team->crm\n ->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n // There is a chance we still cannot import this opportunity.\n if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {\n $this->logger->info('opportunity stage has changed');\n // Storage current stage on activity.\n $callStage = $opportunity->stage;\n\n dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing opportunity stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->name,\n $opportunityStage->name\n ),\n [\n 'userId' => $user->id_string,\n 'opportunityId' => $opportunity->id_string,\n ]\n );\n } else {\n $this->logger->info('opportunity stage has not changed');\n // Stage remains as current.\n $callStage = $opportunityStage;\n }\n }\n }\n\n if ($crmProviderId) {\n // Cast $crmProviderId to string otherwise it won't use database index for some records\n $linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();\n\n // Check if this activity has already been assigned to a different activity.\n if ($linkedActivity && $linkedActivity->id !== $activity->id) {\n throw new InvalidArgumentException(\n 'Sorry, the linked task has already been logged under a different call. '\n . 'Please choose another linked task.'\n );\n }\n }\n } catch (InvalidArgumentException $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($exception->getMessage());\n } catch (Exception $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorInternalError(\n 'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'\n );\n }\n }\n\n if ($categoryId) {\n $category = PlaybookCategory::uuid($categoryId);\n\n if ($category->playbook->team_id !== $team->id) {\n throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n $this->logger->info('Prospect data', [\n 'lead_id' => $lead?->getId(),\n 'account_id' => $account?->getId(),\n 'contact_id' => $contact?->getId(),\n 'opportunity_id' => $opportunity?->getId(),\n 'stage_id' => $stage?->getId(),\n ]);\n\n if ($title) {\n $activity->title = $title;\n }\n\n if ($summary) {\n $activity->summary = $summary;\n }\n\n if ($crmProviderId) {\n $activity->crm_provider_id = $crmProviderId;\n }\n\n if ($callStage) {\n $this->logger->info('Setting stage id', ['stageId' => $callStage->id]);\n $activity->stage_id = $callStage->id;\n }\n\n if ($lead) {\n $this->logger->info('Setting lead id', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n // If we are changed from an account > lead, unset the account data.\n $this->logger->info('Unsetting account id, opportunity id, contact id, value');\n $activity->account_id = null;\n $activity->opportunity_id = null;\n $activity->contact_id = null;\n $activity->value = null;\n }\n\n if ($account) {\n $this->logger->info('Setting account id', ['accountId' => $account->id]);\n $activity->account_id = $account->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('unsetting lead id');\n $activity->lead_id = null;\n\n // Unset the contact if switching different accounts. Will be set up below if still applicable.\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {\n $this->logger->info('Unsetting contact id');\n $activity->contact_id = null;\n }\n }\n\n if ($opportunity) {\n $this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);\n $this->logger->info('unsetting lead id');\n $activity->opportunity_id = $opportunity->id;\n $activity->value = $opportunity->value;\n\n // If we are changed from an lead > account, unset the lead data.\n $activity->lead_id = null;\n }\n\n if ($contact) {\n $this->logger->info('setting contact id', ['contactId' => $contact->id]);\n $activity->contact_id = $contact->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('Unsetting lead id');\n $activity->lead_id = null;\n }\n\n $activity->is_internal = $isInternal;\n $activity->save();\n $activity->refresh();\n\n $this->logger->notice('Activity saved', [\n 'activity_id' => $activity->getId(),\n 'lead_id' => $activity->lead_id,\n 'account_id' => $activity->account_id,\n 'contact_id' => $activity->contact_id,\n 'opportunity_id' => $activity->opportunity_id,\n 'stage_id' => $activity->stage_id,\n 'crm_provider_id' => $activity->getCrmProviderId(),\n ]);\n\n // Store entities as field data on the activity.\n $updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);\n\n if ($activity->isLoggable()) {\n // Follow-up Task or Event data.\n $followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);\n\n $this->logger->info('CRM LOG manual log triggered', [\n 'activityId' => $activity->getUuid(),\n 'followupData' => $followupData,\n 'userId' => $user->getUuid(),\n ]);\n\n // Store data in the CRM.\n // ++add check for crm_required\n $job = new SaveActivity($activity, $followupData);\n\n if ($updatedData) {\n $job->delay(Carbon::now()->addMinutes($jobDelay));\n }\n\n dispatch($job);\n\n // Manually dispatch log for Opportunity or Prospect added\n if ($activity->hasOpportunity() || $activity->hasProspect()) {\n event(new ActivityProspectAdded(\n activity: $activity,\n eventSource: 'manually-log-crm-data'\n ));\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.\n *\n * @param ServiceInterface $service\n * @param Activity $activity\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array\n {\n $updatedData = [];\n $existingData = $activity->data()->get();\n\n // We need to delete any existing data to overwrite with latest values.\n $activity->data()->delete();\n\n $layoutEntities = $layout->entities()\n ->with('field', 'parent')\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->get();\n\n /** @var LayoutEntity $entity */\n foreach ($layoutEntities as $entity) {\n // If the user has provided a value for this entity\n if (array_key_exists($entity->id_string, $entities)) {\n $value = $entities[$entity->id_string];\n\n // Convert raw data into values that the CRM can consume.\n if ($value) {\n $value = $service->normalizeValue($entity->field->type, $value);\n }\n\n // Check the field is part of the activity-summary section.\n if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {\n // This is the internal database ID, not the external CRM ID.\n $objectId = null;\n\n switch ($entity->field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $objectId = $activity->account_id;\n\n break;\n\n case Field::OBJECT_CONTACT:\n $objectId = $activity->contact_id;\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n $objectId = $activity->opportunity_id;\n\n break;\n\n case Field::OBJECT_LEAD:\n $objectId = $activity->lead_id;\n\n break;\n\n case Field::OBJECT_TASK:\n case Field::OBJECT_EVENT:\n $objectId = $activity->id;\n\n break;\n }\n\n if ($objectId) {\n /** @var FieldData $data */\n $data = $activity->data()->create([\n 'crm_layout_entity_id' => $entity->id,\n 'crm_field_id' => $entity->crm_field_id,\n 'object_type' => $entity->field->object_type,\n 'object_id' => $objectId,\n 'value' => $value,\n ]);\n\n // Never send read-only field data to the CRM.\n if ($entity->read_only === false && $entity->is_visible) {\n $existingValue = $existingData\n ->where('crm_layout_entity_id', $entity->id)\n ->where('crm_field_id', $entity->crm_field_id)\n ->where('object_type', $entity->field->object_type)\n ->where('object_id', $objectId)\n ->first();\n\n // If the field was actually changed, we need to reflect this in the CRM too.\n if ($existingValue === null || $existingValue->value !== $value) {\n $updatedData[] = $data->id;\n }\n }\n }\n }\n }\n }\n\n return $updatedData;\n }\n\n /**\n * Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.\n *\n * @param ServiceInterface $crmService\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array\n {\n $fieldData = [];\n foreach ($entities as $entityId => $value) {\n // Only bother with fields that have a value.\n if ($value) {\n // Extract the entity from the UUID. Check the field is valid and part of the follow-up section.\n $entity = $layout->entities()\n ->uuid($entityId, false)\n ->whereHas('parent', function ($query) {\n $query->where('label', 'follow-up');\n })\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->first();\n\n if ($entity) {\n // Convert raw data into values that the CRM can consume.\n $value = $crmService->normalizeValue($entity->field->type, $value);\n\n // Add the field and value to the payload.\n $fieldData += [\n $entity->field->crm_provider_id => $value,\n ];\n }\n }\n }\n\n return $fieldData;\n }\n\n /**\n * @param Activity $activity\n */\n private function validateSummary(Activity $activity): void\n {\n $team = $activity->user->team;\n $crmProvider = $team->crm->provider;\n $attributes = [];\n\n $rules = [\n 'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,\n 'title' => 'string|max:250',\n 'prospects' => 'required|array',\n 'opportunity_id' => new CrmReference($crmProvider),\n 'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',\n 'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator\n 'summary' => 'max:50000',\n 'nId' => 'exists:notifications,id',\n 'crm_id' => new CrmReference($crmProvider),\n 'entities' => 'array',\n 'is_internal' => 'boolean',\n ];\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));\n\n // Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.\n $entities = $layout->entities()\n ->where('read_only', 0)\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->whereHas('parent', function ($query) use ($activity) {\n if ($activity->isLoggable() === false) {\n $query->where('label', '<>', 'follow-up');\n }\n });\n\n $isInternal = $this->request->input('is_internal', false);\n\n foreach ($entities->get() as $entity) {\n $rules += $this->buildFieldValidator($entity, $isInternal);\n $attributes += $this->buildFieldMessage($entity);\n }\n\n $this->request->validate($rules, [], $attributes);\n }\n\n private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array\n {\n return [\n 'entities.' . $entity->id_string => $entity->getValidator($isInternal),\n ];\n }\n\n /**\n * @param LayoutEntity $entity\n *\n * @return array\n */\n private function buildFieldMessage(LayoutEntity $entity): array\n {\n $label = $entity->label;\n if ($label === null) {\n $label = $entity->field->label;\n }\n\n return [\n 'entities.' . $entity->id_string => $label,\n ];\n }\n\n public function search(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->debugLog(\n $user,\n 'User extracted from request',\n ['user' => $user->getId(), 'tz' => $user->getTimezone()]\n );\n\n $searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());\n\n $this->debugLog(\n $user,\n 'ActivitySearch criteria built',\n ['searchCriteria' => $searchCriteria]\n );\n\n $filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);\n\n $this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);\n\n $this->validateSearch($request, $filterSet);\n\n $this->debugLog($user, 'Request validated');\n\n $searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);\n\n /** @var Collection<Activity> $activities */\n $activities = $searchResponse['results'];\n\n $this->debugLog($user, 'Activities ES response extracted');\n\n $hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(\n $user->getTeamId(),\n TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),\n );\n\n if ($hideInternalMeetingsSetting?->getValue() === '1') {\n $activities = $activities->filter(function (Activity $activity) {\n if ($activity->is_internal && empty($activity->actual_start_time)) {\n return false;\n }\n\n return true;\n });\n }\n\n $this->debugLog($user, 'Internal meetings (?!) filtered');\n\n $this->response->getManager()\n ->parseIncludes([\n 'category',\n 'organizer.group',\n 'prospect',\n 'stage',\n 'opportunity',\n 'stats',\n 'scorecards',\n 'masterTrack',\n 'activeParticipants',\n 'notification',\n ])\n ->setSerializer(new JsonSerializer());\n\n $transformerExcludes = $this->request->input('exclude');\n if ($transformerExcludes) {\n $this->response->getManager()->parseExcludes($transformerExcludes);\n }\n\n $this->debugLog($user, 'Response Manager (?!) applied');\n\n $transformer = new ActivityTransformer();\n $transformer->setConsumer($user);\n\n $this->debugLog($user, 'Activity Transformer added');\n\n $resource = new \\League\\Fractal\\Resource\\Collection($activities, $transformer);\n $page = $searchCriteria->getPageNumber();\n\n $this->debugLog($user, 'Search criteria page number called', ['page' => $page]);\n\n $histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');\n\n $this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);\n\n return $this->response->withArray([\n 'pagination' => [\n 'total' => $searchResponse['totalHits'],\n 'current' => $page,\n 'prev' => max($page - 1, 1),\n 'next' => $page + 1,\n ],\n 'results' => $this->response->getManager()->createData($resource)->toArray(),\n 'histogram' => $histogram,\n ]);\n }\n\n private function debugLog(User $user, string $logMessage, ?array $context = []): void\n {\n // Debug for Learning People Only\n if ($user->getTeamId() !== 260) {\n return;\n }\n\n Log::notice(\n sprintf('[activity-search-controller] %s', $logMessage),\n $context\n );\n }\n\n /** @throws ValidationException */\n private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void\n {\n $rules = [\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ];\n\n if ($prefix !== null && mb_strpos($prefix, '.') !== false) {\n $rules[rtrim($prefix, '.')] = sprintf(\n 'required|array|max:%d',\n $filterSet->count()\n );\n }\n\n $validationRules = $filterSet->getValidationRules($prefix)\n ->merge($rules)\n ->all();\n\n $request->validate($validationRules);\n }\n\n public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $search = $this->updateOrCreateActivitySearch($request);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function updateActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('update', $search);\n\n $this->updateOrCreateActivitySearch($request, $search);\n\n return $this->response->withOk();\n }\n\n private function storeNamedSearchFilters(\n Collection $request,\n Search $search,\n FilterDefinitionCollection $filterSet,\n ?string $prefix = null,\n ): self {\n $arrayTypeProperties = $filterSet\n ->getPropertyTypes([\n FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,\n ])\n ->all();\n\n $supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);\n\n foreach ($supportedRequestProperties as $requestPropertyName) {\n if (! array_has($request, $requestPropertyName)) {\n continue;\n }\n\n /** @var string|string[] $propertyValue */\n $propertyValue = array_get($request, $requestPropertyName);\n $propertyName = $prefix === null\n ? $requestPropertyName\n : mb_substr($requestPropertyName, mb_strlen($prefix));\n\n $isArrayType = array_has($arrayTypeProperties, $propertyName);\n\n if (! $isArrayType) {\n /** @var string $requestPropertyValue */\n\n $search->filters()->updateOrCreate(\n [\n 'filter' => $propertyName,\n ],\n [\n 'value' => $propertyValue,\n ]\n );\n\n continue;\n }\n\n /** @var string[] $requestPropertyValue */\n\n /** @var SearchFilter[]|Collection $existingFilterValues */\n $existingFilterValuesKeyed = $search->filters()\n ->where('filter', $propertyName)\n ->get()\n ->keyBy('id');\n\n // Iterate over values provided as request parameters\n foreach ($propertyValue as $value) {\n /** @var SearchFilter|null $valueFilter */\n $valueFilter = $search->filters()\n ->where(\n [\n 'filter' => $propertyName,\n 'value' => $value,\n ]\n )\n ->first();\n\n if ($valueFilter !== null) {\n // Remove filter value pair from list to be deleted\n $existingFilterValuesKeyed->forget($valueFilter->id);\n } else {\n // Add new filter/value pair\n $search->filters()->updateOrCreate([\n 'filter' => $propertyName,\n 'value' => $value,\n ]);\n }\n }\n\n // Delete filter value pairs for this filter that no longer exist in request parameters\n foreach ($existingFilterValuesKeyed as $existingFilter) {\n $existingFilter->delete();\n }\n }\n\n /** @var Collection<int, SearchFilter> $filtersKeyed */\n $filtersKeyed = $search->filters()->get()->keyBy('filter');\n\n // wipe removed filters from this search\n foreach ($filtersKeyed as $filterName => $filter) {\n if (array_has($request, $prefix . $filterName)) {\n continue;\n }\n\n // Remove all filter values for this filter\n $search->filters()->where('filter', $filterName)->delete();\n }\n\n return $this;\n }\n\n /**\n * @throws AuthorizationException\n */\n public function fetchActivitySearch(\n Search $search,\n Request $request,\n SearchTransformer $searchTransformer,\n ): JsonResponse {\n $this->authorize('view', $search);\n\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection(\n $user->searches()->get(),\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n /**\n * Deletes a saved search\n *\n * @param Request $request\n * @param Search $search\n *\n * @throws Exception\n *\n * @return JsonResponse\n */\n public function deleteActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('delete', $search);\n\n // Orphan any AutomatedReports that use this search\n $search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);\n\n // Delete filters and the search itself\n $search->filters()->delete();\n $search->delete();\n\n return $this->response->withOk();\n }\n\n public function live(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n $user = $this->getUserFromRequest($request);\n\n $this->request->validate([\n 'sort_direction' => 'in:asc,desc',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ]);\n\n $activities = $repository->getLiveCoachingEligibleActivities(\n user: $user,\n lookBackMinutes: self::LOOK_BACK,\n limit: (int) $this->request->input('limit', 25),\n page: (int) $this->request->input('page', 1),\n sortBy: ['actual_start_time', 'scheduled_start_time'],\n sortDirection: (string) $this->request->input('sort_direction', 'asc'),\n );\n\n $this->response\n ->getManager()\n ->parseIncludes(['organizer.group', 'prospect'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($activities, new ActivityTransformer());\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function show(Activity $activity, ActivityService $activityService): JsonResponse\n {\n $this->authorize('show', $activity);\n\n $user = $activity->getUser();\n $team = $user->getTeam();\n\n // Sync the opportunity with the latest data if possible.\n if ($activity->opportunity_id) {\n try {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n if (! $user->isCrmRequired()) {\n $crmService->setUser($team->getOwner());\n } else {\n $crmService->setUser($user);\n }\n\n $crmService->syncOpportunity($activity->opportunity->crm_provider_id);\n } catch (Exception $exception) {\n // Move on.\n }\n }\n\n $activityData = $activityService->getActivityData($this->request->user(), $activity);\n\n return response()->json($activityData);\n }\n\n public function createRecording(Activity $activity)\n {\n $this->authorize('record', $activity);\n\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Tell Twilio to start recording this activity.\n if ($activity->recording_state === Activity::RECORDING_OFF) {\n $job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withCreated();\n }\n\n return $this->response->errorGone('Activity is already recording.');\n }\n\n public function updateRecording(Request $request, Activity $activity)\n {\n $this->authorize('record', $activity);\n\n $request->validate([\n 'preference' => 'boolean',\n 'state' => [\n 'string',\n Rule::in([\n Activity::RECORDING_IN_PROGRESS,\n Activity::RECORDING_PAUSED,\n ]),\n ],\n ]);\n\n if ($request->has('state')) {\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Toggle the recording state between paused and resumed.\n if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {\n $job = (new ToggleRecording($activity, $request->input('state')))\n ->onQueue(Constants::QUEUE_CONFERENCES);\n\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Recording is not toggleable.');\n }\n\n if ($request->has('preference')) {\n $activity->update([\n 'recording_preference' => $request->input('preference') ? 1 : 0,\n ]);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorWrongArgs('Something went wrong');\n }\n\n public function stopRecording(Activity $activity)\n {\n $this->authorize('stopRecord', $activity);\n\n // Tell Twilio to stop recording this activity.\n if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {\n $job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Activity is not recording.');\n }\n\n /**\n * Add activity to this user's favorites playlist\n *\n * @throws AuthorizationException\n */\n public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse\n {\n $this->authorize('favorite', $activity);\n\n $user = $this->getUserFromRequest($this->request);\n $favorite = $activity->wasFavoritedBy($user);\n $name = $activity->activity_title ?? '';\n\n // It needs to check at least one record.\n if (! $favorite) {\n $favoritePlaylist = $user->favoritePlaylist();\n\n $playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(\n $activity,\n $user,\n $favoritePlaylist\n );\n\n if ($playlistActivity !== null) {\n $playlistActivity->update(\n // Just update, don't sort.\n ['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],\n );\n } else {\n $playlistActivity = $activity->playlistActivities()->create([\n 'playlist_id' => $favoritePlaylist->getId(),\n 'user_id' => $user->getId(),\n 'start_time' => 0,\n 'name' => mb_strimwidth($name, 0, 100),\n ]);\n // Sort it on top.\n $playlistActivity->update(\n [\n 'sort' => $playlistActivityRepository->calculateNewSortOrder(\n null,\n $playlistActivity,\n ),\n ],\n );\n }\n\n $playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);\n\n return new JsonResponse([], JsonResponse::HTTP_CREATED);\n }\n\n return new JsonResponse(\n [\n 'error' => [\n 'code' => AbstractResponse::CODE_CONFLICT,\n 'http_code' => JsonResponse::HTTP_CONFLICT,\n 'message' => 'Resource Already Exists',\n ],\n ],\n JsonResponse::HTTP_CONFLICT,\n );\n }\n\n /**\n * Remove activity from this user's favorites playlist\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unfavorite(Activity $activity)\n {\n $user = $this->request->user();\n\n $favorites = $activity->favoritedBy($user);\n\n if ($favorites && $favorites->isEmpty()) {\n return $this->response->errorNotFound('Favorite not found.');\n }\n\n $this->authorize('unfavorite', [$activity, $favorites]);\n\n // When you unfavorite an activity,\n // it should remove all the activities in it, including snippets.\n $isDeleted = $favorites->each(function ($favorite) {\n $favorite->forceDelete();\n });\n\n if ($isDeleted) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not remove favorite.');\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function notify(Activity $activity)\n {\n $this->authorize('notify', $activity);\n\n $user = $this->request->user();\n\n $existingNotification = $activity->availabilityNotifications()\n ->where('user_id', $user->id)\n ->exists();\n\n if ($existingNotification) {\n return $this->response->errorWrongArgs('Notification is already configured.');\n }\n\n $notification = Activity\\AvailabilityNotification::create([\n 'user_id' => $user->id,\n 'activity_id' => $activity->id,\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($notification, new AvailabilityNotificationTransformer());\n }\n\n /**\n * @param Activity $activity\n * @param Activity\\AvailabilityNotification $notification\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unnotify(Activity $activity, Activity\\AvailabilityNotification $notification)\n {\n $this->authorize('unnotify', [$activity, $notification]);\n\n if ($notification->sent_at || $notification->delete()) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not delete notification.');\n }\n\n public function play(Request $request, Activity $activity)\n {\n $this->authorize('stream', $activity);\n\n $request->validate([\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $activity->plays()->create([\n 'user_id' => $user->getId(),\n 'start_time' => $request->input('start_time'),\n ]);\n\n return $this->response->withCreated();\n }\n\n /**\n * @param Activity $activity\n *\n * @return mixed\n */\n public function comment(Activity $activity)\n {\n return $this->newComment($activity);\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @return mixed\n */\n public function replyComment(Activity $activity, Comment $comment)\n {\n return $this->newComment($activity, $comment);\n }\n\n /**\n * @param Activity $activity\n * @param Comment|null $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n protected function newComment(Activity $activity, ?Comment $comment = null)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n 'type' => 'integer|between:0,3',\n 'visibility' => sprintf('nullable|integer|between:1,%d', count(Comment::getVisibilityLevels())),\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n $threadStartId = null;\n if ($comment) {\n $threadStartId = $comment->thread_start_id ?: $comment->id;\n }\n\n try {\n $newComment = Comment::create([\n 'parent_comment_id' => $comment->id ?? null,\n 'thread_start_id' => $threadStartId,\n 'activity_id' => $activity->id,\n 'user_id' => $this->request->user()->id,\n 'comment' => trim($this->request->input('comment')),\n 'start_time' => $this->request->input('start_time', 0),\n 'end_time' => $this->request->input('end_time', 0),\n 'type' => $this->request->input('type', Comment::TYPE_NEUTRAL),\n 'visibility' => $this->request->input('visibility', Comment::VISIBILITY_PUBLIC),\n ]);\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($newComment, new ActivityCommentTransformer());\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not create comment.' . $exception->getMessage());\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function updateComment(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n try {\n $comment->update([\n 'comment' => trim($this->request->input('comment')),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment.');\n }\n }\n\n public function updateCommentVisibility(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'visibility' => sprintf('integer|between:1,%d', count(Comment::getVisibilityLevels())),\n ]);\n\n $visibility = $this->request->input('visibility');\n\n if ($comment->parent !== null) {\n return $this->response->errorWrongArgs('Comment visibility can only be updated on top level comments.');\n }\n\n try {\n $this->activityCommentService->updateCommentVisibility($comment, $visibility);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment\\'s visibility.');\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function deleteComment(Activity $activity, Comment $comment)\n {\n $this->authorize('deleteComment', [$activity, $comment]);\n\n // Delete comment and any children.\n $comment->delete();\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function fetchComments()\n {\n $user = $this->request->user();\n $this->request->validate([\n 'forUserId' => 'uuid:users,team_id,' . $user->team_id,\n 'types' => 'array',\n 'types.*' => 'integer|between:0,3',\n ]);\n $forUser = null;\n\n $types = [Comment::TYPE_NEUTRAL, Comment::TYPE_GAME_CHANGER, Comment::TYPE_POSITIVE];\n $user = $this->request->user();\n if ($this->request->has('forUserId')) {\n $forUser = $user->team->users()->uuid($this->request->input('forUserId'));\n }\n\n $comments = Comment::query()\n ->whereHas('activity', static function (Builder $builder) use ($user, $forUser): void {\n $builder\n // I left feedback on my own activity; or\n ->where('activities.user_id', $user->getId());\n if ($forUser) {\n // I left feedback on any activity for this user.\n $builder->orWhere([\n 'user_id' => $user->getId(),\n 'activities.user_id' => $forUser->getId(),\n ]);\n }\n })\n ->whereIn('type', $this->request->input('types', $types))\n ->orderBy('created_at', 'desc')\n ->get();\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity', 'user'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($comments, new ActivityCommentTransformer());\n }\n\n public function deleteCoachingFeedback(Activity $activity, CoachingFeedback $coachingFeedback)\n {\n $this->authorize('deleteCoachingFeedback', [$activity, $coachingFeedback]);\n $activity = $coachingFeedback->getActivity();\n\n if ($coachingFeedback->delete()) {\n event(new UpdateSingleEntity(\n entityId: $activity->getId(),\n updateTarget: UpdateTargetEnum::ACTIVITY,\n purpose: 'delete-coaching-feedback',\n ));\n\n return $this->response->withOk();\n }\n\n return $this->response->withError('Delete operation failed. Contact support.', 500);\n }\n\n /**\n * Add new or update Coaching feedback\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws \\Illuminate\\Validation\\ValidationException\n *\n * @return mixed\n */\n public function putCoachingFeedback(Request $request, Activity $activity)\n {\n $user = $request->user();\n\n if (! $user instanceof User) {\n abort(403);\n }\n $teamId = $user->getTeamId();\n\n $this->authorize('coach', $activity);\n\n $this->request->validate([\n 'coach_id' => 'required|uuid:users,team_id,' . $teamId,\n 'coachee_id' => 'required|uuid:users,team_id,' . $teamId,\n 'visibility' => ['required', Rule::in(CoachingFeedback::VISIBILITIES)],\n 'coaching_sections.*.uuid' => 'required|uuid:coaching_sections',\n 'coaching_sections.*.score' => ['required', Rule::in(CoachingSectionFeedback::SCORES)],\n 'coaching_sections.*.summary' => 'string|max:10000',\n 'coaching_sections.*.criteria.*.uuid' => 'required|uuid:coaching_section_criteria',\n 'coaching_sections.*.criteria.*.note' => 'required|string|max:10000',\n 'sharedWithUsers' => [\n 'required_if:visibility,' . CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS,\n 'array',\n ],\n 'sharedWithUsers.*' => [\n 'uuid:users,team_id,' . $teamId,\n ],\n ]);\n\n /** @var User $coach */\n $coach = User::uuid($this->request->input('coach_id'));\n /** @var User $coachee */\n $coachee = User::uuid($this->request->input('coachee_id'));\n $coachingSectionFeedbacks = $this->request->input('coaching_sections');\n\n $previousRecord = $this->coachingFeedbackRepository->getOneForActivityByCoacheeAndCoach(\n $coachee->getId(),\n $coach->getId(),\n $activity->getId()\n );\n $recordIsNew = false;\n if ($previousRecord === null) {\n $recordIsNew = true;\n }\n\n if (! $coachee->isSameTeamId($coach)) {\n return $this->response->errorForbidden('User not member of your team.');\n }\n\n if (! is_array($coachingSectionFeedbacks) || count($coachingSectionFeedbacks) < 1) {\n return $this->response->withError('At least one Coaching Framework Section shall be scored.', 422);\n }\n\n if (! $activity->participants()->where('participants.user_id', $coachee->id)->exists()) {\n return $this->response->withError('Coached user did not participate activity.', 422);\n }\n\n $visibility = $this->request->input('visibility');\n\n $shouldSendNotification = $recordIsNew;\n if ($recordIsNew === false && $visibility !== $previousRecord->getVisibility()) {\n $shouldSendNotification = true;\n }\n\n /**\n * Create CoachingFeedback\n *\n * @var CoachingFeedback $coachingFeedback\n */\n $coachingFeedback = $activity->coachingFeedbacks()->updateOrCreate(\n [\n 'coach_id' => $coach->id,\n 'coachee_id' => $coachee->id,\n ],\n [\n 'framework_id' => $activity->category->id,\n 'visibility' => $visibility,\n ]\n );\n\n $sharedUserIds = [];\n if ($visibility === CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS) {\n foreach ($this->request->input('sharedWithUsers') as $sharedWithUserUuid) {\n /** @var User $user */\n $user = User::uuid($sharedWithUserUuid);\n $sharedUserIds[] = $user->getId();\n }\n }\n\n $syncResult = $coachingFeedback->customAccessUsers()->sync($sharedUserIds);\n\n $scores = [];\n\n\n /**\n * Create CoachingSectionsFeedbacks.\n *\n * @var CoachingSectionFeedback $coachingSectionFeedback\n */\n foreach ($coachingSectionFeedbacks as $coachingSectionFeedbackInput) {\n $coachingSection = CoachingSection::uuid($coachingSectionFeedbackInput['uuid']);\n $coachingSectionFeedback = $coachingFeedback->sectionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_id' => $coachingSection->id,\n ],\n [\n 'score' => array_get($coachingSectionFeedbackInput, 'score'),\n 'summary' => array_get($coachingSectionFeedbackInput, 'summary') ?? '',\n ]\n );\n\n $scores[] = array_get($coachingSectionFeedbackInput, 'score');\n\n $criteria = array_get($coachingSectionFeedbackInput, 'criteria');\n if (is_array($criteria) && ! empty($criteria)) {\n foreach ($criteria as $criteriaFeedbackInput) {\n $coachingSectionFeedback->criterionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_criterion_id' => CoachingSectionCriterion::uuid(array_get($criteriaFeedbackInput, 'uuid'))\n ->id,\n ],\n ['note' => array_get($criteriaFeedbackInput, 'note')],\n );\n }\n }\n }\n\n $coachingFeedback->average_score = array_sum($scores) / count($scores);\n\n if ($recordIsNew === false && $coachingFeedback->getAverageScore() !== $previousRecord->getAverageScore()) {\n $shouldSendNotification = true;\n }\n if (! empty($syncResult['attached']) || ! empty($syncResult['detached']) || ! empty($syncResult['updated'])) {\n $shouldSendNotification = true;\n }\n\n $coachingFeedback->save();\n // ensure updated at for coaching feedback on section feedback summary added.\n $coachingFeedback->touch();\n\n if ($shouldSendNotification) {\n event(new Coached($coachingFeedback));\n }\n\n Datadog::increment('jiminny.activity.score.update', 1, ['company' => $activity->user->team->slug]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n $coachingFeedbackTransformer = new CoachingFeedbackTransformer();\n $coachingFeedbackTransformer->setConsumer($this->getUserFromRequest($request));\n\n return $this->response->withItem($coachingFeedback, $coachingFeedbackTransformer);\n }\n\n\n /**\n * Retrieve category criteria for coaching.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachingSections(Activity $activity)\n {\n $this->authorize('coach', $activity);\n\n if ($activity->category === null) {\n return $this->response->errorUnprocessable('Category has not yet been assigned.');\n }\n\n $criteria = $activity\n ->category\n ->coachingSections()\n ->where('is_enabled', 1)\n ->orderBy('sequence', 'asc');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($criteria->get(), new CoachingSectionsTransformer());\n }\n\n /**\n * @throws AuthorizationException\n * @throws ValidationException\n *\n * @return mixed\n */\n public function addToPlaylist(Activity $activity, PlaylistTrackFactoryInterface $playlistTrackFactory)\n {\n $this->request->validate([\n 'playlists' => 'required|array',\n 'playlists.*' => 'uuid:playlists',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'name' => 'required|max:100',\n ]);\n\n $this->authorize('addToPlaylist', [$activity, $this->request->input('playlists')]);\n\n $startTime = $this->request->input('start_time');\n $endTime = $this->request->input('end_time');\n $name = $this->request->input('name');\n /** @var User $user */\n $user = $this->request->user();\n\n // Get playlist by uuid.\n foreach ($this->request->input('playlists') as $playlistId) {\n // Pull out the playlist model.\n $playlist = Playlist::uuid($playlistId);\n\n $playlistTrackFactory->createTrack($playlist, $user, [\n 'name' => $name,\n 'activity' => $activity,\n 'start_time' => $startTime,\n 'end_time' => $endTime,\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function share(Request $request, Activity $activity): JsonResponse\n {\n $this->authorize('share', $activity);\n\n $request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'recipients.*.type' => 'in:user,group',\n 'recipients.*.id' => 'string|max:40',\n 'share' => 'string|max:255',\n ]);\n\n $user = $request->user();\n\n $recipients = $request->get('recipients');\n $users = $this->userService->convertRecipientsToUsers($user, $recipients);\n\n $shareData = [\n 'from_user_id' => $user->id,\n 'note' => $request->input('note'),\n 'start_time' => $request->input('start_time'),\n 'end_time' => $request->input('end_time'),\n ];\n\n // Create a share object against a notification provider channel\n if ($request->input('share')) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'notification_provider_channel' => $request->input('share'),\n ]\n )\n );\n\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n\n // Create a share object against each recipient\n foreach ($users as $recipient) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'to_user_id' => $recipient->id,\n ]\n )\n );\n\n // If parent_share_id has been selected yet\n if (! isset($shareData['parent_share_id'])) {\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachRequest(Activity $activity)\n {\n $this->authorize('coachRequest', $activity);\n\n $this->request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'coachers.*.type' => 'required|in:user',\n 'coachers.*.id' => 'required',\n ]);\n\n $coachers = $this->request->get('coachers');\n $user = $this->request->user();\n $users = $this->userService->convertRecipientsToUsers($user, $coachers);\n\n foreach ($users as $coacher) {\n CoachRequest::create([\n 'user_id' => $coacher->id,\n 'activity_id' => $activity->id,\n 'note' => $this->request->get('note'),\n 'start_time' => $this->request->get('start_time'),\n 'end_time' => $this->request->get('end_time'),\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function createActivityTopicTriggers(Activity $activity, LoggerInterface $logger): HttpFoundation\\JsonResponse\n {\n $this->authorize('analyzeTopicTriggers', $activity);\n\n if (! $activity->hasTranscription()) {\n return new HttpFoundation\\JsonResponse(\n [\n 'error' => 'Transcription not found.',\n ],\n JsonResponse::HTTP_NOT_FOUND\n );\n }\n\n $logger->info(__METHOD__ . ': queued for analysis', [\n 'activity' => $activity->id_string,\n ]);\n\n dispatch(new ActivityAnalytics\\Job\\AnalyzeActivityTopicTriggers($activity));\n\n return new HttpFoundation\\JsonResponse(null, JsonResponse::HTTP_CREATED);\n }\n\n public function fetchActivityTopicTriggers(\n Activity $activity,\n LoggerInterface $logger,\n ActivityTopicTriggerTransformer $transformer\n ): HttpFoundation\\JsonResponse {\n $this->authorize('fetchTopicTriggers', $activity);\n\n $logger->debug(__METHOD__, [\n 'activity' => $activity->id_string,\n ]);\n\n if (! $activity->isProcessed()) {\n return new HttpFoundation\\JsonResponse([]);\n }\n\n $payload = [];\n\n if ($activity->hasTopicTriggers()) {\n $payload = $activity->getTopicTriggersSorted()\n ->map(\n static fn (Activity\\TopicTrigger $activityTopicTrigger): array\n => $transformer->transform($activityTopicTrigger)\n )\n ->values()\n ->all();\n }\n\n return new HttpFoundation\\JsonResponse($payload);\n }\n\n /**\n * @param Activity $activity\n * @param StatsTransformer $statsTransformer\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function stats(Activity $activity, StatsTransformer $statsTransformer)\n {\n $this->authorize('stream', $activity);\n\n if (! $activity->hasTranscription()) {\n return $this->response->errorNotFound('Waveform data is not yet generated.');\n }\n\n $this->response\n ->getManager()\n ->parseIncludes(['wavedata'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($activity, $statsTransformer);\n }\n\n public function destroy(Activity $activity)\n {\n $this->authorize('delete', $activity);\n\n $activity->delete();\n\n \\Log::info('Soft delete activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n\n return $this->response->withNoContent();\n }\n\n public function note(Activity $activity)\n {\n $this->authorize('note', $activity);\n\n $this->request->validate([\n 'note' => 'required|min:1|max:2000',\n 'time' => 'required|numeric|min:0|max:86400',\n ]);\n\n $note = $this->request->input('note');\n $time = $this->request->input('time');\n\n $this->activityService->setActivity($activity);\n $this->activityService->takeNote($this->getUser(), $note, $time);\n\n return $this->response->withCreated();\n }\n\n /**\n * Mark an activity as private.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPrivate(Activity $activity)\n {\n $this->authorize('markAsPrivate', $activity);\n\n if ($activity->is_private === false) {\n $activity->is_private = true;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * Mark an activity as public.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPublic(Activity $activity)\n {\n $this->authorize('markAsPublic', $activity);\n\n if ($activity->is_private) {\n $activity->is_private = false;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws LogicException\n */\n public function fetchCloudFrontS3MediaKeys(Activity $activity, PlaybackService $playbackService): JsonResponse\n {\n $masterTrack = $activity->masterTrack()->first();\n\n if (! $masterTrack instanceof Track) {\n throw new LogicException(sprintf('Master track not found for activity \"%s\"', $activity->getUuid()));\n }\n\n return $this->response->withArray(\n $playbackService->generateCookies(\n $masterTrack,\n $this->request->ip(),\n ),\n );\n }\n\n /**\n * @throws ValidationException\n */\n private function updateOrCreateActivitySearch(Request $request, ?Search $search = null): Search\n {\n $request->validate([\n 'name' => 'required|string|min:2|max:100',\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $searchName = $request->input('name');\n\n if ($search !== null) {\n $search->update([\n 'name' => $searchName,\n ]);\n\n return $search;\n }\n\n $request->validate([\n 'filters' => ['required', 'array', new MultidimensionalArrayMaxCharRule(limit: 255)],\n 'nudges' => 'array|max:' . count(Nudge::MAP_CHANNEL),\n 'nudges.*.channel' => 'required|in:' . implode(',', Nudge::MAP_CHANNEL),\n 'nudges.*.frequency' => 'required|in:' . implode(',', Nudge::MAP_FREQUENCY),\n 'nudges.*.expiresAt' => [\n 'required',\n 'date',\n 'after:today',\n 'before_or_equal:' . now()->addYear()->format('Y-m-d'),\n ],\n ]);\n\n $searchCriteria = Criteria::createFromRequest(\n Collection::make($request->input('filters', []))->all(),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($searchCriteria, $user);\n $this->validateSearch($request, $filterSet, 'filters.');\n\n /** @var Search $search */\n $search = Search::create([\n 'name' => $searchName,\n 'uuid' => Uuid::uuid4()->toString(),\n 'user_id' => $user->getId(),\n ]);\n\n Collection::make($request->input('nudges', []))\n ->each(fn (array $attributes): Nudge => $this->nudgeFactory->createNudge($search, $attributes));\n\n $this->storeNamedSearchFilters(Collection::make($request->all()), $search, $filterSet, 'filters.');\n\n return $search;\n }\n\n private function resolveAccount(\n Team $team,\n Contact $contact,\n ServiceInterface $crmService,\n array $prospects,\n ): ?Account {\n $this->logger->info('Resolving account from contact');\n $account = $contact->getAccount();\n\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS)) {\n $this->logger->info('Team does not have feature to link activity to multiple prospects');\n\n return $account;\n }\n\n $this->logger->info('Resolving account from prospect data');\n $accountData = array_filter(\n $prospects,\n static fn (array $prospectData): bool => $prospectData['type'] === 'account'\n );\n\n if (! empty($accountData)) {\n $this->logger->info('Found account data in prospects');\n $accountData = reset($accountData);\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountData['id'])->first();\n\n if (! $account instanceof Account) {\n $this->logger->info('Account not found in database, syncing from CRM');\n $account = $crmService->syncAccount($accountData['id']);\n }\n }\n\n $this->logger->info('Resolved account', ['account' => $account->getId()]);\n\n return $account;\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}]...
|
-7287184300264252456
|
-8385861013499833196
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use Carbon\Carbon;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\In;
use Illuminate\Validation\ValidationException;
use InvalidArgumentException;
use Jiminny\Component\ActivityAnalytics;
use Jiminny\Component\ActivitySearch;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Queue\Constants;
use Jiminny\Contracts\ES\Events\UpdateSingleEntity;
use Jiminny\Contracts\ES\UpdateTargetEnum;
use Jiminny\Contracts\Nudge\NudgeFactoryInterface;
use Jiminny\Contracts\Playlist\PlaylistTrackFactoryInterface;
use Jiminny\Contracts\Repositories\PlaylistActivityRepository;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Enums\TeamSetting;
use Jiminny\Events\Activities\AiAutomation\ActivityProspectAdded;
use Jiminny\Events\Activities\Coaching\Coached;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Controllers\CommentContextInterface;
use Jiminny\Http\Responses\Api\AbstractResponse;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\ActivityCommentTransformer;
use Jiminny\Http\Transformers\ActivityTopicTriggerTransformer;
use Jiminny\Http\Transformers\ActivityTransformer;
use Jiminny\Http\Transformers\AvailabilityNotificationTransformer;
use Jiminny\Http\Transformers\CoachingFeedbackTransformer;
use Jiminny\Http\Transformers\CoachingSectionsTransformer;
use Jiminny\Http\Transformers\SearchTransformer;
use Jiminny\Http\Transformers\StatsTransformer;
use Jiminny\Jobs\Crm\SaveActivity;
use Jiminny\Jobs\Crm\UpdateStage;
use Jiminny\Jobs\Telephony\StartRecording;
use Jiminny\Jobs\Telephony\StopRecording;
use Jiminny\Jobs\Telephony\ToggleRecording;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\CoachingFeedback;
use Jiminny\Models\CoachingSection;
use Jiminny\Models\CoachingSectionCriterion;
use Jiminny\Models\CoachingSectionFeedback;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\LanguageDialect;
use Jiminny\Models\Lead;
use Jiminny\Models\Nudge;
use Jiminny\Models\PlaybookCategory;
use Jiminny\Models\Playlist;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\Track;
use Jiminny\Models\User;
use Jiminny\Repositories\CoachingFeedbackRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Rules\CrmReference;
use Jiminny\Rules\MultidimensionalArrayMaxCharRule;
use Jiminny\Services\ActivityService;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Services\PlaybackService;
use Jiminny\Services\UserService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
use Ramsey\Uuid\Uuid;
use Sentry;
use Symfony\Component\HttpFoundation;
final class ActivityController extends Controller implements CommentContextInterface
{
// Number of minutes to look back on activities. i.e. a timeout on activity duration.
private const int LOOK_BACK = 180;
public function __construct(
private ProviderRegistry $providerRegistry,
private ActivityService $activityService,
Response $response,
private UserService $userService,
private ActivitySearch\Service\ActivitySearch $activitySearch,
private NudgeFactoryInterface $nudgeFactory,
private ActivityCommentService $activityCommentService,
private LoggerInterface $logger,
private readonly CoachingFeedbackRepository $coachingFeedbackRepository,
private readonly TeamRepository $teamRepository,
) {
parent::__construct($response);
}
public static function getCommentImplementation(): string
{
return Comment::class;
}
public function delete()
{
$this->request->validate([
'*' => 'uuid:activities',
]);
$deletedIds = [];
foreach ($this->request->all() as $activityId) {
$activity = Activity::idOrUuId($activityId);
try {
if ($this->authorize('delete', $activity)) {
$activity->delete();
$deletedIds[] = $activityId;
\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);
}
} catch (AuthorizationException $authorizationException) {
// They didn't have permission.
}
}
return $this->response->withArray($deletedIds);
}
public function update(Request $request, Activity $activity)
{
$this->authorize('updateMetadata', $activity);
$request->validate([
'title' => 'string|max:250',
'category_id' => 'uuid:playbook_categories',
'language' => [
new In(
LanguageDialect::query()
->with('language')
->cursor()
->map(static function (LanguageDialect $languageDialect): string {
return $languageDialect->getLanguageLocale();
})
->all()
),
],
]);
if ($request->has('title')) {
$activity->title = $request->input('title');
}
if ($request->has('category_id')) {
$category = PlaybookCategory::uuid($request->input('category_id'));
if ($category->playbook->team_id !== $request->user()->team_id) {
return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
if ($request->has('language')) {
if (! $activity->isInProgress()) {
return $this->response->withError(
'Activity language can only be set while the meeting is in progress.',
400
);
}
$activity->setLanguageCode($request->input('language'));
}
$activity->save();
return $this->response->withOk();
}
// XXX: This should be merged with the update method.
/**
* @param Activity $activity
*
* @throws AuthorizationException
* @throws SocialAccountTokenInvalidException
*
* @return mixed
*/
public function summarize(Activity $activity): mixed
{
$this->logger->info('[Log Activity] Summarizing activity ', [
'activityId' => $activity->getUuid(),
'payload' => $this->request->all(),
]);
$this->authorize('update', $activity);
$this->logger->info('[Log Activity] Validating summary');
// Validate the payload.
$this->validateSummary($activity);
// All objects must belong to this team.
/** @var User $user */
$user = $this->request->user();
$team = $user->getTeam();
$crmService = $this->providerRegistry->get($team->crm->provider);
try {
$crmUser = $user;
if ($user->isCrmRequired() === false) {
$crmUser = $team->owner;
}
$crmService->setUser($crmUser);
} catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());
}
$rawEntities = $this->request->input('entities');
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid(
$this->request->input('layout_id')
);
// Delay execution of CRM jobs to avoid locking issues.
$jobDelay = 0;
// If we have arrived from a notification, mark it as read.
$notificationId = $this->request->input('nId');
if ($notificationId) {
$notification = $user->unreadNotifications->where('id', $notificationId)->first();
if ($notification) {
$notification->markAsRead();
}
}
$title = $this->request->input('title');
$prospects = $this->request->input('prospects');
$opportunityId = $this->request->input('opportunity_id');
$stageId = $this->request->input('stage_id');
$categoryId = $this->request->input('category_id');
$summary = $this->request->input('summary');
$crmProviderId = $this->request->input('crm_id');
$isInternal = $this->request->input('is_internal') ?? false;
$lead = null;
$category = null;
$account = null;
$contact = null;
$opportunity = null;
$stage = null;
$callStage = null;
foreach ($prospects as $prospectData) {
$objectId = $prospectData['id'];
if ($objectId === null) {
continue;
}
$objectType = $prospectData['type'];
$this->logger->info('debug', ['prospect_data' => $prospectData]);
try {
if ($objectType === null) {
$this->logger->info('no object type');
if ($crmService instanceof SupportsObjectTypeParseInterface) {
$objectType = $crmService->parseObjectType($objectId);
}
}
switch ($objectType) {
case 'lead':
$this->logger->info('Processing lead');
/** @var Lead|null $lead */
$lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();
// Lead does not exist locally, import it.
if ($lead === null) {
$this->logger->info('Lead does not exist locally');
/** @var Lead $lead */
$lead = $crmService->syncLead($objectId);
}
$this->logger->info('Lead found', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
if ($stageId === null) {
$this->logger->info('Stage ID is null');
// If it was not provided, just assume it is the current stage.
$callStage = $lead->stage;
break;
}
$this->logger->info('Looking for stage');
// Determine if they have changed the stage.
/** @var Stage $stage */
$stage = $team->crm->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_LEAD)
->firstOrFail();
$this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);
if ($lead->stage_id && $lead->stage_id !== $stage->id) {
$this->logger->info('Stage has changed');
// Storage current stage on activity.
$callStage = $lead->stage;
// The stage has changed, update in remote CRM.
dispatch(new UpdateStage($activity, $lead, $callStage, $stage));
$this->logger->info(
sprintf(
'[%s] User changing lead stage from %s to %s',
$crmService->getDisplayName(),
$callStage->getName(),
$stage->getName()
),
[
'user' => $user->getUuid(),
'lead' => $lead->getUuid(),
]
);
} else {
$this->logger->info('Stage has not changed');
// Stage remains as current.
$callStage = $stage;
}
break;
case 'account':
$this->logger->info('Processing account');
// If the object is not a lead, it should be an account.
$account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();
// Account does not exist locally, import it.
if ($account === null) {
$this->logger->info('Account does not exist locally');
$account = $crmService->syncAccount($objectId);
}
$this->logger->info('Account found', ['accountId' => $account->id]);
break;
case 'contact':
$this->logger->info('processing contact');
$contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$this->logger->info('contact does not exist locally');
$contact = $crmService->syncContact($objectId);
}
$this->logger->info('resolving account');
$account = $this->resolveAccount($team, $contact, $crmService, $prospects);
break;
}
// If they have specified an opportunity, retrieve this with stage.
if ($opportunityId) {
$this->logger->info('opportunity id is set');
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if ($opportunity === null) {
$this->logger->info('opportunity does not exist locally');
$opportunity = $crmService->syncOpportunity($opportunityId);
}
if ($stageId === null) {
$this->logger->info('stage id is null');
// If it was not provided, just assume it is the current stage.
$callStage = $opportunity->stage ?? null;
} else {
$this->logger->info('looking for stage');
/** @var ?Stage $opportunityStage */
$opportunityStage = $team->crm
->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
// There is a chance we still cannot import this opportunity.
if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {
$this->logger->info('opportunity stage has changed');
// Storage current stage on activity.
$callStage = $opportunity->stage;
dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));
$this->logger->info(
sprintf(
'[%s] User changing opportunity stage from %s to %s',
$crmService->getDisplayName(),
$callStage->name,
$opportunityStage->name
),
[
'userId' => $user->id_string,
'opportunityId' => $opportunity->id_string,
]
);
} else {
$this->logger->info('opportunity stage has not changed');
// Stage remains as current.
$callStage = $opportunityStage;
}
}
}
if ($crmProviderId) {
// Cast $crmProviderId to string otherwise it won't use database index for some records
$linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();
// Check if this activity has already been assigned to a different activity.
if ($linkedActivity && $linkedActivity->id !== $activity->id) {
throw new InvalidArgumentException(
'Sorry, the linked task has already been logged under a different call. '
. 'Please choose another linked task.'
);
}
}
} catch (InvalidArgumentException $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($exception->getMessage());
} catch (Exception $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorInternalError(
'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'
);
}
}
if ($categoryId) {
$category = PlaybookCategory::uuid($categoryId);
if ($category->playbook->team_id !== $team->id) {
throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
$this->logger->info('Prospect data', [
'lead_id' => $lead?->getId(),
'account_id' => $account?->getId(),
'contact_id' => $contact?->getId(),
'opportunity_id' => $opportunity?->getId(),
'stage_id' => $stage?->getId(),
]);
if ($title) {
$activity->title = $title;
}
if ($summary) {
$activity->summary = $summary;
}
if ($crmProviderId) {
$activity->crm_provider_id = $crmProviderId;
}
if ($callStage) {
$this->logger->info('Setting stage id', ['stageId' => $callStage->id]);
$activity->stage_id = $callStage->id;
}
if ($lead) {
$this->logger->info('Setting lead id', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
// If we are changed from an account > lead, unset the account data.
$this->logger->info('Unsetting account id, opportunity id, contact id, value');
$activity->account_id = null;
$activity->opportunity_id = null;
$activity->contact_id = null;
$activity->value = null;
}
if ($account) {
$this->logger->info('Setting account id', ['accountId' => $account->id]);
$activity->account_id = $account->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('unsetting lead id');
$activity->lead_id = null;
// Unset the contact if switching different accounts. Will be set up below if still applicable.
if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {
$this->logger->info('Unsetting contact id');
$activity->contact_id = null;
}
}
if ($opportunity) {
$this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);
$this->logger->info('unsetting lead id');
$activity->opportunity_id = $opportunity->id;
$activity->value = $opportunity->value;
// If we are changed from an lead > account, unset the lead data.
$activity->lead_id = null;
}
if ($contact) {
$this->logger->info('setting contact id', ['contactId' => $contact->id]);
$activity->contact_id = $contact->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('Unsetting lead id');
$activity->lead_id = null;
}
$activity->is_internal = $isInternal;
$activity->save();
$activity->refresh();
$this->logger->notice('Activity saved', [
'activity_id' => $activity->getId(),
'lead_id' => $activity->lead_id,
'account_id' => $activity->account_id,
'contact_id' => $activity->contact_id,
'opportunity_id' => $activity->opportunity_id,
'stage_id' => $activity->stage_id,
'crm_provider_id' => $activity->getCrmProviderId(),
]);
// Store entities as field data on the activity.
$updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);
if ($activity->isLoggable()) {
// Follow-up Task or Event data.
$followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);
$this->logger->info('CRM LOG manual log triggered', [
'activityId' => $activity->getUuid(),
'followupData' => $followupData,
'userId' => $user->getUuid(),
]);
// Store data in the CRM.
// ++add check for crm_required
$job = new SaveActivity($activity, $followupData);
if ($updatedData) {
$job->delay(Carbon::now()->addMinutes($jobDelay));
}
dispatch($job);
// Manually dispatch log for Opportunity or Prospect added
if ($activity->hasOpportunity() || $activity->hasProspect()) {
event(new ActivityProspectAdded(
activity: $activity,
eventSource: 'manually-log-crm-data'
));
}
}
return $this->response->withOk();
}
/**
* Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.
*
* @param ServiceInterface $service
* @param Activity $activity
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array
{
$updatedData = [];
$existingData = $activity->data()->get();
// We need to delete any existing data to overwrite with latest values.
$activity->data()->delete();
$layoutEntities = $layout->entities()
->with('field', 'parent')
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->get();
/** @var LayoutEntity $entity */
foreach ($layoutEntities as $entity) {
// If the user has provided a value for this entity
if (array_key_exists($entity->id_string, $entities)) {
$value = $entities[$entity->id_string];
// Convert raw data into values that the CRM can consume.
if ($value) {
$value = $service->normalizeValue($entity->field->type, $value);
}
// Check the field is part of the activity-summary section.
if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {
// This is the internal database ID, not the external CRM ID.
$objectId = null;
switch ($entity->field->object_type) {
case Field::OBJECT_ACCOUNT:
$objectId = $activity->account_id;
break;
case Field::OBJECT_CONTACT:
$objectId = $activity->contact_id;
break;
case Field::OBJECT_OPPORTUNITY:
$objectId = $activity->opportunity_id;
break;
case Field::OBJECT_LEAD:
$objectId = $activity->lead_id;
break;
case Field::OBJECT_TASK:
case Field::OBJECT_EVENT:
$objectId = $activity->id;
break;
}
if ($objectId) {
/** @var FieldData $data */
$data = $activity->data()->create([
'crm_layout_entity_id' => $entity->id,
'crm_field_id' => $entity->crm_field_id,
'object_type' => $entity->field->object_type,
'object_id' => $objectId,
'value' => $value,
]);
// Never send read-only field data to the CRM.
if ($entity->read_only === false && $entity->is_visible) {
$existingValue = $existingData
->where('crm_layout_entity_id', $entity->id)
->where('crm_field_id', $entity->crm_field_id)
->where('object_type', $entity->field->object_type)
->where('object_id', $objectId)
->first();
// If the field was actually changed, we need to reflect this in the CRM too.
if ($existingValue === null || $existingValue->value !== $value) {
$updatedData[] = $data->id;
}
}
}
}
}
}
return $updatedData;
}
/**
* Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.
*
* @param ServiceInterface $crmService
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array
{
$fieldData = [];
foreach ($entities as $entityId => $value) {
// Only bother with fields that have a value.
if ($value) {
// Extract the entity from the UUID. Check the field is valid and part of the follow-up section.
$entity = $layout->entities()
->uuid($entityId, false)
->whereHas('parent', function ($query) {
$query->where('label', 'follow-up');
})
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->first();
if ($entity) {
// Convert raw data into values that the CRM can consume.
$value = $crmService->normalizeValue($entity->field->type, $value);
// Add the field and value to the payload.
$fieldData += [
$entity->field->crm_provider_id => $value,
];
}
}
}
return $fieldData;
}
/**
* @param Activity $activity
*/
private function validateSummary(Activity $activity): void
{
$team = $activity->user->team;
$crmProvider = $team->crm->provider;
$attributes = [];
$rules = [
'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,
'title' => 'string|max:250',
'prospects' => 'required|array',
'opportunity_id' => new CrmReference($crmProvider),
'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',
'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator
'summary' => 'max:50000',
'nId' => 'exists:notifications,id',
'crm_id' => new CrmReference($crmProvider),
'entities' => 'array',
'is_internal' => 'boolean',
];
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));
// Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.
$entities = $layout->entities()
->where('read_only', 0)
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->whereHas('parent', function ($query) use ($activity) {
if ($activity->isLoggable() === false) {
$query->where('label', '<>', 'follow-up');
}
});
$isInternal = $this->request->input('is_internal', false);
foreach ($entities->get() as $entity) {
$rules += $this->buildFieldValidator($entity, $isInternal);
$attributes += $this->buildFieldMessage($entity);
}
$this->request->validate($rules, [], $attributes);
}
private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array
{
return [
'entities.' . $entity->id_string => $entity->getValidator($isInternal),
];
}
/**
* @param LayoutEntity $entity
*
* @return array
*/
private function buildFieldMessage(LayoutEntity $entity): array
{
$label = $entity->label;
if ($label === null) {
$label = $entity->field->label;
}
return [
'entities.' . $entity->id_string => $label,
];
}
public function search(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->debugLog(
$user,
'User extracted from request',
['user' => $user->getId(), 'tz' => $user->getTimezone()]
);
$searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());
$this->debugLog(
$user,
'ActivitySearch criteria built',
['searchCriteria' => $searchCriteria]
);
$filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);
$this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);
$this->validateSearch($request, $filterSet);
$this->debugLog($user, 'Request validated');
$searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);
/** @var Collection<Activity> $activities */
$activities = $searchResponse['results'];
$this->debugLog($user, 'Activities ES response extracted');
$hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(
$user->getTeamId(),
TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),
);
if ($hideInternalMeetingsSetting?->getValue() === '1') {
$activities = $activities->filter(function (Activity $activity) {
if ($activity->is_internal && empty($activity->actual_start_time)) {
return false;
}
return true;
});
}
$this->debugLog($user, 'Internal meetings (?!) filtered');
$this->response->getManager()
->parseIncludes([
'category',
'organizer.group',
'prospect',
'stage',
'opportunity',
'stats',
'scorecards',
'masterTrack',
'activeParticipants',
'notification',
])
->setSerializer(new JsonSerializer());
$transformerExcludes = $this->request->input('exclude');
if ($transformerExcludes) {
$this->response->getManager()->parseExcludes($transformerExcludes);
}
$this->debugLog($user, 'Response Manager (?!) applied');
$transformer = new ActivityTransformer();
$transformer->setConsumer($user);
$this->debugLog($user, 'Activity Transformer added');
$resource = new \League\Fractal\Resource\Collection($activities, $transformer);
$page = $searchCriteria->getPageNumber();
$this->debugLog($user, 'Search criteria page number called', ['page' => $page]);
$histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');
$this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);
return $this->response->withArray([
'pagination' => [
'total' => $searchResponse['totalHits'],
'current' => $page,
'prev' => max($page - 1, 1),
'next' => $page + 1,
],
'results' => $this->response->getManager()->createData($resource)->toArray(),
'histogram' => $histogram,
]);
}
private function debugLog(User $user, string $logMessage, ?array $context = []): void
{
// Debug for Learning People Only
if ($user->getTeamId() !== 260) {
return;
}
Log::notice(
sprintf('[activity-search-controller] %s', $logMessage),
$context
);
}
/** @throws ValidationException */
private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void
{
$rules = [
'exclude' => 'array',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
];
if ($prefix !== null && mb_strpos($prefix, '.') !== false) {
$rules[rtrim($prefix, '.')] = sprintf(
'required|array|max:%d',
$filterSet->count()
);
}
$validationRules = $filterSet->getValidationRules($prefix)
->merge($rules)
->all();
$request->validate($validationRules);
}
public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$search = $this->updateOrCreateActivitySearch($request);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function updateActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('update', $search);
$this->updateOrCreateActivitySearch($request, $search);
return $this->response->withOk();
}
private function storeNamedSearchFilters(
Collection $request,
Search $search,
FilterDefinitionCollection $filterSet,
?string $prefix = null,
): self {
$arrayTypeProperties = $filterSet
->getPropertyTypes([
FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,
])
->all();
$supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);
foreach ($supportedRequestProperties as $requestPropertyName) {
if (! array_has($request, $requestPropertyName)) {
continue;
}
/** @var string|string[] $propertyValue */
$propertyValue = array_get($request, $requestPropertyName);
$propertyName = $prefix === null
? $requestPropertyName
: mb_substr($requestPropertyName, mb_strlen($prefix));
$isArrayType = array_has($arrayTypeProperties, $propertyName);
if (! $isArrayType) {
/** @var string $requestPropertyValue */
$search->filters()->updateOrCreate(
[
'filter' => $propertyName,
],
[
'value' => $propertyValue,
]
);
continue;
}
/** @var string[] $requestPropertyValue */
/** @var SearchFilter[]|Collection $existingFilterValues */
$existingFilterValuesKeyed = $search->filters()
->where('filter', $propertyName)
->get()
->keyBy('id');
// Iterate over values provided as request parameters
foreach ($propertyValue as $value) {
/** @var SearchFilter|null $valueFilter */
$valueFilter = $search->filters()
->where(
[
'filter' => $propertyName,
'value' => $value,
]
)
->first();
if ($valueFilter !== null) {
// Remove filter value pair from list to be deleted
$existingFilterValuesKeyed->forget($valueFilter->id);
} else {
// Add new filter/value pair
$search->filters()->updateOrCreate([
'filter' => $propertyName,
'value' => $value,
]);
}
}
// Delete filter value pairs for this filter that no longer exist in request parameters
foreach ($existingFilterValuesKeyed as $existingFilter) {
$existingFilter->delete();
}
}
/** @var Collection<int, SearchFilter> $filtersKeyed */
$filtersKeyed = $search->filters()->get()->keyBy('filter');
// wipe removed filters from this search
foreach ($filtersKeyed as $filterName => $filter) {
if (array_has($request, $prefix . $filterName)) {
continue;
}
// Remove all filter values for this filter
$search->filters()->where('filter', $filterName)->delete();
}
return $this;
}
/**
* @throws AuthorizationException
*/
public function fetchActivitySearch(
Search $search,
Request $request,
SearchTransformer $searchTransformer,
): JsonResponse {
$this->authorize('view', $search);
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withCollection(
$user->searches()->get(),
$searchTransformer
->withConsumer($user)
);
}
/**
* Deletes a saved search
*
* @param Request $request
* @param Search $search
*
* @throws Exception
*
* @return JsonResponse
*/
public function deleteActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('delete', $search);
// Orphan any AutomatedReports that use this search
$search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);
// Delete filters and the search itself
$search->filters()->delete();
$search->delete();
return $this->response->withOk();
}
public function live(Request $request, ElasticActivityRepository $repository): JsonResponse
{
$user = $this->getUserFromRequest($request);
$this->request->validate([
'sort_direction' => 'in:asc,desc',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
]);
$activities = $repository->getLiveCoachingEligibleActivities(
user: $user,
lookBackMinutes: self::LOOK_BACK,
limit: (int) $this->request->input('limit', 25),
page: (int) $this->request->input('page', 1),
sortBy: ['actual_start_time', 'scheduled_start_time'],
sortDirection: (string) $this->request->input('sort_direction', 'asc'),
);
$this->response
->getManager()
->parseIncludes(['organizer.group', 'prospect'])
->setSerializer(new JsonSerializer());
return $this->response->withCollection($activities, new ActivityTransformer());
}
/**
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function show(Activity $activity, ActivityService $activityService): JsonResponse
{
$this->authorize('show', $activity);
$user = $activity->getUser();
$team = $user->getTeam();
// Sync the opportunity with the latest data if possible.
if ($activity->opportunity_id) {
try {
$crmService = $this->providerRegistry->get($team->crm->provider);
if (! $user->isCrmRequired()) {
$crmService->setUser($team->getOwner());
} else {
$crmService->setUser($user);
}
$crmService->syncOpportunity($activity->opportunity->crm_provider_id);
} catch (Exception $exception) {
// Move on.
}
}
$activityData = $activityService->getActivityData($this->request->user(), $activity);
return response()->json($activityData);
}
public function createRecording(Activity $activity)
{
$this->authorize('record', $activity);
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Tell Twilio to start recording this activity.
if ($activity->recording_state === Activity::RECORDING_OFF) {
$job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withCreated();
}
return $this->response->errorGone('Activity is already recording.');
}
public function updateRecording(Request $request, Activity $activity)
{
$this->authorize('record', $activity);
$request->validate([
'preference' => 'boolean',
'state' => [
'string',
Rule::in([
Activity::RECORDING_IN_PROGRESS,
Activity::RECORDING_PAUSED,
]),
],
]);
if ($request->has('state')) {
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Toggle the recording state between paused and resumed.
if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {
$job = (new ToggleRecording($activity, $request->input('state')))
->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Recording is not toggleable.');
}
if ($request->has('preference')) {
$activity->update([
'recording_preference' => $request->input('preference') ? 1 : 0,
]);
return $this->response->withOk();
}
return $this->response->errorWrongArgs('Something went wrong');
}
public function stopRecording(Activity $activity)
{
$this->authorize('stopRecord', $activity);
// Tell Twilio to stop recording this activity.
if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {
$job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Activity is not recording.');
}
/**
* Add activity to this user's favorites playlist
*
* @throws AuthorizationException
*/
public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse
{
$this->authorize('favorite', $activity);
$user = $this->getUserFromRequest($this->request);
$favorite = $activity->wasFavoritedBy($user);
$name = $activity->activity_title ?? '';
// It needs to check at least one record.
if (! $favorite) {
$favoritePlaylist = $user->favoritePlaylist();
$playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(
$activity,
$user,
$favoritePlaylist
);
if ($playlistActivity !== null) {
$playlistActivity->update(
// Just update, don't sort.
['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],
);
} else {
$playlistActivity = $activity->playlistActivities()->create([
'playlist_id' => $favoritePlaylist->getId(),
'user_id' => $user->getId(),
'start_time' => 0,
'name' => mb_strimwidth($name, 0, 100),
]);
// Sort it on top.
$playlistActivity->update(
[
'sort' => $playlistActivityRepository->calculateNewSortOrder(
null,
$playlistActivity,
),
],
);
}
$playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);
return new JsonResponse([], JsonResponse::HTTP_CREATED);
}
return new JsonResponse(
[
'error' => [
'code' => AbstractResponse::CODE_CONFLICT,
'http_code' => JsonResponse::HTTP_CONFLICT,
'message' => 'Resource Already Exists',
],
],
JsonResponse::HTTP_CONFLICT,
);
}
/**
* Remove activity from this user's favorites playlist
*
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function unfavorite(Activity $activity)
{
$user = $t...
|
32865
|
NULL
|
NULL
|
NULL
|
|
32868
|
NULL
|
0
|
2026-05-13T09:42:46.258058+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665366258_m2.jpg...
|
PhpStorm
|
faVsco.js – ActivityController.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.034242023,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
8243381250999052583
|
-8204424741936591934
|
idle
|
hybrid
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
PhostormProiect vVIeWINavicareCodeLaravelKeractorTOOISWindowFV faVsco.js"9 master~(C ActivityController.pnp|aravel.l0gA SF (jiminny@localhost]4 HS_local [jiminny@localhost]& console (PROD] X A console [EU]D Teaminsights, m Themesv D UserAutomatedRep -007final class ActivityController extends Controller implements CommentContextInterfaceA console [STAGING]v Dv2c) ACuviLyvzconuroAskAnythingCorLL0/(C) AskJiminnyRepc© DealsV2Controll 410%(C) OnDemandV2Cc€ PlavlistControlleC) PlavlistSharecorC PlavlistTrackCor111131114(C) UoloadControlleC) [EMAIL]) AiCrmNotesControl(c) Rasecontroller nhn@ ClientTokenControl 1157(e) CrmController.pnp11158© DealLevelPromptsC 115$c) DealRiskcontroller.@ InctantMeetinaCont 116111164C) Languagecontrolle© LayoutManagemen 1163Ca) livoCoodControllor1164 |9© MeetingsController 1192© MessageController. 1193 l >C MotadataControllor L214© MobileSettingsCont 1212 (g >© MomentController.r 125gc) Nudgecontroller.phNumberAllocatorCc 12/e11271OraanizationMembi 1212C) OraanizationRetentC) OraanizationSvnce@ PartnerController.o1276 1g) PlavbackController1133480 PlavlictController pl 1335g ScimController.nhn9) SidekickController , 13379a) SoftnhoneControlle© SsoController.php(e) CnbccrintionGontrae ToamAiAutomationt6) ToamAiContovtCar0 ToamControllor nhr 1343 (@9 >public function ListActivitySearch(Request Srequest, SearchTransformer SsearchTransformer): JsonResponses: 569— 571* Deletes a saved search— 573* @param Request $request* apanam Search $search575* achrows except1or* drecurn Jsonkesponse-57%578579— 580pubLic tunccion deleteActivicysearch kequest srequest, search ssearch: Jsonkesponse.582oubunc tunction uivelrequest srequest, clastcactIvirvkedosirory srepostrory: usonkesponse....* dparam Activitu Sactivitu*Gthrows_AuthorizationExcent.ion589* Greturn mixedpublic function show(Activity Sactivity, ActivityService $activityService): JsonResponse{...}public function createRecordingActivity Sactivity)i...h597593594public function updateRecording(Request Srequest, Activity $activity)1...h~ 596public function stopRecording(Activity Sactivity)(...}* Add activity to this user's favorites playlist_ 601=602* athrows AuthorizationException604public function favorite(Activity Sactivitv. PlavlistActivitvRepository SolavlistActivitvRepositorv): J501605606=607* Remove activitu from this user's favorites plaulisti60S•Goarom Actvatu sactvitu*athrowsAuthorizationExcent.ion* Greturn mixednublic function unfavorite Activitv Sactivitv)-Tx: AutovCONCAT(u.id, CASE WHEN U.id = t.owner_id THEN ' (owner)' ELSE'' END) AS user_id,sa.*t.owner_id FROM social_accounts saNolN usens u on u.id e sa.sociablle i.diJOIN teams t .n<->l: on t.id = u.team_icWHERE u.team_id = 581 and sa.provider = 'salesforce';SELECT * FROM automated_report_results order by id desc;select * from features;select * from team_features where feature_id = 40;select * from teams where id = 556:select * from automated_reports:where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044"pat", "podcast"]SELECT * FROM automated report_ results WHERE uuid to bin( '822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid:select * from automated_report_results order by za desc;SELECT * FROM automated report resultsWHEkE 10 =17141select * from automated report results WHERE report id = 54:select * from opportunities where 1d = 75943494SELE * FROM teams WHERE name LIKE "%Les%': # 711, 692. 16067 - Timinnvintearationdlesmils.comselect * from playbooks where team id = 711: # event 226147SELEd * FROM Davbook catedonies WHERE Dlavbook 10 e 55151SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_typeSELECT * EROM eom fields WHERE 1d = 226147÷SELECT * EROM eom field values WHERE com field 1d = 226147.SELECT * FROM crm_configurations WHERE id = 692;SEISCTCONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '• END) AS user_id,nemailiSa.xt.owner id FROM social accounts saJOIN users u on u.id = sa.sociable idJOIN teams t 1..n<->1: on t.id = u.team_idWHERE U.team id = 711 and sa.provider = 'salesforce':SELECT * FROM crm profiles co JOIN users u 1..n<->1: on u.id = co.user id WHERE u.team_id = 711:select * from leads:select * from calendars:SELECTSo jiminny4041440 X.04 AS0 hl• suppont Dally • In zn 10m100% S2• Wed 13 May 12:42:46AskJiminnyReportActivityServiceTest vTrial Owner Role Senoices should only be - Recorder, Recorder & Voice, Analysthis option shouldn't appear when editing an organisation+0 ..I'II review the current flow for the trial creation and owner role assianment. Let me create a oian and investigate the1) Find Create Team / trial creation logic in backendUnderstand current owner role assianment flowLocate Import Opportunities Sync Period field locationSind frontend Create Team comnonentiReview current role assignment when owner signs inhought for 1sSearched Create TeamlcreateTeam in ~fiiminnvlabolSearched owner.*role|ownerRole in ~/jiminny/appSearched Imoort Opportunities Svnc Periodlimoort "opportunities "svnc in ~/iminnvlaodsearched controller.onp and pertormed 1 otner quenyAnalyzed app/nutp/controttersInought tor isThought for 2s >1/5 tasks done21 Understand current owner role assianment flowSearched class UserinvitationDTO in ~fiminny/appPoad Invitel IcerToTeamAction nhn and 2 other filesCoarchod pol e pecopnepipole analyctipole pecOpnep AND VOICE in cfliminnulonnAsk anvthina (84L)"Code SWF-1.6WN Windsurf Toams 1120-1UTF.8Po 4 spaces...
|
32866
|
NULL
|
NULL
|
NULL
|
|
32869
|
1256
|
0
|
2026-05-13T09:43:14.412963+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665394412_m1.jpg...
|
PhpStorm
|
faVsco.js – ActivityController.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use Carbon\Carbon;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\In;
use Illuminate\Validation\ValidationException;
use InvalidArgumentException;
use Jiminny\Component\ActivityAnalytics;
use Jiminny\Component\ActivitySearch;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Queue\Constants;
use Jiminny\Contracts\ES\Events\UpdateSingleEntity;
use Jiminny\Contracts\ES\UpdateTargetEnum;
use Jiminny\Contracts\Nudge\NudgeFactoryInterface;
use Jiminny\Contracts\Playlist\PlaylistTrackFactoryInterface;
use Jiminny\Contracts\Repositories\PlaylistActivityRepository;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Enums\TeamSetting;
use Jiminny\Events\Activities\AiAutomation\ActivityProspectAdded;
use Jiminny\Events\Activities\Coaching\Coached;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Controllers\CommentContextInterface;
use Jiminny\Http\Responses\Api\AbstractResponse;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\ActivityCommentTransformer;
use Jiminny\Http\Transformers\ActivityTopicTriggerTransformer;
use Jiminny\Http\Transformers\ActivityTransformer;
use Jiminny\Http\Transformers\AvailabilityNotificationTransformer;
use Jiminny\Http\Transformers\CoachingFeedbackTransformer;
use Jiminny\Http\Transformers\CoachingSectionsTransformer;
use Jiminny\Http\Transformers\SearchTransformer;
use Jiminny\Http\Transformers\StatsTransformer;
use Jiminny\Jobs\Crm\SaveActivity;
use Jiminny\Jobs\Crm\UpdateStage;
use Jiminny\Jobs\Telephony\StartRecording;
use Jiminny\Jobs\Telephony\StopRecording;
use Jiminny\Jobs\Telephony\ToggleRecording;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\CoachingFeedback;
use Jiminny\Models\CoachingSection;
use Jiminny\Models\CoachingSectionCriterion;
use Jiminny\Models\CoachingSectionFeedback;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\LanguageDialect;
use Jiminny\Models\Lead;
use Jiminny\Models\Nudge;
use Jiminny\Models\PlaybookCategory;
use Jiminny\Models\Playlist;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\Track;
use Jiminny\Models\User;
use Jiminny\Repositories\CoachingFeedbackRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Rules\CrmReference;
use Jiminny\Rules\MultidimensionalArrayMaxCharRule;
use Jiminny\Services\ActivityService;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Services\PlaybackService;
use Jiminny\Services\UserService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
use Ramsey\Uuid\Uuid;
use Sentry;
use Symfony\Component\HttpFoundation;
final class ActivityController extends Controller implements CommentContextInterface
{
// Number of minutes to look back on activities. i.e. a timeout on activity duration.
private const int LOOK_BACK = 180;
public function __construct(
private ProviderRegistry $providerRegistry,
private ActivityService $activityService,
Response $response,
private UserService $userService,
private ActivitySearch\Service\ActivitySearch $activitySearch,
private NudgeFactoryInterface $nudgeFactory,
private ActivityCommentService $activityCommentService,
private LoggerInterface $logger,
private readonly CoachingFeedbackRepository $coachingFeedbackRepository,
private readonly TeamRepository $teamRepository,
) {
parent::__construct($response);
}
public static function getCommentImplementation(): string
{
return Comment::class;
}
public function delete()
{
$this->request->validate([
'*' => 'uuid:activities',
]);
$deletedIds = [];
foreach ($this->request->all() as $activityId) {
$activity = Activity::idOrUuId($activityId);
try {
if ($this->authorize('delete', $activity)) {
$activity->delete();
$deletedIds[] = $activityId;
\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);
}
} catch (AuthorizationException $authorizationException) {
// They didn't have permission.
}
}
return $this->response->withArray($deletedIds);
}
public function update(Request $request, Activity $activity)
{
$this->authorize('updateMetadata', $activity);
$request->validate([
'title' => 'string|max:250',
'category_id' => 'uuid:playbook_categories',
'language' => [
new In(
LanguageDialect::query()
->with('language')
->cursor()
->map(static function (LanguageDialect $languageDialect): string {
return $languageDialect->getLanguageLocale();
})
->all()
),
],
]);
if ($request->has('title')) {
$activity->title = $request->input('title');
}
if ($request->has('category_id')) {
$category = PlaybookCategory::uuid($request->input('category_id'));
if ($category->playbook->team_id !== $request->user()->team_id) {
return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
if ($request->has('language')) {
if (! $activity->isInProgress()) {
return $this->response->withError(
'Activity language can only be set while the meeting is in progress.',
400
);
}
$activity->setLanguageCode($request->input('language'));
}
$activity->save();
return $this->response->withOk();
}
// XXX: This should be merged with the update method.
/**
* @param Activity $activity
*
* @throws AuthorizationException
* @throws SocialAccountTokenInvalidException
*
* @return mixed
*/
public function summarize(Activity $activity): mixed
{
$this->logger->info('[Log Activity] Summarizing activity ', [
'activityId' => $activity->getUuid(),
'payload' => $this->request->all(),
]);
$this->authorize('update', $activity);
$this->logger->info('[Log Activity] Validating summary');
// Validate the payload.
$this->validateSummary($activity);
// All objects must belong to this team.
/** @var User $user */
$user = $this->request->user();
$team = $user->getTeam();
$crmService = $this->providerRegistry->get($team->crm->provider);
try {
$crmUser = $user;
if ($user->isCrmRequired() === false) {
$crmUser = $team->owner;
}
$crmService->setUser($crmUser);
} catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());
}
$rawEntities = $this->request->input('entities');
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid(
$this->request->input('layout_id')
);
// Delay execution of CRM jobs to avoid locking issues.
$jobDelay = 0;
// If we have arrived from a notification, mark it as read.
$notificationId = $this->request->input('nId');
if ($notificationId) {
$notification = $user->unreadNotifications->where('id', $notificationId)->first();
if ($notification) {
$notification->markAsRead();
}
}
$title = $this->request->input('title');
$prospects = $this->request->input('prospects');
$opportunityId = $this->request->input('opportunity_id');
$stageId = $this->request->input('stage_id');
$categoryId = $this->request->input('category_id');
$summary = $this->request->input('summary');
$crmProviderId = $this->request->input('crm_id');
$isInternal = $this->request->input('is_internal') ?? false;
$lead = null;
$category = null;
$account = null;
$contact = null;
$opportunity = null;
$stage = null;
$callStage = null;
foreach ($prospects as $prospectData) {
$objectId = $prospectData['id'];
if ($objectId === null) {
continue;
}
$objectType = $prospectData['type'];
$this->logger->info('debug', ['prospect_data' => $prospectData]);
try {
if ($objectType === null) {
$this->logger->info('no object type');
if ($crmService instanceof SupportsObjectTypeParseInterface) {
$objectType = $crmService->parseObjectType($objectId);
}
}
switch ($objectType) {
case 'lead':
$this->logger->info('Processing lead');
/** @var Lead|null $lead */
$lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();
// Lead does not exist locally, import it.
if ($lead === null) {
$this->logger->info('Lead does not exist locally');
/** @var Lead $lead */
$lead = $crmService->syncLead($objectId);
}
$this->logger->info('Lead found', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
if ($stageId === null) {
$this->logger->info('Stage ID is null');
// If it was not provided, just assume it is the current stage.
$callStage = $lead->stage;
break;
}
$this->logger->info('Looking for stage');
// Determine if they have changed the stage.
/** @var Stage $stage */
$stage = $team->crm->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_LEAD)
->firstOrFail();
$this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);
if ($lead->stage_id && $lead->stage_id !== $stage->id) {
$this->logger->info('Stage has changed');
// Storage current stage on activity.
$callStage = $lead->stage;
// The stage has changed, update in remote CRM.
dispatch(new UpdateStage($activity, $lead, $callStage, $stage));
$this->logger->info(
sprintf(
'[%s] User changing lead stage from %s to %s',
$crmService->getDisplayName(),
$callStage->getName(),
$stage->getName()
),
[
'user' => $user->getUuid(),
'lead' => $lead->getUuid(),
]
);
} else {
$this->logger->info('Stage has not changed');
// Stage remains as current.
$callStage = $stage;
}
break;
case 'account':
$this->logger->info('Processing account');
// If the object is not a lead, it should be an account.
$account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();
// Account does not exist locally, import it.
if ($account === null) {
$this->logger->info('Account does not exist locally');
$account = $crmService->syncAccount($objectId);
}
$this->logger->info('Account found', ['accountId' => $account->id]);
break;
case 'contact':
$this->logger->info('processing contact');
$contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$this->logger->info('contact does not exist locally');
$contact = $crmService->syncContact($objectId);
}
$this->logger->info('resolving account');
$account = $this->resolveAccount($team, $contact, $crmService, $prospects);
break;
}
// If they have specified an opportunity, retrieve this with stage.
if ($opportunityId) {
$this->logger->info('opportunity id is set');
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if ($opportunity === null) {
$this->logger->info('opportunity does not exist locally');
$opportunity = $crmService->syncOpportunity($opportunityId);
}
if ($stageId === null) {
$this->logger->info('stage id is null');
// If it was not provided, just assume it is the current stage.
$callStage = $opportunity->stage ?? null;
} else {
$this->logger->info('looking for stage');
/** @var ?Stage $opportunityStage */
$opportunityStage = $team->crm
->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
// There is a chance we still cannot import this opportunity.
if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {
$this->logger->info('opportunity stage has changed');
// Storage current stage on activity.
$callStage = $opportunity->stage;
dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));
$this->logger->info(
sprintf(
'[%s] User changing opportunity stage from %s to %s',
$crmService->getDisplayName(),
$callStage->name,
$opportunityStage->name
),
[
'userId' => $user->id_string,
'opportunityId' => $opportunity->id_string,
]
);
} else {
$this->logger->info('opportunity stage has not changed');
// Stage remains as current.
$callStage = $opportunityStage;
}
}
}
if ($crmProviderId) {
// Cast $crmProviderId to string otherwise it won't use database index for some records
$linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();
// Check if this activity has already been assigned to a different activity.
if ($linkedActivity && $linkedActivity->id !== $activity->id) {
throw new InvalidArgumentException(
'Sorry, the linked task has already been logged under a different call. '
. 'Please choose another linked task.'
);
}
}
} catch (InvalidArgumentException $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($exception->getMessage());
} catch (Exception $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorInternalError(
'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'
);
}
}
if ($categoryId) {
$category = PlaybookCategory::uuid($categoryId);
if ($category->playbook->team_id !== $team->id) {
throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
$this->logger->info('Prospect data', [
'lead_id' => $lead?->getId(),
'account_id' => $account?->getId(),
'contact_id' => $contact?->getId(),
'opportunity_id' => $opportunity?->getId(),
'stage_id' => $stage?->getId(),
]);
if ($title) {
$activity->title = $title;
}
if ($summary) {
$activity->summary = $summary;
}
if ($crmProviderId) {
$activity->crm_provider_id = $crmProviderId;
}
if ($callStage) {
$this->logger->info('Setting stage id', ['stageId' => $callStage->id]);
$activity->stage_id = $callStage->id;
}
if ($lead) {
$this->logger->info('Setting lead id', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
// If we are changed from an account > lead, unset the account data.
$this->logger->info('Unsetting account id, opportunity id, contact id, value');
$activity->account_id = null;
$activity->opportunity_id = null;
$activity->contact_id = null;
$activity->value = null;
}
if ($account) {
$this->logger->info('Setting account id', ['accountId' => $account->id]);
$activity->account_id = $account->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('unsetting lead id');
$activity->lead_id = null;
// Unset the contact if switching different accounts. Will be set up below if still applicable.
if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {
$this->logger->info('Unsetting contact id');
$activity->contact_id = null;
}
}
if ($opportunity) {
$this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);
$this->logger->info('unsetting lead id');
$activity->opportunity_id = $opportunity->id;
$activity->value = $opportunity->value;
// If we are changed from an lead > account, unset the lead data.
$activity->lead_id = null;
}
if ($contact) {
$this->logger->info('setting contact id', ['contactId' => $contact->id]);
$activity->contact_id = $contact->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('Unsetting lead id');
$activity->lead_id = null;
}
$activity->is_internal = $isInternal;
$activity->save();
$activity->refresh();
$this->logger->notice('Activity saved', [
'activity_id' => $activity->getId(),
'lead_id' => $activity->lead_id,
'account_id' => $activity->account_id,
'contact_id' => $activity->contact_id,
'opportunity_id' => $activity->opportunity_id,
'stage_id' => $activity->stage_id,
'crm_provider_id' => $activity->getCrmProviderId(),
]);
// Store entities as field data on the activity.
$updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);
if ($activity->isLoggable()) {
// Follow-up Task or Event data.
$followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);
$this->logger->info('CRM LOG manual log triggered', [
'activityId' => $activity->getUuid(),
'followupData' => $followupData,
'userId' => $user->getUuid(),
]);
// Store data in the CRM.
// ++add check for crm_required
$job = new SaveActivity($activity, $followupData);
if ($updatedData) {
$job->delay(Carbon::now()->addMinutes($jobDelay));
}
dispatch($job);
// Manually dispatch log for Opportunity or Prospect added
if ($activity->hasOpportunity() || $activity->hasProspect()) {
event(new ActivityProspectAdded(
activity: $activity,
eventSource: 'manually-log-crm-data'
));
}
}
return $this->response->withOk();
}
/**
* Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.
*
* @param ServiceInterface $service
* @param Activity $activity
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array
{
$updatedData = [];
$existingData = $activity->data()->get();
// We need to delete any existing data to overwrite with latest values.
$activity->data()->delete();
$layoutEntities = $layout->entities()
->with('field', 'parent')
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->get();
/** @var LayoutEntity $entity */
foreach ($layoutEntities as $entity) {
// If the user has provided a value for this entity
if (array_key_exists($entity->id_string, $entities)) {
$value = $entities[$entity->id_string];
// Convert raw data into values that the CRM can consume.
if ($value) {
$value = $service->normalizeValue($entity->field->type, $value);
}
// Check the field is part of the activity-summary section.
if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {
// This is the internal database ID, not the external CRM ID.
$objectId = null;
switch ($entity->field->object_type) {
case Field::OBJECT_ACCOUNT:
$objectId = $activity->account_id;
break;
case Field::OBJECT_CONTACT:
$objectId = $activity->contact_id;
break;
case Field::OBJECT_OPPORTUNITY:
$objectId = $activity->opportunity_id;
break;
case Field::OBJECT_LEAD:
$objectId = $activity->lead_id;
break;
case Field::OBJECT_TASK:
case Field::OBJECT_EVENT:
$objectId = $activity->id;
break;
}
if ($objectId) {
/** @var FieldData $data */
$data = $activity->data()->create([
'crm_layout_entity_id' => $entity->id,
'crm_field_id' => $entity->crm_field_id,
'object_type' => $entity->field->object_type,
'object_id' => $objectId,
'value' => $value,
]);
// Never send read-only field data to the CRM.
if ($entity->read_only === false && $entity->is_visible) {
$existingValue = $existingData
->where('crm_layout_entity_id', $entity->id)
->where('crm_field_id', $entity->crm_field_id)
->where('object_type', $entity->field->object_type)
->where('object_id', $objectId)
->first();
// If the field was actually changed, we need to reflect this in the CRM too.
if ($existingValue === null || $existingValue->value !== $value) {
$updatedData[] = $data->id;
}
}
}
}
}
}
return $updatedData;
}
/**
* Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.
*
* @param ServiceInterface $crmService
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array
{
$fieldData = [];
foreach ($entities as $entityId => $value) {
// Only bother with fields that have a value.
if ($value) {
// Extract the entity from the UUID. Check the field is valid and part of the follow-up section.
$entity = $layout->entities()
->uuid($entityId, false)
->whereHas('parent', function ($query) {
$query->where('label', 'follow-up');
})
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->first();
if ($entity) {
// Convert raw data into values that the CRM can consume.
$value = $crmService->normalizeValue($entity->field->type, $value);
// Add the field and value to the payload.
$fieldData += [
$entity->field->crm_provider_id => $value,
];
}
}
}
return $fieldData;
}
/**
* @param Activity $activity
*/
private function validateSummary(Activity $activity): void
{
$team = $activity->user->team;
$crmProvider = $team->crm->provider;
$attributes = [];
$rules = [
'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,
'title' => 'string|max:250',
'prospects' => 'required|array',
'opportunity_id' => new CrmReference($crmProvider),
'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',
'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator
'summary' => 'max:50000',
'nId' => 'exists:notifications,id',
'crm_id' => new CrmReference($crmProvider),
'entities' => 'array',
'is_internal' => 'boolean',
];
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));
// Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.
$entities = $layout->entities()
->where('read_only', 0)
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->whereHas('parent', function ($query) use ($activity) {
if ($activity->isLoggable() === false) {
$query->where('label', '<>', 'follow-up');
}
});
$isInternal = $this->request->input('is_internal', false);
foreach ($entities->get() as $entity) {
$rules += $this->buildFieldValidator($entity, $isInternal);
$attributes += $this->buildFieldMessage($entity);
}
$this->request->validate($rules, [], $attributes);
}
private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array
{
return [
'entities.' . $entity->id_string => $entity->getValidator($isInternal),
];
}
/**
* @param LayoutEntity $entity
*
* @return array
*/
private function buildFieldMessage(LayoutEntity $entity): array
{
$label = $entity->label;
if ($label === null) {
$label = $entity->field->label;
}
return [
'entities.' . $entity->id_string => $label,
];
}
public function search(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->debugLog(
$user,
'User extracted from request',
['user' => $user->getId(), 'tz' => $user->getTimezone()]
);
$searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());
$this->debugLog(
$user,
'ActivitySearch criteria built',
['searchCriteria' => $searchCriteria]
);
$filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);
$this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);
$this->validateSearch($request, $filterSet);
$this->debugLog($user, 'Request validated');
$searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);
/** @var Collection<Activity> $activities */
$activities = $searchResponse['results'];
$this->debugLog($user, 'Activities ES response extracted');
$hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(
$user->getTeamId(),
TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),
);
if ($hideInternalMeetingsSetting?->getValue() === '1') {
$activities = $activities->filter(function (Activity $activity) {
if ($activity->is_internal && empty($activity->actual_start_time)) {
return false;
}
return true;
});
}
$this->debugLog($user, 'Internal meetings (?!) filtered');
$this->response->getManager()
->parseIncludes([
'category',
'organizer.group',
'prospect',
'stage',
'opportunity',
'stats',
'scorecards',
'masterTrack',
'activeParticipants',
'notification',
])
->setSerializer(new JsonSerializer());
$transformerExcludes = $this->request->input('exclude');
if ($transformerExcludes) {
$this->response->getManager()->parseExcludes($transformerExcludes);
}
$this->debugLog($user, 'Response Manager (?!) applied');
$transformer = new ActivityTransformer();
$transformer->setConsumer($user);
$this->debugLog($user, 'Activity Transformer added');
$resource = new \League\Fractal\Resource\Collection($activities, $transformer);
$page = $searchCriteria->getPageNumber();
$this->debugLog($user, 'Search criteria page number called', ['page' => $page]);
$histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');
$this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);
return $this->response->withArray([
'pagination' => [
'total' => $searchResponse['totalHits'],
'current' => $page,
'prev' => max($page - 1, 1),
'next' => $page + 1,
],
'results' => $this->response->getManager()->createData($resource)->toArray(),
'histogram' => $histogram,
]);
}
private function debugLog(User $user, string $logMessage, ?array $context = []): void
{
// Debug for Learning People Only
if ($user->getTeamId() !== 260) {
return;
}
Log::notice(
sprintf('[activity-search-controller] %s', $logMessage),
$context
);
}
/** @throws ValidationException */
private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void
{
$rules = [
'exclude' => 'array',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
];
if ($prefix !== null && mb_strpos($prefix, '.') !== false) {
$rules[rtrim($prefix, '.')] = sprintf(
'required|array|max:%d',
$filterSet->count()
);
}
$validationRules = $filterSet->getValidationRules($prefix)
->merge($rules)
->all();
$request->validate($validationRules);
}
public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$search = $this->updateOrCreateActivitySearch($request);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function updateActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('update', $search);
$this->updateOrCreateActivitySearch($request, $search);
return $this->response->withOk();
}
private function storeNamedSearchFilters(
Collection $request,
Search $search,
FilterDefinitionCollection $filterSet,
?string $prefix = null,
): self {
$arrayTypeProperties = $filterSet
->getPropertyTypes([
FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,
])
->all();
$supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);
foreach ($supportedRequestProperties as $requestPropertyName) {
if (! array_has($request, $requestPropertyName)) {
continue;
}
/** @var string|string[] $propertyValue */
$propertyValue = array_get($request, $requestPropertyName);
$propertyName = $prefix === null
? $requestPropertyName
: mb_substr($requestPropertyName, mb_strlen($prefix));
$isArrayType = array_has($arrayTypeProperties, $propertyName);
if (! $isArrayType) {
/** @var string $requestPropertyValue */
$search->filters()->updateOrCreate(
[
'filter' => $propertyName,
],
[
'value' => $propertyValue,
]
);
continue;
}
/** @var string[] $requestPropertyValue */
/** @var SearchFilter[]|Collection $existingFilterValues */
$existingFilterValuesKeyed = $search->filters()
->where('filter', $propertyName)
->get()
->keyBy('id');
// Iterate over values provided as request parameters
foreach ($propertyValue as $value) {
/** @var SearchFilter|null $valueFilter */
$valueFilter = $search->filters()
->where(
[
'filter' => $propertyName,
'value' => $value,
]
)
->first();
if ($valueFilter !== null) {
// Remove filter value pair from list to be deleted
$existingFilterValuesKeyed->forget($valueFilter->id);
} else {
// Add new filter/value pair
$search->filters()->updateOrCreate([
'filter' => $propertyName,
'value' => $value,
]);
}
}
// Delete filter value pairs for this filter that no longer exist in request parameters
foreach ($existingFilterValuesKeyed as $existingFilter) {
$existingFilter->delete();
}
}
/** @var Collection<int, SearchFilter> $filtersKeyed */
$filtersKeyed = $search->filters()->get()->keyBy('filter');
// wipe removed filters from this search
foreach ($filtersKeyed as $filterName => $filter) {
if (array_has($request, $prefix . $filterName)) {
continue;
}
// Remove all filter values for this filter
$search->filters()->where('filter', $filterName)->delete();
}
return $this;
}
/**
* @throws AuthorizationException
*/
public function fetchActivitySearch(
Search $search,
Request $request,
SearchTransformer $searchTransformer,
): JsonResponse {
$this->authorize('view', $search);
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withCollection(
$user->searches()->get(),
$searchTransformer
->withConsumer($user)
);
}
/**
* Deletes a saved search
*
* @param Request $request
* @param Search $search
*
* @throws Exception
*
* @return JsonResponse
*/
public function deleteActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('delete', $search);
// Orphan any AutomatedReports that use this search
$search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);
// Delete filters and the search itself
$search->filters()->delete();
$search->delete();
return $this->response->withOk();
}
public function live(Request $request, ElasticActivityRepository $repository): JsonResponse
{
$user = $this->getUserFromRequest($request);
$this->request->validate([
'sort_direction' => 'in:asc,desc',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
]);
$activities = $repository->getLiveCoachingEligibleActivities(
user: $user,
lookBackMinutes: self::LOOK_BACK,
limit: (int) $this->request->input('limit', 25),
page: (int) $this->request->input('page', 1),
sortBy: ['actual_start_time', 'scheduled_start_time'],
sortDirection: (string) $this->request->input('sort_direction', 'asc'),
);
$this->response
->getManager()
->parseIncludes(['organizer.group', 'prospect'])
->setSerializer(new JsonSerializer());
return $this->response->withCollection($activities, new ActivityTransformer());
}
/**
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function show(Activity $activity, ActivityService $activityService): JsonResponse
{
$this->authorize('show', $activity);
$user = $activity->getUser();
$team = $user->getTeam();
// Sync the opportunity with the latest data if possible.
if ($activity->opportunity_id) {
try {
$crmService = $this->providerRegistry->get($team->crm->provider);
if (! $user->isCrmRequired()) {
$crmService->setUser($team->getOwner());
} else {
$crmService->setUser($user);
}
$crmService->syncOpportunity($activity->opportunity->crm_provider_id);
} catch (Exception $exception) {
// Move on.
}
}
$activityData = $activityService->getActivityData($this->request->user(), $activity);
return response()->json($activityData);
}
public function createRecording(Activity $activity)
{
$this->authorize('record', $activity);
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Tell Twilio to start recording this activity.
if ($activity->recording_state === Activity::RECORDING_OFF) {
$job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withCreated();
}
return $this->response->errorGone('Activity is already recording.');
}
public function updateRecording(Request $request, Activity $activity)
{
$this->authorize('record', $activity);
$request->validate([
'preference' => 'boolean',
'state' => [
'string',
Rule::in([
Activity::RECORDING_IN_PROGRESS,
Activity::RECORDING_PAUSED,
]),
],
]);
if ($request->has('state')) {
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Toggle the recording state between paused and resumed.
if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {
$job = (new ToggleRecording($activity, $request->input('state')))
->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Recording is not toggleable.');
}
if ($request->has('preference')) {
$activity->update([
'recording_preference' => $request->input('preference') ? 1 : 0,
]);
return $this->response->withOk();
}
return $this->response->errorWrongArgs('Something went wrong');
}
public function stopRecording(Activity $activity)
{
$this->authorize('stopRecord', $activity);
// Tell Twilio to stop recording this activity.
if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {
$job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Activity is not recording.');
}
/**
* Add activity to this user's favorites playlist
*
* @throws AuthorizationException
*/
public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse
{
$this->authorize('favorite', $activity);
$user = $this->getUserFromRequest($this->request);
$favorite = $activity->wasFavoritedBy($user);
$name = $activity->activity_title ?? '';
// It needs to check at least one record.
if (! $favorite) {
$favoritePlaylist = $user->favoritePlaylist();
$playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(
$activity,
$user,
$favoritePlaylist
);
if ($playlistActivity !== null) {
$playlistActivity->update(
// Just update, don't sort.
['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],
);
} else {
$playlistActivity = $activity->playlistActivities()->create([
'playlist_id' => $favoritePlaylist->getId(),
'user_id' => $user->getId(),
'start_time' => 0,
'name' => mb_strimwidth($name, 0, 100),
]);
// Sort it on top.
$playlistActivity->update(
[
'sort' => $playlistActivityRepository->calculateNewSortOrder(
null,
$playlistActivity,
),
],
);
}
$playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);
return new JsonResponse([], JsonResponse::HTTP_CREATED);
}
return new JsonResponse(
[
'error' => [
'code' => AbstractResponse::CODE_CONFLICT,
'http_code' => JsonResponse::HTTP_CONFLICT,
'message' => 'Resource Already Exists',
],
],
JsonResponse::HTTP_CONFLICT,
);
}
/**
* Remove activity from this user's favorites playlist
*
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function unfavorite(Activity $activity)
{
$user = $t...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"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":"Analyzing…","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 Carbon\\Carbon;\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Exception;\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Validation\\Rule;\nuse Illuminate\\Validation\\Rules\\In;\nuse Illuminate\\Validation\\ValidationException;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ActivityAnalytics;\nuse Jiminny\\Component\\ActivitySearch;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Contracts\\ES\\Events\\UpdateSingleEntity;\nuse Jiminny\\Contracts\\ES\\UpdateTargetEnum;\nuse Jiminny\\Contracts\\Nudge\\NudgeFactoryInterface;\nuse Jiminny\\Contracts\\Playlist\\PlaylistTrackFactoryInterface;\nuse Jiminny\\Contracts\\Repositories\\PlaylistActivityRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Enums\\TeamSetting;\nuse Jiminny\\Events\\Activities\\AiAutomation\\ActivityProspectAdded;\nuse Jiminny\\Events\\Activities\\Coaching\\Coached;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Controllers\\CommentContextInterface;\nuse Jiminny\\Http\\Responses\\Api\\AbstractResponse;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\ActivityCommentTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTopicTriggerTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTransformer;\nuse Jiminny\\Http\\Transformers\\AvailabilityNotificationTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingFeedbackTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingSectionsTransformer;\nuse Jiminny\\Http\\Transformers\\SearchTransformer;\nuse Jiminny\\Http\\Transformers\\StatsTransformer;\nuse Jiminny\\Jobs\\Crm\\SaveActivity;\nuse Jiminny\\Jobs\\Crm\\UpdateStage;\nuse Jiminny\\Jobs\\Telephony\\StartRecording;\nuse Jiminny\\Jobs\\Telephony\\StopRecording;\nuse Jiminny\\Jobs\\Telephony\\ToggleRecording;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\CoachingFeedback;\nuse Jiminny\\Models\\CoachingSection;\nuse Jiminny\\Models\\CoachingSectionCriterion;\nuse Jiminny\\Models\\CoachingSectionFeedback;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\LanguageDialect;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Nudge;\nuse Jiminny\\Models\\PlaybookCategory;\nuse Jiminny\\Models\\Playlist;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\Track;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\CoachingFeedbackRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Rules\\MultidimensionalArrayMaxCharRule;\nuse Jiminny\\Services\\ActivityService;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Services\\PlaybackService;\nuse Jiminny\\Services\\UserService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\nuse Ramsey\\Uuid\\Uuid;\nuse Sentry;\nuse Symfony\\Component\\HttpFoundation;\n\nfinal class ActivityController extends Controller implements CommentContextInterface\n{\n // Number of minutes to look back on activities. i.e. a timeout on activity duration.\n private const int LOOK_BACK = 180;\n\n public function __construct(\n private ProviderRegistry $providerRegistry,\n private ActivityService $activityService,\n Response $response,\n private UserService $userService,\n private ActivitySearch\\Service\\ActivitySearch $activitySearch,\n private NudgeFactoryInterface $nudgeFactory,\n private ActivityCommentService $activityCommentService,\n private LoggerInterface $logger,\n private readonly CoachingFeedbackRepository $coachingFeedbackRepository,\n private readonly TeamRepository $teamRepository,\n ) {\n parent::__construct($response);\n }\n\n public static function getCommentImplementation(): string\n {\n return Comment::class;\n }\n\n public function delete()\n {\n $this->request->validate([\n '*' => 'uuid:activities',\n ]);\n\n $deletedIds = [];\n foreach ($this->request->all() as $activityId) {\n $activity = Activity::idOrUuId($activityId);\n\n try {\n if ($this->authorize('delete', $activity)) {\n $activity->delete();\n $deletedIds[] = $activityId;\n\n \\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n }\n } catch (AuthorizationException $authorizationException) {\n // They didn't have permission.\n }\n }\n\n return $this->response->withArray($deletedIds);\n }\n\n public function update(Request $request, Activity $activity)\n {\n $this->authorize('updateMetadata', $activity);\n\n $request->validate([\n 'title' => 'string|max:250',\n 'category_id' => 'uuid:playbook_categories',\n 'language' => [\n new In(\n LanguageDialect::query()\n ->with('language')\n ->cursor()\n ->map(static function (LanguageDialect $languageDialect): string {\n return $languageDialect->getLanguageLocale();\n })\n ->all()\n ),\n ],\n ]);\n\n if ($request->has('title')) {\n $activity->title = $request->input('title');\n }\n\n if ($request->has('category_id')) {\n $category = PlaybookCategory::uuid($request->input('category_id'));\n\n if ($category->playbook->team_id !== $request->user()->team_id) {\n return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n if ($request->has('language')) {\n if (! $activity->isInProgress()) {\n return $this->response->withError(\n 'Activity language can only be set while the meeting is in progress.',\n 400\n );\n }\n\n $activity->setLanguageCode($request->input('language'));\n }\n\n $activity->save();\n\n return $this->response->withOk();\n }\n\n // XXX: This should be merged with the update method.\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws SocialAccountTokenInvalidException\n *\n * @return mixed\n */\n public function summarize(Activity $activity): mixed\n {\n $this->logger->info('[Log Activity] Summarizing activity ', [\n 'activityId' => $activity->getUuid(),\n 'payload' => $this->request->all(),\n ]);\n $this->authorize('update', $activity);\n\n $this->logger->info('[Log Activity] Validating summary');\n // Validate the payload.\n $this->validateSummary($activity);\n\n // All objects must belong to this team.\n /** @var User $user */\n $user = $this->request->user();\n $team = $user->getTeam();\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n try {\n $crmUser = $user;\n if ($user->isCrmRequired() === false) {\n $crmUser = $team->owner;\n }\n $crmService->setUser($crmUser);\n } catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());\n }\n\n $rawEntities = $this->request->input('entities');\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid(\n $this->request->input('layout_id')\n );\n\n // Delay execution of CRM jobs to avoid locking issues.\n $jobDelay = 0;\n\n // If we have arrived from a notification, mark it as read.\n $notificationId = $this->request->input('nId');\n if ($notificationId) {\n $notification = $user->unreadNotifications->where('id', $notificationId)->first();\n\n if ($notification) {\n $notification->markAsRead();\n }\n }\n\n $title = $this->request->input('title');\n $prospects = $this->request->input('prospects');\n $opportunityId = $this->request->input('opportunity_id');\n $stageId = $this->request->input('stage_id');\n $categoryId = $this->request->input('category_id');\n $summary = $this->request->input('summary');\n $crmProviderId = $this->request->input('crm_id');\n $isInternal = $this->request->input('is_internal') ?? false;\n\n $lead = null;\n $category = null;\n $account = null;\n $contact = null;\n $opportunity = null;\n $stage = null;\n $callStage = null;\n\n foreach ($prospects as $prospectData) {\n $objectId = $prospectData['id'];\n\n if ($objectId === null) {\n continue;\n }\n\n $objectType = $prospectData['type'];\n $this->logger->info('debug', ['prospect_data' => $prospectData]);\n\n try {\n if ($objectType === null) {\n $this->logger->info('no object type');\n if ($crmService instanceof SupportsObjectTypeParseInterface) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n }\n\n switch ($objectType) {\n case 'lead':\n $this->logger->info('Processing lead');\n /** @var Lead|null $lead */\n $lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();\n\n // Lead does not exist locally, import it.\n if ($lead === null) {\n $this->logger->info('Lead does not exist locally');\n /** @var Lead $lead */\n $lead = $crmService->syncLead($objectId);\n }\n\n $this->logger->info('Lead found', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n if ($stageId === null) {\n $this->logger->info('Stage ID is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $lead->stage;\n\n break;\n }\n\n $this->logger->info('Looking for stage');\n // Determine if they have changed the stage.\n /** @var Stage $stage */\n $stage = $team->crm->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_LEAD)\n ->firstOrFail();\n\n $this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);\n if ($lead->stage_id && $lead->stage_id !== $stage->id) {\n $this->logger->info('Stage has changed');\n // Storage current stage on activity.\n $callStage = $lead->stage;\n\n // The stage has changed, update in remote CRM.\n dispatch(new UpdateStage($activity, $lead, $callStage, $stage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing lead stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->getName(),\n $stage->getName()\n ),\n [\n 'user' => $user->getUuid(),\n 'lead' => $lead->getUuid(),\n ]\n );\n } else {\n $this->logger->info('Stage has not changed');\n // Stage remains as current.\n $callStage = $stage;\n }\n\n break;\n\n case 'account':\n $this->logger->info('Processing account');\n // If the object is not a lead, it should be an account.\n $account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();\n\n // Account does not exist locally, import it.\n if ($account === null) {\n $this->logger->info('Account does not exist locally');\n $account = $crmService->syncAccount($objectId);\n }\n\n $this->logger->info('Account found', ['accountId' => $account->id]);\n\n break;\n case 'contact':\n $this->logger->info('processing contact');\n $contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $this->logger->info('contact does not exist locally');\n $contact = $crmService->syncContact($objectId);\n }\n\n $this->logger->info('resolving account');\n $account = $this->resolveAccount($team, $contact, $crmService, $prospects);\n\n break;\n }\n\n // If they have specified an opportunity, retrieve this with stage.\n if ($opportunityId) {\n $this->logger->info('opportunity id is set');\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if ($opportunity === null) {\n $this->logger->info('opportunity does not exist locally');\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n if ($stageId === null) {\n $this->logger->info('stage id is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $opportunity->stage ?? null;\n } else {\n $this->logger->info('looking for stage');\n /** @var ?Stage $opportunityStage */\n $opportunityStage = $team->crm\n ->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n // There is a chance we still cannot import this opportunity.\n if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {\n $this->logger->info('opportunity stage has changed');\n // Storage current stage on activity.\n $callStage = $opportunity->stage;\n\n dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing opportunity stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->name,\n $opportunityStage->name\n ),\n [\n 'userId' => $user->id_string,\n 'opportunityId' => $opportunity->id_string,\n ]\n );\n } else {\n $this->logger->info('opportunity stage has not changed');\n // Stage remains as current.\n $callStage = $opportunityStage;\n }\n }\n }\n\n if ($crmProviderId) {\n // Cast $crmProviderId to string otherwise it won't use database index for some records\n $linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();\n\n // Check if this activity has already been assigned to a different activity.\n if ($linkedActivity && $linkedActivity->id !== $activity->id) {\n throw new InvalidArgumentException(\n 'Sorry, the linked task has already been logged under a different call. '\n . 'Please choose another linked task.'\n );\n }\n }\n } catch (InvalidArgumentException $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($exception->getMessage());\n } catch (Exception $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorInternalError(\n 'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'\n );\n }\n }\n\n if ($categoryId) {\n $category = PlaybookCategory::uuid($categoryId);\n\n if ($category->playbook->team_id !== $team->id) {\n throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n $this->logger->info('Prospect data', [\n 'lead_id' => $lead?->getId(),\n 'account_id' => $account?->getId(),\n 'contact_id' => $contact?->getId(),\n 'opportunity_id' => $opportunity?->getId(),\n 'stage_id' => $stage?->getId(),\n ]);\n\n if ($title) {\n $activity->title = $title;\n }\n\n if ($summary) {\n $activity->summary = $summary;\n }\n\n if ($crmProviderId) {\n $activity->crm_provider_id = $crmProviderId;\n }\n\n if ($callStage) {\n $this->logger->info('Setting stage id', ['stageId' => $callStage->id]);\n $activity->stage_id = $callStage->id;\n }\n\n if ($lead) {\n $this->logger->info('Setting lead id', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n // If we are changed from an account > lead, unset the account data.\n $this->logger->info('Unsetting account id, opportunity id, contact id, value');\n $activity->account_id = null;\n $activity->opportunity_id = null;\n $activity->contact_id = null;\n $activity->value = null;\n }\n\n if ($account) {\n $this->logger->info('Setting account id', ['accountId' => $account->id]);\n $activity->account_id = $account->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('unsetting lead id');\n $activity->lead_id = null;\n\n // Unset the contact if switching different accounts. Will be set up below if still applicable.\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {\n $this->logger->info('Unsetting contact id');\n $activity->contact_id = null;\n }\n }\n\n if ($opportunity) {\n $this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);\n $this->logger->info('unsetting lead id');\n $activity->opportunity_id = $opportunity->id;\n $activity->value = $opportunity->value;\n\n // If we are changed from an lead > account, unset the lead data.\n $activity->lead_id = null;\n }\n\n if ($contact) {\n $this->logger->info('setting contact id', ['contactId' => $contact->id]);\n $activity->contact_id = $contact->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('Unsetting lead id');\n $activity->lead_id = null;\n }\n\n $activity->is_internal = $isInternal;\n $activity->save();\n $activity->refresh();\n\n $this->logger->notice('Activity saved', [\n 'activity_id' => $activity->getId(),\n 'lead_id' => $activity->lead_id,\n 'account_id' => $activity->account_id,\n 'contact_id' => $activity->contact_id,\n 'opportunity_id' => $activity->opportunity_id,\n 'stage_id' => $activity->stage_id,\n 'crm_provider_id' => $activity->getCrmProviderId(),\n ]);\n\n // Store entities as field data on the activity.\n $updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);\n\n if ($activity->isLoggable()) {\n // Follow-up Task or Event data.\n $followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);\n\n $this->logger->info('CRM LOG manual log triggered', [\n 'activityId' => $activity->getUuid(),\n 'followupData' => $followupData,\n 'userId' => $user->getUuid(),\n ]);\n\n // Store data in the CRM.\n // ++add check for crm_required\n $job = new SaveActivity($activity, $followupData);\n\n if ($updatedData) {\n $job->delay(Carbon::now()->addMinutes($jobDelay));\n }\n\n dispatch($job);\n\n // Manually dispatch log for Opportunity or Prospect added\n if ($activity->hasOpportunity() || $activity->hasProspect()) {\n event(new ActivityProspectAdded(\n activity: $activity,\n eventSource: 'manually-log-crm-data'\n ));\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.\n *\n * @param ServiceInterface $service\n * @param Activity $activity\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array\n {\n $updatedData = [];\n $existingData = $activity->data()->get();\n\n // We need to delete any existing data to overwrite with latest values.\n $activity->data()->delete();\n\n $layoutEntities = $layout->entities()\n ->with('field', 'parent')\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->get();\n\n /** @var LayoutEntity $entity */\n foreach ($layoutEntities as $entity) {\n // If the user has provided a value for this entity\n if (array_key_exists($entity->id_string, $entities)) {\n $value = $entities[$entity->id_string];\n\n // Convert raw data into values that the CRM can consume.\n if ($value) {\n $value = $service->normalizeValue($entity->field->type, $value);\n }\n\n // Check the field is part of the activity-summary section.\n if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {\n // This is the internal database ID, not the external CRM ID.\n $objectId = null;\n\n switch ($entity->field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $objectId = $activity->account_id;\n\n break;\n\n case Field::OBJECT_CONTACT:\n $objectId = $activity->contact_id;\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n $objectId = $activity->opportunity_id;\n\n break;\n\n case Field::OBJECT_LEAD:\n $objectId = $activity->lead_id;\n\n break;\n\n case Field::OBJECT_TASK:\n case Field::OBJECT_EVENT:\n $objectId = $activity->id;\n\n break;\n }\n\n if ($objectId) {\n /** @var FieldData $data */\n $data = $activity->data()->create([\n 'crm_layout_entity_id' => $entity->id,\n 'crm_field_id' => $entity->crm_field_id,\n 'object_type' => $entity->field->object_type,\n 'object_id' => $objectId,\n 'value' => $value,\n ]);\n\n // Never send read-only field data to the CRM.\n if ($entity->read_only === false && $entity->is_visible) {\n $existingValue = $existingData\n ->where('crm_layout_entity_id', $entity->id)\n ->where('crm_field_id', $entity->crm_field_id)\n ->where('object_type', $entity->field->object_type)\n ->where('object_id', $objectId)\n ->first();\n\n // If the field was actually changed, we need to reflect this in the CRM too.\n if ($existingValue === null || $existingValue->value !== $value) {\n $updatedData[] = $data->id;\n }\n }\n }\n }\n }\n }\n\n return $updatedData;\n }\n\n /**\n * Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.\n *\n * @param ServiceInterface $crmService\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array\n {\n $fieldData = [];\n foreach ($entities as $entityId => $value) {\n // Only bother with fields that have a value.\n if ($value) {\n // Extract the entity from the UUID. Check the field is valid and part of the follow-up section.\n $entity = $layout->entities()\n ->uuid($entityId, false)\n ->whereHas('parent', function ($query) {\n $query->where('label', 'follow-up');\n })\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->first();\n\n if ($entity) {\n // Convert raw data into values that the CRM can consume.\n $value = $crmService->normalizeValue($entity->field->type, $value);\n\n // Add the field and value to the payload.\n $fieldData += [\n $entity->field->crm_provider_id => $value,\n ];\n }\n }\n }\n\n return $fieldData;\n }\n\n /**\n * @param Activity $activity\n */\n private function validateSummary(Activity $activity): void\n {\n $team = $activity->user->team;\n $crmProvider = $team->crm->provider;\n $attributes = [];\n\n $rules = [\n 'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,\n 'title' => 'string|max:250',\n 'prospects' => 'required|array',\n 'opportunity_id' => new CrmReference($crmProvider),\n 'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',\n 'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator\n 'summary' => 'max:50000',\n 'nId' => 'exists:notifications,id',\n 'crm_id' => new CrmReference($crmProvider),\n 'entities' => 'array',\n 'is_internal' => 'boolean',\n ];\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));\n\n // Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.\n $entities = $layout->entities()\n ->where('read_only', 0)\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->whereHas('parent', function ($query) use ($activity) {\n if ($activity->isLoggable() === false) {\n $query->where('label', '<>', 'follow-up');\n }\n });\n\n $isInternal = $this->request->input('is_internal', false);\n\n foreach ($entities->get() as $entity) {\n $rules += $this->buildFieldValidator($entity, $isInternal);\n $attributes += $this->buildFieldMessage($entity);\n }\n\n $this->request->validate($rules, [], $attributes);\n }\n\n private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array\n {\n return [\n 'entities.' . $entity->id_string => $entity->getValidator($isInternal),\n ];\n }\n\n /**\n * @param LayoutEntity $entity\n *\n * @return array\n */\n private function buildFieldMessage(LayoutEntity $entity): array\n {\n $label = $entity->label;\n if ($label === null) {\n $label = $entity->field->label;\n }\n\n return [\n 'entities.' . $entity->id_string => $label,\n ];\n }\n\n public function search(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->debugLog(\n $user,\n 'User extracted from request',\n ['user' => $user->getId(), 'tz' => $user->getTimezone()]\n );\n\n $searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());\n\n $this->debugLog(\n $user,\n 'ActivitySearch criteria built',\n ['searchCriteria' => $searchCriteria]\n );\n\n $filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);\n\n $this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);\n\n $this->validateSearch($request, $filterSet);\n\n $this->debugLog($user, 'Request validated');\n\n $searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);\n\n /** @var Collection<Activity> $activities */\n $activities = $searchResponse['results'];\n\n $this->debugLog($user, 'Activities ES response extracted');\n\n $hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(\n $user->getTeamId(),\n TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),\n );\n\n if ($hideInternalMeetingsSetting?->getValue() === '1') {\n $activities = $activities->filter(function (Activity $activity) {\n if ($activity->is_internal && empty($activity->actual_start_time)) {\n return false;\n }\n\n return true;\n });\n }\n\n $this->debugLog($user, 'Internal meetings (?!) filtered');\n\n $this->response->getManager()\n ->parseIncludes([\n 'category',\n 'organizer.group',\n 'prospect',\n 'stage',\n 'opportunity',\n 'stats',\n 'scorecards',\n 'masterTrack',\n 'activeParticipants',\n 'notification',\n ])\n ->setSerializer(new JsonSerializer());\n\n $transformerExcludes = $this->request->input('exclude');\n if ($transformerExcludes) {\n $this->response->getManager()->parseExcludes($transformerExcludes);\n }\n\n $this->debugLog($user, 'Response Manager (?!) applied');\n\n $transformer = new ActivityTransformer();\n $transformer->setConsumer($user);\n\n $this->debugLog($user, 'Activity Transformer added');\n\n $resource = new \\League\\Fractal\\Resource\\Collection($activities, $transformer);\n $page = $searchCriteria->getPageNumber();\n\n $this->debugLog($user, 'Search criteria page number called', ['page' => $page]);\n\n $histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');\n\n $this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);\n\n return $this->response->withArray([\n 'pagination' => [\n 'total' => $searchResponse['totalHits'],\n 'current' => $page,\n 'prev' => max($page - 1, 1),\n 'next' => $page + 1,\n ],\n 'results' => $this->response->getManager()->createData($resource)->toArray(),\n 'histogram' => $histogram,\n ]);\n }\n\n private function debugLog(User $user, string $logMessage, ?array $context = []): void\n {\n // Debug for Learning People Only\n if ($user->getTeamId() !== 260) {\n return;\n }\n\n Log::notice(\n sprintf('[activity-search-controller] %s', $logMessage),\n $context\n );\n }\n\n /** @throws ValidationException */\n private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void\n {\n $rules = [\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ];\n\n if ($prefix !== null && mb_strpos($prefix, '.') !== false) {\n $rules[rtrim($prefix, '.')] = sprintf(\n 'required|array|max:%d',\n $filterSet->count()\n );\n }\n\n $validationRules = $filterSet->getValidationRules($prefix)\n ->merge($rules)\n ->all();\n\n $request->validate($validationRules);\n }\n\n public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $search = $this->updateOrCreateActivitySearch($request);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function updateActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('update', $search);\n\n $this->updateOrCreateActivitySearch($request, $search);\n\n return $this->response->withOk();\n }\n\n private function storeNamedSearchFilters(\n Collection $request,\n Search $search,\n FilterDefinitionCollection $filterSet,\n ?string $prefix = null,\n ): self {\n $arrayTypeProperties = $filterSet\n ->getPropertyTypes([\n FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,\n ])\n ->all();\n\n $supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);\n\n foreach ($supportedRequestProperties as $requestPropertyName) {\n if (! array_has($request, $requestPropertyName)) {\n continue;\n }\n\n /** @var string|string[] $propertyValue */\n $propertyValue = array_get($request, $requestPropertyName);\n $propertyName = $prefix === null\n ? $requestPropertyName\n : mb_substr($requestPropertyName, mb_strlen($prefix));\n\n $isArrayType = array_has($arrayTypeProperties, $propertyName);\n\n if (! $isArrayType) {\n /** @var string $requestPropertyValue */\n\n $search->filters()->updateOrCreate(\n [\n 'filter' => $propertyName,\n ],\n [\n 'value' => $propertyValue,\n ]\n );\n\n continue;\n }\n\n /** @var string[] $requestPropertyValue */\n\n /** @var SearchFilter[]|Collection $existingFilterValues */\n $existingFilterValuesKeyed = $search->filters()\n ->where('filter', $propertyName)\n ->get()\n ->keyBy('id');\n\n // Iterate over values provided as request parameters\n foreach ($propertyValue as $value) {\n /** @var SearchFilter|null $valueFilter */\n $valueFilter = $search->filters()\n ->where(\n [\n 'filter' => $propertyName,\n 'value' => $value,\n ]\n )\n ->first();\n\n if ($valueFilter !== null) {\n // Remove filter value pair from list to be deleted\n $existingFilterValuesKeyed->forget($valueFilter->id);\n } else {\n // Add new filter/value pair\n $search->filters()->updateOrCreate([\n 'filter' => $propertyName,\n 'value' => $value,\n ]);\n }\n }\n\n // Delete filter value pairs for this filter that no longer exist in request parameters\n foreach ($existingFilterValuesKeyed as $existingFilter) {\n $existingFilter->delete();\n }\n }\n\n /** @var Collection<int, SearchFilter> $filtersKeyed */\n $filtersKeyed = $search->filters()->get()->keyBy('filter');\n\n // wipe removed filters from this search\n foreach ($filtersKeyed as $filterName => $filter) {\n if (array_has($request, $prefix . $filterName)) {\n continue;\n }\n\n // Remove all filter values for this filter\n $search->filters()->where('filter', $filterName)->delete();\n }\n\n return $this;\n }\n\n /**\n * @throws AuthorizationException\n */\n public function fetchActivitySearch(\n Search $search,\n Request $request,\n SearchTransformer $searchTransformer,\n ): JsonResponse {\n $this->authorize('view', $search);\n\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection(\n $user->searches()->get(),\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n /**\n * Deletes a saved search\n *\n * @param Request $request\n * @param Search $search\n *\n * @throws Exception\n *\n * @return JsonResponse\n */\n public function deleteActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('delete', $search);\n\n // Orphan any AutomatedReports that use this search\n $search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);\n\n // Delete filters and the search itself\n $search->filters()->delete();\n $search->delete();\n\n return $this->response->withOk();\n }\n\n public function live(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n $user = $this->getUserFromRequest($request);\n\n $this->request->validate([\n 'sort_direction' => 'in:asc,desc',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ]);\n\n $activities = $repository->getLiveCoachingEligibleActivities(\n user: $user,\n lookBackMinutes: self::LOOK_BACK,\n limit: (int) $this->request->input('limit', 25),\n page: (int) $this->request->input('page', 1),\n sortBy: ['actual_start_time', 'scheduled_start_time'],\n sortDirection: (string) $this->request->input('sort_direction', 'asc'),\n );\n\n $this->response\n ->getManager()\n ->parseIncludes(['organizer.group', 'prospect'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($activities, new ActivityTransformer());\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function show(Activity $activity, ActivityService $activityService): JsonResponse\n {\n $this->authorize('show', $activity);\n\n $user = $activity->getUser();\n $team = $user->getTeam();\n\n // Sync the opportunity with the latest data if possible.\n if ($activity->opportunity_id) {\n try {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n if (! $user->isCrmRequired()) {\n $crmService->setUser($team->getOwner());\n } else {\n $crmService->setUser($user);\n }\n\n $crmService->syncOpportunity($activity->opportunity->crm_provider_id);\n } catch (Exception $exception) {\n // Move on.\n }\n }\n\n $activityData = $activityService->getActivityData($this->request->user(), $activity);\n\n return response()->json($activityData);\n }\n\n public function createRecording(Activity $activity)\n {\n $this->authorize('record', $activity);\n\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Tell Twilio to start recording this activity.\n if ($activity->recording_state === Activity::RECORDING_OFF) {\n $job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withCreated();\n }\n\n return $this->response->errorGone('Activity is already recording.');\n }\n\n public function updateRecording(Request $request, Activity $activity)\n {\n $this->authorize('record', $activity);\n\n $request->validate([\n 'preference' => 'boolean',\n 'state' => [\n 'string',\n Rule::in([\n Activity::RECORDING_IN_PROGRESS,\n Activity::RECORDING_PAUSED,\n ]),\n ],\n ]);\n\n if ($request->has('state')) {\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Toggle the recording state between paused and resumed.\n if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {\n $job = (new ToggleRecording($activity, $request->input('state')))\n ->onQueue(Constants::QUEUE_CONFERENCES);\n\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Recording is not toggleable.');\n }\n\n if ($request->has('preference')) {\n $activity->update([\n 'recording_preference' => $request->input('preference') ? 1 : 0,\n ]);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorWrongArgs('Something went wrong');\n }\n\n public function stopRecording(Activity $activity)\n {\n $this->authorize('stopRecord', $activity);\n\n // Tell Twilio to stop recording this activity.\n if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {\n $job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Activity is not recording.');\n }\n\n /**\n * Add activity to this user's favorites playlist\n *\n * @throws AuthorizationException\n */\n public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse\n {\n $this->authorize('favorite', $activity);\n\n $user = $this->getUserFromRequest($this->request);\n $favorite = $activity->wasFavoritedBy($user);\n $name = $activity->activity_title ?? '';\n\n // It needs to check at least one record.\n if (! $favorite) {\n $favoritePlaylist = $user->favoritePlaylist();\n\n $playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(\n $activity,\n $user,\n $favoritePlaylist\n );\n\n if ($playlistActivity !== null) {\n $playlistActivity->update(\n // Just update, don't sort.\n ['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],\n );\n } else {\n $playlistActivity = $activity->playlistActivities()->create([\n 'playlist_id' => $favoritePlaylist->getId(),\n 'user_id' => $user->getId(),\n 'start_time' => 0,\n 'name' => mb_strimwidth($name, 0, 100),\n ]);\n // Sort it on top.\n $playlistActivity->update(\n [\n 'sort' => $playlistActivityRepository->calculateNewSortOrder(\n null,\n $playlistActivity,\n ),\n ],\n );\n }\n\n $playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);\n\n return new JsonResponse([], JsonResponse::HTTP_CREATED);\n }\n\n return new JsonResponse(\n [\n 'error' => [\n 'code' => AbstractResponse::CODE_CONFLICT,\n 'http_code' => JsonResponse::HTTP_CONFLICT,\n 'message' => 'Resource Already Exists',\n ],\n ],\n JsonResponse::HTTP_CONFLICT,\n );\n }\n\n /**\n * Remove activity from this user's favorites playlist\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unfavorite(Activity $activity)\n {\n $user = $this->request->user();\n\n $favorites = $activity->favoritedBy($user);\n\n if ($favorites && $favorites->isEmpty()) {\n return $this->response->errorNotFound('Favorite not found.');\n }\n\n $this->authorize('unfavorite', [$activity, $favorites]);\n\n // When you unfavorite an activity,\n // it should remove all the activities in it, including snippets.\n $isDeleted = $favorites->each(function ($favorite) {\n $favorite->forceDelete();\n });\n\n if ($isDeleted) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not remove favorite.');\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function notify(Activity $activity)\n {\n $this->authorize('notify', $activity);\n\n $user = $this->request->user();\n\n $existingNotification = $activity->availabilityNotifications()\n ->where('user_id', $user->id)\n ->exists();\n\n if ($existingNotification) {\n return $this->response->errorWrongArgs('Notification is already configured.');\n }\n\n $notification = Activity\\AvailabilityNotification::create([\n 'user_id' => $user->id,\n 'activity_id' => $activity->id,\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($notification, new AvailabilityNotificationTransformer());\n }\n\n /**\n * @param Activity $activity\n * @param Activity\\AvailabilityNotification $notification\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unnotify(Activity $activity, Activity\\AvailabilityNotification $notification)\n {\n $this->authorize('unnotify', [$activity, $notification]);\n\n if ($notification->sent_at || $notification->delete()) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not delete notification.');\n }\n\n public function play(Request $request, Activity $activity)\n {\n $this->authorize('stream', $activity);\n\n $request->validate([\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $activity->plays()->create([\n 'user_id' => $user->getId(),\n 'start_time' => $request->input('start_time'),\n ]);\n\n return $this->response->withCreated();\n }\n\n /**\n * @param Activity $activity\n *\n * @return mixed\n */\n public function comment(Activity $activity)\n {\n return $this->newComment($activity);\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @return mixed\n */\n public function replyComment(Activity $activity, Comment $comment)\n {\n return $this->newComment($activity, $comment);\n }\n\n /**\n * @param Activity $activity\n * @param Comment|null $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n protected function newComment(Activity $activity, ?Comment $comment = null)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n 'type' => 'integer|between:0,3',\n 'visibility' => sprintf('nullable|integer|between:1,%d', count(Comment::getVisibilityLevels())),\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n $threadStartId = null;\n if ($comment) {\n $threadStartId = $comment->thread_start_id ?: $comment->id;\n }\n\n try {\n $newComment = Comment::create([\n 'parent_comment_id' => $comment->id ?? null,\n 'thread_start_id' => $threadStartId,\n 'activity_id' => $activity->id,\n 'user_id' => $this->request->user()->id,\n 'comment' => trim($this->request->input('comment')),\n 'start_time' => $this->request->input('start_time', 0),\n 'end_time' => $this->request->input('end_time', 0),\n 'type' => $this->request->input('type', Comment::TYPE_NEUTRAL),\n 'visibility' => $this->request->input('visibility', Comment::VISIBILITY_PUBLIC),\n ]);\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($newComment, new ActivityCommentTransformer());\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not create comment.' . $exception->getMessage());\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function updateComment(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n try {\n $comment->update([\n 'comment' => trim($this->request->input('comment')),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment.');\n }\n }\n\n public function updateCommentVisibility(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'visibility' => sprintf('integer|between:1,%d', count(Comment::getVisibilityLevels())),\n ]);\n\n $visibility = $this->request->input('visibility');\n\n if ($comment->parent !== null) {\n return $this->response->errorWrongArgs('Comment visibility can only be updated on top level comments.');\n }\n\n try {\n $this->activityCommentService->updateCommentVisibility($comment, $visibility);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment\\'s visibility.');\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function deleteComment(Activity $activity, Comment $comment)\n {\n $this->authorize('deleteComment', [$activity, $comment]);\n\n // Delete comment and any children.\n $comment->delete();\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function fetchComments()\n {\n $user = $this->request->user();\n $this->request->validate([\n 'forUserId' => 'uuid:users,team_id,' . $user->team_id,\n 'types' => 'array',\n 'types.*' => 'integer|between:0,3',\n ]);\n $forUser = null;\n\n $types = [Comment::TYPE_NEUTRAL, Comment::TYPE_GAME_CHANGER, Comment::TYPE_POSITIVE];\n $user = $this->request->user();\n if ($this->request->has('forUserId')) {\n $forUser = $user->team->users()->uuid($this->request->input('forUserId'));\n }\n\n $comments = Comment::query()\n ->whereHas('activity', static function (Builder $builder) use ($user, $forUser): void {\n $builder\n // I left feedback on my own activity; or\n ->where('activities.user_id', $user->getId());\n if ($forUser) {\n // I left feedback on any activity for this user.\n $builder->orWhere([\n 'user_id' => $user->getId(),\n 'activities.user_id' => $forUser->getId(),\n ]);\n }\n })\n ->whereIn('type', $this->request->input('types', $types))\n ->orderBy('created_at', 'desc')\n ->get();\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity', 'user'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($comments, new ActivityCommentTransformer());\n }\n\n public function deleteCoachingFeedback(Activity $activity, CoachingFeedback $coachingFeedback)\n {\n $this->authorize('deleteCoachingFeedback', [$activity, $coachingFeedback]);\n $activity = $coachingFeedback->getActivity();\n\n if ($coachingFeedback->delete()) {\n event(new UpdateSingleEntity(\n entityId: $activity->getId(),\n updateTarget: UpdateTargetEnum::ACTIVITY,\n purpose: 'delete-coaching-feedback',\n ));\n\n return $this->response->withOk();\n }\n\n return $this->response->withError('Delete operation failed. Contact support.', 500);\n }\n\n /**\n * Add new or update Coaching feedback\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws \\Illuminate\\Validation\\ValidationException\n *\n * @return mixed\n */\n public function putCoachingFeedback(Request $request, Activity $activity)\n {\n $user = $request->user();\n\n if (! $user instanceof User) {\n abort(403);\n }\n $teamId = $user->getTeamId();\n\n $this->authorize('coach', $activity);\n\n $this->request->validate([\n 'coach_id' => 'required|uuid:users,team_id,' . $teamId,\n 'coachee_id' => 'required|uuid:users,team_id,' . $teamId,\n 'visibility' => ['required', Rule::in(CoachingFeedback::VISIBILITIES)],\n 'coaching_sections.*.uuid' => 'required|uuid:coaching_sections',\n 'coaching_sections.*.score' => ['required', Rule::in(CoachingSectionFeedback::SCORES)],\n 'coaching_sections.*.summary' => 'string|max:10000',\n 'coaching_sections.*.criteria.*.uuid' => 'required|uuid:coaching_section_criteria',\n 'coaching_sections.*.criteria.*.note' => 'required|string|max:10000',\n 'sharedWithUsers' => [\n 'required_if:visibility,' . CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS,\n 'array',\n ],\n 'sharedWithUsers.*' => [\n 'uuid:users,team_id,' . $teamId,\n ],\n ]);\n\n /** @var User $coach */\n $coach = User::uuid($this->request->input('coach_id'));\n /** @var User $coachee */\n $coachee = User::uuid($this->request->input('coachee_id'));\n $coachingSectionFeedbacks = $this->request->input('coaching_sections');\n\n $previousRecord = $this->coachingFeedbackRepository->getOneForActivityByCoacheeAndCoach(\n $coachee->getId(),\n $coach->getId(),\n $activity->getId()\n );\n $recordIsNew = false;\n if ($previousRecord === null) {\n $recordIsNew = true;\n }\n\n if (! $coachee->isSameTeamId($coach)) {\n return $this->response->errorForbidden('User not member of your team.');\n }\n\n if (! is_array($coachingSectionFeedbacks) || count($coachingSectionFeedbacks) < 1) {\n return $this->response->withError('At least one Coaching Framework Section shall be scored.', 422);\n }\n\n if (! $activity->participants()->where('participants.user_id', $coachee->id)->exists()) {\n return $this->response->withError('Coached user did not participate activity.', 422);\n }\n\n $visibility = $this->request->input('visibility');\n\n $shouldSendNotification = $recordIsNew;\n if ($recordIsNew === false && $visibility !== $previousRecord->getVisibility()) {\n $shouldSendNotification = true;\n }\n\n /**\n * Create CoachingFeedback\n *\n * @var CoachingFeedback $coachingFeedback\n */\n $coachingFeedback = $activity->coachingFeedbacks()->updateOrCreate(\n [\n 'coach_id' => $coach->id,\n 'coachee_id' => $coachee->id,\n ],\n [\n 'framework_id' => $activity->category->id,\n 'visibility' => $visibility,\n ]\n );\n\n $sharedUserIds = [];\n if ($visibility === CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS) {\n foreach ($this->request->input('sharedWithUsers') as $sharedWithUserUuid) {\n /** @var User $user */\n $user = User::uuid($sharedWithUserUuid);\n $sharedUserIds[] = $user->getId();\n }\n }\n\n $syncResult = $coachingFeedback->customAccessUsers()->sync($sharedUserIds);\n\n $scores = [];\n\n\n /**\n * Create CoachingSectionsFeedbacks.\n *\n * @var CoachingSectionFeedback $coachingSectionFeedback\n */\n foreach ($coachingSectionFeedbacks as $coachingSectionFeedbackInput) {\n $coachingSection = CoachingSection::uuid($coachingSectionFeedbackInput['uuid']);\n $coachingSectionFeedback = $coachingFeedback->sectionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_id' => $coachingSection->id,\n ],\n [\n 'score' => array_get($coachingSectionFeedbackInput, 'score'),\n 'summary' => array_get($coachingSectionFeedbackInput, 'summary') ?? '',\n ]\n );\n\n $scores[] = array_get($coachingSectionFeedbackInput, 'score');\n\n $criteria = array_get($coachingSectionFeedbackInput, 'criteria');\n if (is_array($criteria) && ! empty($criteria)) {\n foreach ($criteria as $criteriaFeedbackInput) {\n $coachingSectionFeedback->criterionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_criterion_id' => CoachingSectionCriterion::uuid(array_get($criteriaFeedbackInput, 'uuid'))\n ->id,\n ],\n ['note' => array_get($criteriaFeedbackInput, 'note')],\n );\n }\n }\n }\n\n $coachingFeedback->average_score = array_sum($scores) / count($scores);\n\n if ($recordIsNew === false && $coachingFeedback->getAverageScore() !== $previousRecord->getAverageScore()) {\n $shouldSendNotification = true;\n }\n if (! empty($syncResult['attached']) || ! empty($syncResult['detached']) || ! empty($syncResult['updated'])) {\n $shouldSendNotification = true;\n }\n\n $coachingFeedback->save();\n // ensure updated at for coaching feedback on section feedback summary added.\n $coachingFeedback->touch();\n\n if ($shouldSendNotification) {\n event(new Coached($coachingFeedback));\n }\n\n Datadog::increment('jiminny.activity.score.update', 1, ['company' => $activity->user->team->slug]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n $coachingFeedbackTransformer = new CoachingFeedbackTransformer();\n $coachingFeedbackTransformer->setConsumer($this->getUserFromRequest($request));\n\n return $this->response->withItem($coachingFeedback, $coachingFeedbackTransformer);\n }\n\n\n /**\n * Retrieve category criteria for coaching.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachingSections(Activity $activity)\n {\n $this->authorize('coach', $activity);\n\n if ($activity->category === null) {\n return $this->response->errorUnprocessable('Category has not yet been assigned.');\n }\n\n $criteria = $activity\n ->category\n ->coachingSections()\n ->where('is_enabled', 1)\n ->orderBy('sequence', 'asc');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($criteria->get(), new CoachingSectionsTransformer());\n }\n\n /**\n * @throws AuthorizationException\n * @throws ValidationException\n *\n * @return mixed\n */\n public function addToPlaylist(Activity $activity, PlaylistTrackFactoryInterface $playlistTrackFactory)\n {\n $this->request->validate([\n 'playlists' => 'required|array',\n 'playlists.*' => 'uuid:playlists',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'name' => 'required|max:100',\n ]);\n\n $this->authorize('addToPlaylist', [$activity, $this->request->input('playlists')]);\n\n $startTime = $this->request->input('start_time');\n $endTime = $this->request->input('end_time');\n $name = $this->request->input('name');\n /** @var User $user */\n $user = $this->request->user();\n\n // Get playlist by uuid.\n foreach ($this->request->input('playlists') as $playlistId) {\n // Pull out the playlist model.\n $playlist = Playlist::uuid($playlistId);\n\n $playlistTrackFactory->createTrack($playlist, $user, [\n 'name' => $name,\n 'activity' => $activity,\n 'start_time' => $startTime,\n 'end_time' => $endTime,\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function share(Request $request, Activity $activity): JsonResponse\n {\n $this->authorize('share', $activity);\n\n $request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'recipients.*.type' => 'in:user,group',\n 'recipients.*.id' => 'string|max:40',\n 'share' => 'string|max:255',\n ]);\n\n $user = $request->user();\n\n $recipients = $request->get('recipients');\n $users = $this->userService->convertRecipientsToUsers($user, $recipients);\n\n $shareData = [\n 'from_user_id' => $user->id,\n 'note' => $request->input('note'),\n 'start_time' => $request->input('start_time'),\n 'end_time' => $request->input('end_time'),\n ];\n\n // Create a share object against a notification provider channel\n if ($request->input('share')) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'notification_provider_channel' => $request->input('share'),\n ]\n )\n );\n\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n\n // Create a share object against each recipient\n foreach ($users as $recipient) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'to_user_id' => $recipient->id,\n ]\n )\n );\n\n // If parent_share_id has been selected yet\n if (! isset($shareData['parent_share_id'])) {\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachRequest(Activity $activity)\n {\n $this->authorize('coachRequest', $activity);\n\n $this->request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'coachers.*.type' => 'required|in:user',\n 'coachers.*.id' => 'required',\n ]);\n\n $coachers = $this->request->get('coachers');\n $user = $this->request->user();\n $users = $this->userService->convertRecipientsToUsers($user, $coachers);\n\n foreach ($users as $coacher) {\n CoachRequest::create([\n 'user_id' => $coacher->id,\n 'activity_id' => $activity->id,\n 'note' => $this->request->get('note'),\n 'start_time' => $this->request->get('start_time'),\n 'end_time' => $this->request->get('end_time'),\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function createActivityTopicTriggers(Activity $activity, LoggerInterface $logger): HttpFoundation\\JsonResponse\n {\n $this->authorize('analyzeTopicTriggers', $activity);\n\n if (! $activity->hasTranscription()) {\n return new HttpFoundation\\JsonResponse(\n [\n 'error' => 'Transcription not found.',\n ],\n JsonResponse::HTTP_NOT_FOUND\n );\n }\n\n $logger->info(__METHOD__ . ': queued for analysis', [\n 'activity' => $activity->id_string,\n ]);\n\n dispatch(new ActivityAnalytics\\Job\\AnalyzeActivityTopicTriggers($activity));\n\n return new HttpFoundation\\JsonResponse(null, JsonResponse::HTTP_CREATED);\n }\n\n public function fetchActivityTopicTriggers(\n Activity $activity,\n LoggerInterface $logger,\n ActivityTopicTriggerTransformer $transformer\n ): HttpFoundation\\JsonResponse {\n $this->authorize('fetchTopicTriggers', $activity);\n\n $logger->debug(__METHOD__, [\n 'activity' => $activity->id_string,\n ]);\n\n if (! $activity->isProcessed()) {\n return new HttpFoundation\\JsonResponse([]);\n }\n\n $payload = [];\n\n if ($activity->hasTopicTriggers()) {\n $payload = $activity->getTopicTriggersSorted()\n ->map(\n static fn (Activity\\TopicTrigger $activityTopicTrigger): array\n => $transformer->transform($activityTopicTrigger)\n )\n ->values()\n ->all();\n }\n\n return new HttpFoundation\\JsonResponse($payload);\n }\n\n /**\n * @param Activity $activity\n * @param StatsTransformer $statsTransformer\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function stats(Activity $activity, StatsTransformer $statsTransformer)\n {\n $this->authorize('stream', $activity);\n\n if (! $activity->hasTranscription()) {\n return $this->response->errorNotFound('Waveform data is not yet generated.');\n }\n\n $this->response\n ->getManager()\n ->parseIncludes(['wavedata'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($activity, $statsTransformer);\n }\n\n public function destroy(Activity $activity)\n {\n $this->authorize('delete', $activity);\n\n $activity->delete();\n\n \\Log::info('Soft delete activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n\n return $this->response->withNoContent();\n }\n\n public function note(Activity $activity)\n {\n $this->authorize('note', $activity);\n\n $this->request->validate([\n 'note' => 'required|min:1|max:2000',\n 'time' => 'required|numeric|min:0|max:86400',\n ]);\n\n $note = $this->request->input('note');\n $time = $this->request->input('time');\n\n $this->activityService->setActivity($activity);\n $this->activityService->takeNote($this->getUser(), $note, $time);\n\n return $this->response->withCreated();\n }\n\n /**\n * Mark an activity as private.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPrivate(Activity $activity)\n {\n $this->authorize('markAsPrivate', $activity);\n\n if ($activity->is_private === false) {\n $activity->is_private = true;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * Mark an activity as public.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPublic(Activity $activity)\n {\n $this->authorize('markAsPublic', $activity);\n\n if ($activity->is_private) {\n $activity->is_private = false;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws LogicException\n */\n public function fetchCloudFrontS3MediaKeys(Activity $activity, PlaybackService $playbackService): JsonResponse\n {\n $masterTrack = $activity->masterTrack()->first();\n\n if (! $masterTrack instanceof Track) {\n throw new LogicException(sprintf('Master track not found for activity \"%s\"', $activity->getUuid()));\n }\n\n return $this->response->withArray(\n $playbackService->generateCookies(\n $masterTrack,\n $this->request->ip(),\n ),\n );\n }\n\n /**\n * @throws ValidationException\n */\n private function updateOrCreateActivitySearch(Request $request, ?Search $search = null): Search\n {\n $request->validate([\n 'name' => 'required|string|min:2|max:100',\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $searchName = $request->input('name');\n\n if ($search !== null) {\n $search->update([\n 'name' => $searchName,\n ]);\n\n return $search;\n }\n\n $request->validate([\n 'filters' => ['required', 'array', new MultidimensionalArrayMaxCharRule(limit: 255)],\n 'nudges' => 'array|max:' . count(Nudge::MAP_CHANNEL),\n 'nudges.*.channel' => 'required|in:' . implode(',', Nudge::MAP_CHANNEL),\n 'nudges.*.frequency' => 'required|in:' . implode(',', Nudge::MAP_FREQUENCY),\n 'nudges.*.expiresAt' => [\n 'required',\n 'date',\n 'after:today',\n 'before_or_equal:' . now()->addYear()->format('Y-m-d'),\n ],\n ]);\n\n $searchCriteria = Criteria::createFromRequest(\n Collection::make($request->input('filters', []))->all(),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($searchCriteria, $user);\n $this->validateSearch($request, $filterSet, 'filters.');\n\n /** @var Search $search */\n $search = Search::create([\n 'name' => $searchName,\n 'uuid' => Uuid::uuid4()->toString(),\n 'user_id' => $user->getId(),\n ]);\n\n Collection::make($request->input('nudges', []))\n ->each(fn (array $attributes): Nudge => $this->nudgeFactory->createNudge($search, $attributes));\n\n $this->storeNamedSearchFilters(Collection::make($request->all()), $search, $filterSet, 'filters.');\n\n return $search;\n }\n\n private function resolveAccount(\n Team $team,\n Contact $contact,\n ServiceInterface $crmService,\n array $prospects,\n ): ?Account {\n $this->logger->info('Resolving account from contact');\n $account = $contact->getAccount();\n\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS)) {\n $this->logger->info('Team does not have feature to link activity to multiple prospects');\n\n return $account;\n }\n\n $this->logger->info('Resolving account from prospect data');\n $accountData = array_filter(\n $prospects,\n static fn (array $prospectData): bool => $prospectData['type'] === 'account'\n );\n\n if (! empty($accountData)) {\n $this->logger->info('Found account data in prospects');\n $accountData = reset($accountData);\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountData['id'])->first();\n\n if (! $account instanceof Account) {\n $this->logger->info('Account not found in database, syncing from CRM');\n $account = $crmService->syncAccount($accountData['id']);\n }\n }\n\n $this->logger->info('Resolved account', ['account' => $account->getId()]);\n\n return $account;\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Http\\Controllers\\API;\n\nuse Carbon\\Carbon;\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Exception;\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Validation\\Rule;\nuse Illuminate\\Validation\\Rules\\In;\nuse Illuminate\\Validation\\ValidationException;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ActivityAnalytics;\nuse Jiminny\\Component\\ActivitySearch;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Contracts\\ES\\Events\\UpdateSingleEntity;\nuse Jiminny\\Contracts\\ES\\UpdateTargetEnum;\nuse Jiminny\\Contracts\\Nudge\\NudgeFactoryInterface;\nuse Jiminny\\Contracts\\Playlist\\PlaylistTrackFactoryInterface;\nuse Jiminny\\Contracts\\Repositories\\PlaylistActivityRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Enums\\TeamSetting;\nuse Jiminny\\Events\\Activities\\AiAutomation\\ActivityProspectAdded;\nuse Jiminny\\Events\\Activities\\Coaching\\Coached;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Controllers\\CommentContextInterface;\nuse Jiminny\\Http\\Responses\\Api\\AbstractResponse;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\ActivityCommentTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTopicTriggerTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTransformer;\nuse Jiminny\\Http\\Transformers\\AvailabilityNotificationTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingFeedbackTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingSectionsTransformer;\nuse Jiminny\\Http\\Transformers\\SearchTransformer;\nuse Jiminny\\Http\\Transformers\\StatsTransformer;\nuse Jiminny\\Jobs\\Crm\\SaveActivity;\nuse Jiminny\\Jobs\\Crm\\UpdateStage;\nuse Jiminny\\Jobs\\Telephony\\StartRecording;\nuse Jiminny\\Jobs\\Telephony\\StopRecording;\nuse Jiminny\\Jobs\\Telephony\\ToggleRecording;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\CoachingFeedback;\nuse Jiminny\\Models\\CoachingSection;\nuse Jiminny\\Models\\CoachingSectionCriterion;\nuse Jiminny\\Models\\CoachingSectionFeedback;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\LanguageDialect;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Nudge;\nuse Jiminny\\Models\\PlaybookCategory;\nuse Jiminny\\Models\\Playlist;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\Track;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\CoachingFeedbackRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Rules\\MultidimensionalArrayMaxCharRule;\nuse Jiminny\\Services\\ActivityService;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Services\\PlaybackService;\nuse Jiminny\\Services\\UserService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\nuse Ramsey\\Uuid\\Uuid;\nuse Sentry;\nuse Symfony\\Component\\HttpFoundation;\n\nfinal class ActivityController extends Controller implements CommentContextInterface\n{\n // Number of minutes to look back on activities. i.e. a timeout on activity duration.\n private const int LOOK_BACK = 180;\n\n public function __construct(\n private ProviderRegistry $providerRegistry,\n private ActivityService $activityService,\n Response $response,\n private UserService $userService,\n private ActivitySearch\\Service\\ActivitySearch $activitySearch,\n private NudgeFactoryInterface $nudgeFactory,\n private ActivityCommentService $activityCommentService,\n private LoggerInterface $logger,\n private readonly CoachingFeedbackRepository $coachingFeedbackRepository,\n private readonly TeamRepository $teamRepository,\n ) {\n parent::__construct($response);\n }\n\n public static function getCommentImplementation(): string\n {\n return Comment::class;\n }\n\n public function delete()\n {\n $this->request->validate([\n '*' => 'uuid:activities',\n ]);\n\n $deletedIds = [];\n foreach ($this->request->all() as $activityId) {\n $activity = Activity::idOrUuId($activityId);\n\n try {\n if ($this->authorize('delete', $activity)) {\n $activity->delete();\n $deletedIds[] = $activityId;\n\n \\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n }\n } catch (AuthorizationException $authorizationException) {\n // They didn't have permission.\n }\n }\n\n return $this->response->withArray($deletedIds);\n }\n\n public function update(Request $request, Activity $activity)\n {\n $this->authorize('updateMetadata', $activity);\n\n $request->validate([\n 'title' => 'string|max:250',\n 'category_id' => 'uuid:playbook_categories',\n 'language' => [\n new In(\n LanguageDialect::query()\n ->with('language')\n ->cursor()\n ->map(static function (LanguageDialect $languageDialect): string {\n return $languageDialect->getLanguageLocale();\n })\n ->all()\n ),\n ],\n ]);\n\n if ($request->has('title')) {\n $activity->title = $request->input('title');\n }\n\n if ($request->has('category_id')) {\n $category = PlaybookCategory::uuid($request->input('category_id'));\n\n if ($category->playbook->team_id !== $request->user()->team_id) {\n return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n if ($request->has('language')) {\n if (! $activity->isInProgress()) {\n return $this->response->withError(\n 'Activity language can only be set while the meeting is in progress.',\n 400\n );\n }\n\n $activity->setLanguageCode($request->input('language'));\n }\n\n $activity->save();\n\n return $this->response->withOk();\n }\n\n // XXX: This should be merged with the update method.\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws SocialAccountTokenInvalidException\n *\n * @return mixed\n */\n public function summarize(Activity $activity): mixed\n {\n $this->logger->info('[Log Activity] Summarizing activity ', [\n 'activityId' => $activity->getUuid(),\n 'payload' => $this->request->all(),\n ]);\n $this->authorize('update', $activity);\n\n $this->logger->info('[Log Activity] Validating summary');\n // Validate the payload.\n $this->validateSummary($activity);\n\n // All objects must belong to this team.\n /** @var User $user */\n $user = $this->request->user();\n $team = $user->getTeam();\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n try {\n $crmUser = $user;\n if ($user->isCrmRequired() === false) {\n $crmUser = $team->owner;\n }\n $crmService->setUser($crmUser);\n } catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());\n }\n\n $rawEntities = $this->request->input('entities');\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid(\n $this->request->input('layout_id')\n );\n\n // Delay execution of CRM jobs to avoid locking issues.\n $jobDelay = 0;\n\n // If we have arrived from a notification, mark it as read.\n $notificationId = $this->request->input('nId');\n if ($notificationId) {\n $notification = $user->unreadNotifications->where('id', $notificationId)->first();\n\n if ($notification) {\n $notification->markAsRead();\n }\n }\n\n $title = $this->request->input('title');\n $prospects = $this->request->input('prospects');\n $opportunityId = $this->request->input('opportunity_id');\n $stageId = $this->request->input('stage_id');\n $categoryId = $this->request->input('category_id');\n $summary = $this->request->input('summary');\n $crmProviderId = $this->request->input('crm_id');\n $isInternal = $this->request->input('is_internal') ?? false;\n\n $lead = null;\n $category = null;\n $account = null;\n $contact = null;\n $opportunity = null;\n $stage = null;\n $callStage = null;\n\n foreach ($prospects as $prospectData) {\n $objectId = $prospectData['id'];\n\n if ($objectId === null) {\n continue;\n }\n\n $objectType = $prospectData['type'];\n $this->logger->info('debug', ['prospect_data' => $prospectData]);\n\n try {\n if ($objectType === null) {\n $this->logger->info('no object type');\n if ($crmService instanceof SupportsObjectTypeParseInterface) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n }\n\n switch ($objectType) {\n case 'lead':\n $this->logger->info('Processing lead');\n /** @var Lead|null $lead */\n $lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();\n\n // Lead does not exist locally, import it.\n if ($lead === null) {\n $this->logger->info('Lead does not exist locally');\n /** @var Lead $lead */\n $lead = $crmService->syncLead($objectId);\n }\n\n $this->logger->info('Lead found', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n if ($stageId === null) {\n $this->logger->info('Stage ID is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $lead->stage;\n\n break;\n }\n\n $this->logger->info('Looking for stage');\n // Determine if they have changed the stage.\n /** @var Stage $stage */\n $stage = $team->crm->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_LEAD)\n ->firstOrFail();\n\n $this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);\n if ($lead->stage_id && $lead->stage_id !== $stage->id) {\n $this->logger->info('Stage has changed');\n // Storage current stage on activity.\n $callStage = $lead->stage;\n\n // The stage has changed, update in remote CRM.\n dispatch(new UpdateStage($activity, $lead, $callStage, $stage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing lead stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->getName(),\n $stage->getName()\n ),\n [\n 'user' => $user->getUuid(),\n 'lead' => $lead->getUuid(),\n ]\n );\n } else {\n $this->logger->info('Stage has not changed');\n // Stage remains as current.\n $callStage = $stage;\n }\n\n break;\n\n case 'account':\n $this->logger->info('Processing account');\n // If the object is not a lead, it should be an account.\n $account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();\n\n // Account does not exist locally, import it.\n if ($account === null) {\n $this->logger->info('Account does not exist locally');\n $account = $crmService->syncAccount($objectId);\n }\n\n $this->logger->info('Account found', ['accountId' => $account->id]);\n\n break;\n case 'contact':\n $this->logger->info('processing contact');\n $contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $this->logger->info('contact does not exist locally');\n $contact = $crmService->syncContact($objectId);\n }\n\n $this->logger->info('resolving account');\n $account = $this->resolveAccount($team, $contact, $crmService, $prospects);\n\n break;\n }\n\n // If they have specified an opportunity, retrieve this with stage.\n if ($opportunityId) {\n $this->logger->info('opportunity id is set');\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if ($opportunity === null) {\n $this->logger->info('opportunity does not exist locally');\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n if ($stageId === null) {\n $this->logger->info('stage id is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $opportunity->stage ?? null;\n } else {\n $this->logger->info('looking for stage');\n /** @var ?Stage $opportunityStage */\n $opportunityStage = $team->crm\n ->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n // There is a chance we still cannot import this opportunity.\n if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {\n $this->logger->info('opportunity stage has changed');\n // Storage current stage on activity.\n $callStage = $opportunity->stage;\n\n dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing opportunity stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->name,\n $opportunityStage->name\n ),\n [\n 'userId' => $user->id_string,\n 'opportunityId' => $opportunity->id_string,\n ]\n );\n } else {\n $this->logger->info('opportunity stage has not changed');\n // Stage remains as current.\n $callStage = $opportunityStage;\n }\n }\n }\n\n if ($crmProviderId) {\n // Cast $crmProviderId to string otherwise it won't use database index for some records\n $linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();\n\n // Check if this activity has already been assigned to a different activity.\n if ($linkedActivity && $linkedActivity->id !== $activity->id) {\n throw new InvalidArgumentException(\n 'Sorry, the linked task has already been logged under a different call. '\n . 'Please choose another linked task.'\n );\n }\n }\n } catch (InvalidArgumentException $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($exception->getMessage());\n } catch (Exception $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorInternalError(\n 'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'\n );\n }\n }\n\n if ($categoryId) {\n $category = PlaybookCategory::uuid($categoryId);\n\n if ($category->playbook->team_id !== $team->id) {\n throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n $this->logger->info('Prospect data', [\n 'lead_id' => $lead?->getId(),\n 'account_id' => $account?->getId(),\n 'contact_id' => $contact?->getId(),\n 'opportunity_id' => $opportunity?->getId(),\n 'stage_id' => $stage?->getId(),\n ]);\n\n if ($title) {\n $activity->title = $title;\n }\n\n if ($summary) {\n $activity->summary = $summary;\n }\n\n if ($crmProviderId) {\n $activity->crm_provider_id = $crmProviderId;\n }\n\n if ($callStage) {\n $this->logger->info('Setting stage id', ['stageId' => $callStage->id]);\n $activity->stage_id = $callStage->id;\n }\n\n if ($lead) {\n $this->logger->info('Setting lead id', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n // If we are changed from an account > lead, unset the account data.\n $this->logger->info('Unsetting account id, opportunity id, contact id, value');\n $activity->account_id = null;\n $activity->opportunity_id = null;\n $activity->contact_id = null;\n $activity->value = null;\n }\n\n if ($account) {\n $this->logger->info('Setting account id', ['accountId' => $account->id]);\n $activity->account_id = $account->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('unsetting lead id');\n $activity->lead_id = null;\n\n // Unset the contact if switching different accounts. Will be set up below if still applicable.\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {\n $this->logger->info('Unsetting contact id');\n $activity->contact_id = null;\n }\n }\n\n if ($opportunity) {\n $this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);\n $this->logger->info('unsetting lead id');\n $activity->opportunity_id = $opportunity->id;\n $activity->value = $opportunity->value;\n\n // If we are changed from an lead > account, unset the lead data.\n $activity->lead_id = null;\n }\n\n if ($contact) {\n $this->logger->info('setting contact id', ['contactId' => $contact->id]);\n $activity->contact_id = $contact->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('Unsetting lead id');\n $activity->lead_id = null;\n }\n\n $activity->is_internal = $isInternal;\n $activity->save();\n $activity->refresh();\n\n $this->logger->notice('Activity saved', [\n 'activity_id' => $activity->getId(),\n 'lead_id' => $activity->lead_id,\n 'account_id' => $activity->account_id,\n 'contact_id' => $activity->contact_id,\n 'opportunity_id' => $activity->opportunity_id,\n 'stage_id' => $activity->stage_id,\n 'crm_provider_id' => $activity->getCrmProviderId(),\n ]);\n\n // Store entities as field data on the activity.\n $updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);\n\n if ($activity->isLoggable()) {\n // Follow-up Task or Event data.\n $followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);\n\n $this->logger->info('CRM LOG manual log triggered', [\n 'activityId' => $activity->getUuid(),\n 'followupData' => $followupData,\n 'userId' => $user->getUuid(),\n ]);\n\n // Store data in the CRM.\n // ++add check for crm_required\n $job = new SaveActivity($activity, $followupData);\n\n if ($updatedData) {\n $job->delay(Carbon::now()->addMinutes($jobDelay));\n }\n\n dispatch($job);\n\n // Manually dispatch log for Opportunity or Prospect added\n if ($activity->hasOpportunity() || $activity->hasProspect()) {\n event(new ActivityProspectAdded(\n activity: $activity,\n eventSource: 'manually-log-crm-data'\n ));\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.\n *\n * @param ServiceInterface $service\n * @param Activity $activity\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array\n {\n $updatedData = [];\n $existingData = $activity->data()->get();\n\n // We need to delete any existing data to overwrite with latest values.\n $activity->data()->delete();\n\n $layoutEntities = $layout->entities()\n ->with('field', 'parent')\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->get();\n\n /** @var LayoutEntity $entity */\n foreach ($layoutEntities as $entity) {\n // If the user has provided a value for this entity\n if (array_key_exists($entity->id_string, $entities)) {\n $value = $entities[$entity->id_string];\n\n // Convert raw data into values that the CRM can consume.\n if ($value) {\n $value = $service->normalizeValue($entity->field->type, $value);\n }\n\n // Check the field is part of the activity-summary section.\n if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {\n // This is the internal database ID, not the external CRM ID.\n $objectId = null;\n\n switch ($entity->field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $objectId = $activity->account_id;\n\n break;\n\n case Field::OBJECT_CONTACT:\n $objectId = $activity->contact_id;\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n $objectId = $activity->opportunity_id;\n\n break;\n\n case Field::OBJECT_LEAD:\n $objectId = $activity->lead_id;\n\n break;\n\n case Field::OBJECT_TASK:\n case Field::OBJECT_EVENT:\n $objectId = $activity->id;\n\n break;\n }\n\n if ($objectId) {\n /** @var FieldData $data */\n $data = $activity->data()->create([\n 'crm_layout_entity_id' => $entity->id,\n 'crm_field_id' => $entity->crm_field_id,\n 'object_type' => $entity->field->object_type,\n 'object_id' => $objectId,\n 'value' => $value,\n ]);\n\n // Never send read-only field data to the CRM.\n if ($entity->read_only === false && $entity->is_visible) {\n $existingValue = $existingData\n ->where('crm_layout_entity_id', $entity->id)\n ->where('crm_field_id', $entity->crm_field_id)\n ->where('object_type', $entity->field->object_type)\n ->where('object_id', $objectId)\n ->first();\n\n // If the field was actually changed, we need to reflect this in the CRM too.\n if ($existingValue === null || $existingValue->value !== $value) {\n $updatedData[] = $data->id;\n }\n }\n }\n }\n }\n }\n\n return $updatedData;\n }\n\n /**\n * Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.\n *\n * @param ServiceInterface $crmService\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array\n {\n $fieldData = [];\n foreach ($entities as $entityId => $value) {\n // Only bother with fields that have a value.\n if ($value) {\n // Extract the entity from the UUID. Check the field is valid and part of the follow-up section.\n $entity = $layout->entities()\n ->uuid($entityId, false)\n ->whereHas('parent', function ($query) {\n $query->where('label', 'follow-up');\n })\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->first();\n\n if ($entity) {\n // Convert raw data into values that the CRM can consume.\n $value = $crmService->normalizeValue($entity->field->type, $value);\n\n // Add the field and value to the payload.\n $fieldData += [\n $entity->field->crm_provider_id => $value,\n ];\n }\n }\n }\n\n return $fieldData;\n }\n\n /**\n * @param Activity $activity\n */\n private function validateSummary(Activity $activity): void\n {\n $team = $activity->user->team;\n $crmProvider = $team->crm->provider;\n $attributes = [];\n\n $rules = [\n 'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,\n 'title' => 'string|max:250',\n 'prospects' => 'required|array',\n 'opportunity_id' => new CrmReference($crmProvider),\n 'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',\n 'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator\n 'summary' => 'max:50000',\n 'nId' => 'exists:notifications,id',\n 'crm_id' => new CrmReference($crmProvider),\n 'entities' => 'array',\n 'is_internal' => 'boolean',\n ];\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));\n\n // Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.\n $entities = $layout->entities()\n ->where('read_only', 0)\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->whereHas('parent', function ($query) use ($activity) {\n if ($activity->isLoggable() === false) {\n $query->where('label', '<>', 'follow-up');\n }\n });\n\n $isInternal = $this->request->input('is_internal', false);\n\n foreach ($entities->get() as $entity) {\n $rules += $this->buildFieldValidator($entity, $isInternal);\n $attributes += $this->buildFieldMessage($entity);\n }\n\n $this->request->validate($rules, [], $attributes);\n }\n\n private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array\n {\n return [\n 'entities.' . $entity->id_string => $entity->getValidator($isInternal),\n ];\n }\n\n /**\n * @param LayoutEntity $entity\n *\n * @return array\n */\n private function buildFieldMessage(LayoutEntity $entity): array\n {\n $label = $entity->label;\n if ($label === null) {\n $label = $entity->field->label;\n }\n\n return [\n 'entities.' . $entity->id_string => $label,\n ];\n }\n\n public function search(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->debugLog(\n $user,\n 'User extracted from request',\n ['user' => $user->getId(), 'tz' => $user->getTimezone()]\n );\n\n $searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());\n\n $this->debugLog(\n $user,\n 'ActivitySearch criteria built',\n ['searchCriteria' => $searchCriteria]\n );\n\n $filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);\n\n $this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);\n\n $this->validateSearch($request, $filterSet);\n\n $this->debugLog($user, 'Request validated');\n\n $searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);\n\n /** @var Collection<Activity> $activities */\n $activities = $searchResponse['results'];\n\n $this->debugLog($user, 'Activities ES response extracted');\n\n $hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(\n $user->getTeamId(),\n TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),\n );\n\n if ($hideInternalMeetingsSetting?->getValue() === '1') {\n $activities = $activities->filter(function (Activity $activity) {\n if ($activity->is_internal && empty($activity->actual_start_time)) {\n return false;\n }\n\n return true;\n });\n }\n\n $this->debugLog($user, 'Internal meetings (?!) filtered');\n\n $this->response->getManager()\n ->parseIncludes([\n 'category',\n 'organizer.group',\n 'prospect',\n 'stage',\n 'opportunity',\n 'stats',\n 'scorecards',\n 'masterTrack',\n 'activeParticipants',\n 'notification',\n ])\n ->setSerializer(new JsonSerializer());\n\n $transformerExcludes = $this->request->input('exclude');\n if ($transformerExcludes) {\n $this->response->getManager()->parseExcludes($transformerExcludes);\n }\n\n $this->debugLog($user, 'Response Manager (?!) applied');\n\n $transformer = new ActivityTransformer();\n $transformer->setConsumer($user);\n\n $this->debugLog($user, 'Activity Transformer added');\n\n $resource = new \\League\\Fractal\\Resource\\Collection($activities, $transformer);\n $page = $searchCriteria->getPageNumber();\n\n $this->debugLog($user, 'Search criteria page number called', ['page' => $page]);\n\n $histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');\n\n $this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);\n\n return $this->response->withArray([\n 'pagination' => [\n 'total' => $searchResponse['totalHits'],\n 'current' => $page,\n 'prev' => max($page - 1, 1),\n 'next' => $page + 1,\n ],\n 'results' => $this->response->getManager()->createData($resource)->toArray(),\n 'histogram' => $histogram,\n ]);\n }\n\n private function debugLog(User $user, string $logMessage, ?array $context = []): void\n {\n // Debug for Learning People Only\n if ($user->getTeamId() !== 260) {\n return;\n }\n\n Log::notice(\n sprintf('[activity-search-controller] %s', $logMessage),\n $context\n );\n }\n\n /** @throws ValidationException */\n private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void\n {\n $rules = [\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ];\n\n if ($prefix !== null && mb_strpos($prefix, '.') !== false) {\n $rules[rtrim($prefix, '.')] = sprintf(\n 'required|array|max:%d',\n $filterSet->count()\n );\n }\n\n $validationRules = $filterSet->getValidationRules($prefix)\n ->merge($rules)\n ->all();\n\n $request->validate($validationRules);\n }\n\n public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $search = $this->updateOrCreateActivitySearch($request);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function updateActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('update', $search);\n\n $this->updateOrCreateActivitySearch($request, $search);\n\n return $this->response->withOk();\n }\n\n private function storeNamedSearchFilters(\n Collection $request,\n Search $search,\n FilterDefinitionCollection $filterSet,\n ?string $prefix = null,\n ): self {\n $arrayTypeProperties = $filterSet\n ->getPropertyTypes([\n FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,\n ])\n ->all();\n\n $supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);\n\n foreach ($supportedRequestProperties as $requestPropertyName) {\n if (! array_has($request, $requestPropertyName)) {\n continue;\n }\n\n /** @var string|string[] $propertyValue */\n $propertyValue = array_get($request, $requestPropertyName);\n $propertyName = $prefix === null\n ? $requestPropertyName\n : mb_substr($requestPropertyName, mb_strlen($prefix));\n\n $isArrayType = array_has($arrayTypeProperties, $propertyName);\n\n if (! $isArrayType) {\n /** @var string $requestPropertyValue */\n\n $search->filters()->updateOrCreate(\n [\n 'filter' => $propertyName,\n ],\n [\n 'value' => $propertyValue,\n ]\n );\n\n continue;\n }\n\n /** @var string[] $requestPropertyValue */\n\n /** @var SearchFilter[]|Collection $existingFilterValues */\n $existingFilterValuesKeyed = $search->filters()\n ->where('filter', $propertyName)\n ->get()\n ->keyBy('id');\n\n // Iterate over values provided as request parameters\n foreach ($propertyValue as $value) {\n /** @var SearchFilter|null $valueFilter */\n $valueFilter = $search->filters()\n ->where(\n [\n 'filter' => $propertyName,\n 'value' => $value,\n ]\n )\n ->first();\n\n if ($valueFilter !== null) {\n // Remove filter value pair from list to be deleted\n $existingFilterValuesKeyed->forget($valueFilter->id);\n } else {\n // Add new filter/value pair\n $search->filters()->updateOrCreate([\n 'filter' => $propertyName,\n 'value' => $value,\n ]);\n }\n }\n\n // Delete filter value pairs for this filter that no longer exist in request parameters\n foreach ($existingFilterValuesKeyed as $existingFilter) {\n $existingFilter->delete();\n }\n }\n\n /** @var Collection<int, SearchFilter> $filtersKeyed */\n $filtersKeyed = $search->filters()->get()->keyBy('filter');\n\n // wipe removed filters from this search\n foreach ($filtersKeyed as $filterName => $filter) {\n if (array_has($request, $prefix . $filterName)) {\n continue;\n }\n\n // Remove all filter values for this filter\n $search->filters()->where('filter', $filterName)->delete();\n }\n\n return $this;\n }\n\n /**\n * @throws AuthorizationException\n */\n public function fetchActivitySearch(\n Search $search,\n Request $request,\n SearchTransformer $searchTransformer,\n ): JsonResponse {\n $this->authorize('view', $search);\n\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection(\n $user->searches()->get(),\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n /**\n * Deletes a saved search\n *\n * @param Request $request\n * @param Search $search\n *\n * @throws Exception\n *\n * @return JsonResponse\n */\n public function deleteActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('delete', $search);\n\n // Orphan any AutomatedReports that use this search\n $search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);\n\n // Delete filters and the search itself\n $search->filters()->delete();\n $search->delete();\n\n return $this->response->withOk();\n }\n\n public function live(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n $user = $this->getUserFromRequest($request);\n\n $this->request->validate([\n 'sort_direction' => 'in:asc,desc',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ]);\n\n $activities = $repository->getLiveCoachingEligibleActivities(\n user: $user,\n lookBackMinutes: self::LOOK_BACK,\n limit: (int) $this->request->input('limit', 25),\n page: (int) $this->request->input('page', 1),\n sortBy: ['actual_start_time', 'scheduled_start_time'],\n sortDirection: (string) $this->request->input('sort_direction', 'asc'),\n );\n\n $this->response\n ->getManager()\n ->parseIncludes(['organizer.group', 'prospect'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($activities, new ActivityTransformer());\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function show(Activity $activity, ActivityService $activityService): JsonResponse\n {\n $this->authorize('show', $activity);\n\n $user = $activity->getUser();\n $team = $user->getTeam();\n\n // Sync the opportunity with the latest data if possible.\n if ($activity->opportunity_id) {\n try {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n if (! $user->isCrmRequired()) {\n $crmService->setUser($team->getOwner());\n } else {\n $crmService->setUser($user);\n }\n\n $crmService->syncOpportunity($activity->opportunity->crm_provider_id);\n } catch (Exception $exception) {\n // Move on.\n }\n }\n\n $activityData = $activityService->getActivityData($this->request->user(), $activity);\n\n return response()->json($activityData);\n }\n\n public function createRecording(Activity $activity)\n {\n $this->authorize('record', $activity);\n\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Tell Twilio to start recording this activity.\n if ($activity->recording_state === Activity::RECORDING_OFF) {\n $job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withCreated();\n }\n\n return $this->response->errorGone('Activity is already recording.');\n }\n\n public function updateRecording(Request $request, Activity $activity)\n {\n $this->authorize('record', $activity);\n\n $request->validate([\n 'preference' => 'boolean',\n 'state' => [\n 'string',\n Rule::in([\n Activity::RECORDING_IN_PROGRESS,\n Activity::RECORDING_PAUSED,\n ]),\n ],\n ]);\n\n if ($request->has('state')) {\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Toggle the recording state between paused and resumed.\n if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {\n $job = (new ToggleRecording($activity, $request->input('state')))\n ->onQueue(Constants::QUEUE_CONFERENCES);\n\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Recording is not toggleable.');\n }\n\n if ($request->has('preference')) {\n $activity->update([\n 'recording_preference' => $request->input('preference') ? 1 : 0,\n ]);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorWrongArgs('Something went wrong');\n }\n\n public function stopRecording(Activity $activity)\n {\n $this->authorize('stopRecord', $activity);\n\n // Tell Twilio to stop recording this activity.\n if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {\n $job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Activity is not recording.');\n }\n\n /**\n * Add activity to this user's favorites playlist\n *\n * @throws AuthorizationException\n */\n public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse\n {\n $this->authorize('favorite', $activity);\n\n $user = $this->getUserFromRequest($this->request);\n $favorite = $activity->wasFavoritedBy($user);\n $name = $activity->activity_title ?? '';\n\n // It needs to check at least one record.\n if (! $favorite) {\n $favoritePlaylist = $user->favoritePlaylist();\n\n $playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(\n $activity,\n $user,\n $favoritePlaylist\n );\n\n if ($playlistActivity !== null) {\n $playlistActivity->update(\n // Just update, don't sort.\n ['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],\n );\n } else {\n $playlistActivity = $activity->playlistActivities()->create([\n 'playlist_id' => $favoritePlaylist->getId(),\n 'user_id' => $user->getId(),\n 'start_time' => 0,\n 'name' => mb_strimwidth($name, 0, 100),\n ]);\n // Sort it on top.\n $playlistActivity->update(\n [\n 'sort' => $playlistActivityRepository->calculateNewSortOrder(\n null,\n $playlistActivity,\n ),\n ],\n );\n }\n\n $playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);\n\n return new JsonResponse([], JsonResponse::HTTP_CREATED);\n }\n\n return new JsonResponse(\n [\n 'error' => [\n 'code' => AbstractResponse::CODE_CONFLICT,\n 'http_code' => JsonResponse::HTTP_CONFLICT,\n 'message' => 'Resource Already Exists',\n ],\n ],\n JsonResponse::HTTP_CONFLICT,\n );\n }\n\n /**\n * Remove activity from this user's favorites playlist\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unfavorite(Activity $activity)\n {\n $user = $this->request->user();\n\n $favorites = $activity->favoritedBy($user);\n\n if ($favorites && $favorites->isEmpty()) {\n return $this->response->errorNotFound('Favorite not found.');\n }\n\n $this->authorize('unfavorite', [$activity, $favorites]);\n\n // When you unfavorite an activity,\n // it should remove all the activities in it, including snippets.\n $isDeleted = $favorites->each(function ($favorite) {\n $favorite->forceDelete();\n });\n\n if ($isDeleted) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not remove favorite.');\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function notify(Activity $activity)\n {\n $this->authorize('notify', $activity);\n\n $user = $this->request->user();\n\n $existingNotification = $activity->availabilityNotifications()\n ->where('user_id', $user->id)\n ->exists();\n\n if ($existingNotification) {\n return $this->response->errorWrongArgs('Notification is already configured.');\n }\n\n $notification = Activity\\AvailabilityNotification::create([\n 'user_id' => $user->id,\n 'activity_id' => $activity->id,\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($notification, new AvailabilityNotificationTransformer());\n }\n\n /**\n * @param Activity $activity\n * @param Activity\\AvailabilityNotification $notification\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unnotify(Activity $activity, Activity\\AvailabilityNotification $notification)\n {\n $this->authorize('unnotify', [$activity, $notification]);\n\n if ($notification->sent_at || $notification->delete()) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not delete notification.');\n }\n\n public function play(Request $request, Activity $activity)\n {\n $this->authorize('stream', $activity);\n\n $request->validate([\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $activity->plays()->create([\n 'user_id' => $user->getId(),\n 'start_time' => $request->input('start_time'),\n ]);\n\n return $this->response->withCreated();\n }\n\n /**\n * @param Activity $activity\n *\n * @return mixed\n */\n public function comment(Activity $activity)\n {\n return $this->newComment($activity);\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @return mixed\n */\n public function replyComment(Activity $activity, Comment $comment)\n {\n return $this->newComment($activity, $comment);\n }\n\n /**\n * @param Activity $activity\n * @param Comment|null $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n protected function newComment(Activity $activity, ?Comment $comment = null)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n 'type' => 'integer|between:0,3',\n 'visibility' => sprintf('nullable|integer|between:1,%d', count(Comment::getVisibilityLevels())),\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n $threadStartId = null;\n if ($comment) {\n $threadStartId = $comment->thread_start_id ?: $comment->id;\n }\n\n try {\n $newComment = Comment::create([\n 'parent_comment_id' => $comment->id ?? null,\n 'thread_start_id' => $threadStartId,\n 'activity_id' => $activity->id,\n 'user_id' => $this->request->user()->id,\n 'comment' => trim($this->request->input('comment')),\n 'start_time' => $this->request->input('start_time', 0),\n 'end_time' => $this->request->input('end_time', 0),\n 'type' => $this->request->input('type', Comment::TYPE_NEUTRAL),\n 'visibility' => $this->request->input('visibility', Comment::VISIBILITY_PUBLIC),\n ]);\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($newComment, new ActivityCommentTransformer());\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not create comment.' . $exception->getMessage());\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function updateComment(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n try {\n $comment->update([\n 'comment' => trim($this->request->input('comment')),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment.');\n }\n }\n\n public function updateCommentVisibility(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'visibility' => sprintf('integer|between:1,%d', count(Comment::getVisibilityLevels())),\n ]);\n\n $visibility = $this->request->input('visibility');\n\n if ($comment->parent !== null) {\n return $this->response->errorWrongArgs('Comment visibility can only be updated on top level comments.');\n }\n\n try {\n $this->activityCommentService->updateCommentVisibility($comment, $visibility);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment\\'s visibility.');\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function deleteComment(Activity $activity, Comment $comment)\n {\n $this->authorize('deleteComment', [$activity, $comment]);\n\n // Delete comment and any children.\n $comment->delete();\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function fetchComments()\n {\n $user = $this->request->user();\n $this->request->validate([\n 'forUserId' => 'uuid:users,team_id,' . $user->team_id,\n 'types' => 'array',\n 'types.*' => 'integer|between:0,3',\n ]);\n $forUser = null;\n\n $types = [Comment::TYPE_NEUTRAL, Comment::TYPE_GAME_CHANGER, Comment::TYPE_POSITIVE];\n $user = $this->request->user();\n if ($this->request->has('forUserId')) {\n $forUser = $user->team->users()->uuid($this->request->input('forUserId'));\n }\n\n $comments = Comment::query()\n ->whereHas('activity', static function (Builder $builder) use ($user, $forUser): void {\n $builder\n // I left feedback on my own activity; or\n ->where('activities.user_id', $user->getId());\n if ($forUser) {\n // I left feedback on any activity for this user.\n $builder->orWhere([\n 'user_id' => $user->getId(),\n 'activities.user_id' => $forUser->getId(),\n ]);\n }\n })\n ->whereIn('type', $this->request->input('types', $types))\n ->orderBy('created_at', 'desc')\n ->get();\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity', 'user'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($comments, new ActivityCommentTransformer());\n }\n\n public function deleteCoachingFeedback(Activity $activity, CoachingFeedback $coachingFeedback)\n {\n $this->authorize('deleteCoachingFeedback', [$activity, $coachingFeedback]);\n $activity = $coachingFeedback->getActivity();\n\n if ($coachingFeedback->delete()) {\n event(new UpdateSingleEntity(\n entityId: $activity->getId(),\n updateTarget: UpdateTargetEnum::ACTIVITY,\n purpose: 'delete-coaching-feedback',\n ));\n\n return $this->response->withOk();\n }\n\n return $this->response->withError('Delete operation failed. Contact support.', 500);\n }\n\n /**\n * Add new or update Coaching feedback\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws \\Illuminate\\Validation\\ValidationException\n *\n * @return mixed\n */\n public function putCoachingFeedback(Request $request, Activity $activity)\n {\n $user = $request->user();\n\n if (! $user instanceof User) {\n abort(403);\n }\n $teamId = $user->getTeamId();\n\n $this->authorize('coach', $activity);\n\n $this->request->validate([\n 'coach_id' => 'required|uuid:users,team_id,' . $teamId,\n 'coachee_id' => 'required|uuid:users,team_id,' . $teamId,\n 'visibility' => ['required', Rule::in(CoachingFeedback::VISIBILITIES)],\n 'coaching_sections.*.uuid' => 'required|uuid:coaching_sections',\n 'coaching_sections.*.score' => ['required', Rule::in(CoachingSectionFeedback::SCORES)],\n 'coaching_sections.*.summary' => 'string|max:10000',\n 'coaching_sections.*.criteria.*.uuid' => 'required|uuid:coaching_section_criteria',\n 'coaching_sections.*.criteria.*.note' => 'required|string|max:10000',\n 'sharedWithUsers' => [\n 'required_if:visibility,' . CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS,\n 'array',\n ],\n 'sharedWithUsers.*' => [\n 'uuid:users,team_id,' . $teamId,\n ],\n ]);\n\n /** @var User $coach */\n $coach = User::uuid($this->request->input('coach_id'));\n /** @var User $coachee */\n $coachee = User::uuid($this->request->input('coachee_id'));\n $coachingSectionFeedbacks = $this->request->input('coaching_sections');\n\n $previousRecord = $this->coachingFeedbackRepository->getOneForActivityByCoacheeAndCoach(\n $coachee->getId(),\n $coach->getId(),\n $activity->getId()\n );\n $recordIsNew = false;\n if ($previousRecord === null) {\n $recordIsNew = true;\n }\n\n if (! $coachee->isSameTeamId($coach)) {\n return $this->response->errorForbidden('User not member of your team.');\n }\n\n if (! is_array($coachingSectionFeedbacks) || count($coachingSectionFeedbacks) < 1) {\n return $this->response->withError('At least one Coaching Framework Section shall be scored.', 422);\n }\n\n if (! $activity->participants()->where('participants.user_id', $coachee->id)->exists()) {\n return $this->response->withError('Coached user did not participate activity.', 422);\n }\n\n $visibility = $this->request->input('visibility');\n\n $shouldSendNotification = $recordIsNew;\n if ($recordIsNew === false && $visibility !== $previousRecord->getVisibility()) {\n $shouldSendNotification = true;\n }\n\n /**\n * Create CoachingFeedback\n *\n * @var CoachingFeedback $coachingFeedback\n */\n $coachingFeedback = $activity->coachingFeedbacks()->updateOrCreate(\n [\n 'coach_id' => $coach->id,\n 'coachee_id' => $coachee->id,\n ],\n [\n 'framework_id' => $activity->category->id,\n 'visibility' => $visibility,\n ]\n );\n\n $sharedUserIds = [];\n if ($visibility === CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS) {\n foreach ($this->request->input('sharedWithUsers') as $sharedWithUserUuid) {\n /** @var User $user */\n $user = User::uuid($sharedWithUserUuid);\n $sharedUserIds[] = $user->getId();\n }\n }\n\n $syncResult = $coachingFeedback->customAccessUsers()->sync($sharedUserIds);\n\n $scores = [];\n\n\n /**\n * Create CoachingSectionsFeedbacks.\n *\n * @var CoachingSectionFeedback $coachingSectionFeedback\n */\n foreach ($coachingSectionFeedbacks as $coachingSectionFeedbackInput) {\n $coachingSection = CoachingSection::uuid($coachingSectionFeedbackInput['uuid']);\n $coachingSectionFeedback = $coachingFeedback->sectionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_id' => $coachingSection->id,\n ],\n [\n 'score' => array_get($coachingSectionFeedbackInput, 'score'),\n 'summary' => array_get($coachingSectionFeedbackInput, 'summary') ?? '',\n ]\n );\n\n $scores[] = array_get($coachingSectionFeedbackInput, 'score');\n\n $criteria = array_get($coachingSectionFeedbackInput, 'criteria');\n if (is_array($criteria) && ! empty($criteria)) {\n foreach ($criteria as $criteriaFeedbackInput) {\n $coachingSectionFeedback->criterionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_criterion_id' => CoachingSectionCriterion::uuid(array_get($criteriaFeedbackInput, 'uuid'))\n ->id,\n ],\n ['note' => array_get($criteriaFeedbackInput, 'note')],\n );\n }\n }\n }\n\n $coachingFeedback->average_score = array_sum($scores) / count($scores);\n\n if ($recordIsNew === false && $coachingFeedback->getAverageScore() !== $previousRecord->getAverageScore()) {\n $shouldSendNotification = true;\n }\n if (! empty($syncResult['attached']) || ! empty($syncResult['detached']) || ! empty($syncResult['updated'])) {\n $shouldSendNotification = true;\n }\n\n $coachingFeedback->save();\n // ensure updated at for coaching feedback on section feedback summary added.\n $coachingFeedback->touch();\n\n if ($shouldSendNotification) {\n event(new Coached($coachingFeedback));\n }\n\n Datadog::increment('jiminny.activity.score.update', 1, ['company' => $activity->user->team->slug]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n $coachingFeedbackTransformer = new CoachingFeedbackTransformer();\n $coachingFeedbackTransformer->setConsumer($this->getUserFromRequest($request));\n\n return $this->response->withItem($coachingFeedback, $coachingFeedbackTransformer);\n }\n\n\n /**\n * Retrieve category criteria for coaching.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachingSections(Activity $activity)\n {\n $this->authorize('coach', $activity);\n\n if ($activity->category === null) {\n return $this->response->errorUnprocessable('Category has not yet been assigned.');\n }\n\n $criteria = $activity\n ->category\n ->coachingSections()\n ->where('is_enabled', 1)\n ->orderBy('sequence', 'asc');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($criteria->get(), new CoachingSectionsTransformer());\n }\n\n /**\n * @throws AuthorizationException\n * @throws ValidationException\n *\n * @return mixed\n */\n public function addToPlaylist(Activity $activity, PlaylistTrackFactoryInterface $playlistTrackFactory)\n {\n $this->request->validate([\n 'playlists' => 'required|array',\n 'playlists.*' => 'uuid:playlists',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'name' => 'required|max:100',\n ]);\n\n $this->authorize('addToPlaylist', [$activity, $this->request->input('playlists')]);\n\n $startTime = $this->request->input('start_time');\n $endTime = $this->request->input('end_time');\n $name = $this->request->input('name');\n /** @var User $user */\n $user = $this->request->user();\n\n // Get playlist by uuid.\n foreach ($this->request->input('playlists') as $playlistId) {\n // Pull out the playlist model.\n $playlist = Playlist::uuid($playlistId);\n\n $playlistTrackFactory->createTrack($playlist, $user, [\n 'name' => $name,\n 'activity' => $activity,\n 'start_time' => $startTime,\n 'end_time' => $endTime,\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function share(Request $request, Activity $activity): JsonResponse\n {\n $this->authorize('share', $activity);\n\n $request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'recipients.*.type' => 'in:user,group',\n 'recipients.*.id' => 'string|max:40',\n 'share' => 'string|max:255',\n ]);\n\n $user = $request->user();\n\n $recipients = $request->get('recipients');\n $users = $this->userService->convertRecipientsToUsers($user, $recipients);\n\n $shareData = [\n 'from_user_id' => $user->id,\n 'note' => $request->input('note'),\n 'start_time' => $request->input('start_time'),\n 'end_time' => $request->input('end_time'),\n ];\n\n // Create a share object against a notification provider channel\n if ($request->input('share')) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'notification_provider_channel' => $request->input('share'),\n ]\n )\n );\n\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n\n // Create a share object against each recipient\n foreach ($users as $recipient) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'to_user_id' => $recipient->id,\n ]\n )\n );\n\n // If parent_share_id has been selected yet\n if (! isset($shareData['parent_share_id'])) {\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachRequest(Activity $activity)\n {\n $this->authorize('coachRequest', $activity);\n\n $this->request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'coachers.*.type' => 'required|in:user',\n 'coachers.*.id' => 'required',\n ]);\n\n $coachers = $this->request->get('coachers');\n $user = $this->request->user();\n $users = $this->userService->convertRecipientsToUsers($user, $coachers);\n\n foreach ($users as $coacher) {\n CoachRequest::create([\n 'user_id' => $coacher->id,\n 'activity_id' => $activity->id,\n 'note' => $this->request->get('note'),\n 'start_time' => $this->request->get('start_time'),\n 'end_time' => $this->request->get('end_time'),\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function createActivityTopicTriggers(Activity $activity, LoggerInterface $logger): HttpFoundation\\JsonResponse\n {\n $this->authorize('analyzeTopicTriggers', $activity);\n\n if (! $activity->hasTranscription()) {\n return new HttpFoundation\\JsonResponse(\n [\n 'error' => 'Transcription not found.',\n ],\n JsonResponse::HTTP_NOT_FOUND\n );\n }\n\n $logger->info(__METHOD__ . ': queued for analysis', [\n 'activity' => $activity->id_string,\n ]);\n\n dispatch(new ActivityAnalytics\\Job\\AnalyzeActivityTopicTriggers($activity));\n\n return new HttpFoundation\\JsonResponse(null, JsonResponse::HTTP_CREATED);\n }\n\n public function fetchActivityTopicTriggers(\n Activity $activity,\n LoggerInterface $logger,\n ActivityTopicTriggerTransformer $transformer\n ): HttpFoundation\\JsonResponse {\n $this->authorize('fetchTopicTriggers', $activity);\n\n $logger->debug(__METHOD__, [\n 'activity' => $activity->id_string,\n ]);\n\n if (! $activity->isProcessed()) {\n return new HttpFoundation\\JsonResponse([]);\n }\n\n $payload = [];\n\n if ($activity->hasTopicTriggers()) {\n $payload = $activity->getTopicTriggersSorted()\n ->map(\n static fn (Activity\\TopicTrigger $activityTopicTrigger): array\n => $transformer->transform($activityTopicTrigger)\n )\n ->values()\n ->all();\n }\n\n return new HttpFoundation\\JsonResponse($payload);\n }\n\n /**\n * @param Activity $activity\n * @param StatsTransformer $statsTransformer\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function stats(Activity $activity, StatsTransformer $statsTransformer)\n {\n $this->authorize('stream', $activity);\n\n if (! $activity->hasTranscription()) {\n return $this->response->errorNotFound('Waveform data is not yet generated.');\n }\n\n $this->response\n ->getManager()\n ->parseIncludes(['wavedata'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($activity, $statsTransformer);\n }\n\n public function destroy(Activity $activity)\n {\n $this->authorize('delete', $activity);\n\n $activity->delete();\n\n \\Log::info('Soft delete activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n\n return $this->response->withNoContent();\n }\n\n public function note(Activity $activity)\n {\n $this->authorize('note', $activity);\n\n $this->request->validate([\n 'note' => 'required|min:1|max:2000',\n 'time' => 'required|numeric|min:0|max:86400',\n ]);\n\n $note = $this->request->input('note');\n $time = $this->request->input('time');\n\n $this->activityService->setActivity($activity);\n $this->activityService->takeNote($this->getUser(), $note, $time);\n\n return $this->response->withCreated();\n }\n\n /**\n * Mark an activity as private.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPrivate(Activity $activity)\n {\n $this->authorize('markAsPrivate', $activity);\n\n if ($activity->is_private === false) {\n $activity->is_private = true;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * Mark an activity as public.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPublic(Activity $activity)\n {\n $this->authorize('markAsPublic', $activity);\n\n if ($activity->is_private) {\n $activity->is_private = false;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws LogicException\n */\n public function fetchCloudFrontS3MediaKeys(Activity $activity, PlaybackService $playbackService): JsonResponse\n {\n $masterTrack = $activity->masterTrack()->first();\n\n if (! $masterTrack instanceof Track) {\n throw new LogicException(sprintf('Master track not found for activity \"%s\"', $activity->getUuid()));\n }\n\n return $this->response->withArray(\n $playbackService->generateCookies(\n $masterTrack,\n $this->request->ip(),\n ),\n );\n }\n\n /**\n * @throws ValidationException\n */\n private function updateOrCreateActivitySearch(Request $request, ?Search $search = null): Search\n {\n $request->validate([\n 'name' => 'required|string|min:2|max:100',\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $searchName = $request->input('name');\n\n if ($search !== null) {\n $search->update([\n 'name' => $searchName,\n ]);\n\n return $search;\n }\n\n $request->validate([\n 'filters' => ['required', 'array', new MultidimensionalArrayMaxCharRule(limit: 255)],\n 'nudges' => 'array|max:' . count(Nudge::MAP_CHANNEL),\n 'nudges.*.channel' => 'required|in:' . implode(',', Nudge::MAP_CHANNEL),\n 'nudges.*.frequency' => 'required|in:' . implode(',', Nudge::MAP_FREQUENCY),\n 'nudges.*.expiresAt' => [\n 'required',\n 'date',\n 'after:today',\n 'before_or_equal:' . now()->addYear()->format('Y-m-d'),\n ],\n ]);\n\n $searchCriteria = Criteria::createFromRequest(\n Collection::make($request->input('filters', []))->all(),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($searchCriteria, $user);\n $this->validateSearch($request, $filterSet, 'filters.');\n\n /** @var Search $search */\n $search = Search::create([\n 'name' => $searchName,\n 'uuid' => Uuid::uuid4()->toString(),\n 'user_id' => $user->getId(),\n ]);\n\n Collection::make($request->input('nudges', []))\n ->each(fn (array $attributes): Nudge => $this->nudgeFactory->createNudge($search, $attributes));\n\n $this->storeNamedSearchFilters(Collection::make($request->all()), $search, $filterSet, 'filters.');\n\n return $search;\n }\n\n private function resolveAccount(\n Team $team,\n Contact $contact,\n ServiceInterface $crmService,\n array $prospects,\n ): ?Account {\n $this->logger->info('Resolving account from contact');\n $account = $contact->getAccount();\n\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS)) {\n $this->logger->info('Team does not have feature to link activity to multiple prospects');\n\n return $account;\n }\n\n $this->logger->info('Resolving account from prospect data');\n $accountData = array_filter(\n $prospects,\n static fn (array $prospectData): bool => $prospectData['type'] === 'account'\n );\n\n if (! empty($accountData)) {\n $this->logger->info('Found account data in prospects');\n $accountData = reset($accountData);\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountData['id'])->first();\n\n if (! $account instanceof Account) {\n $this->logger->info('Account not found in database, syncing from CRM');\n $account = $crmService->syncAccount($accountData['id']);\n }\n }\n\n $this->logger->info('Resolved account', ['account' => $account->getId()]);\n\n return $account;\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":"40","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"40","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"64","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","depth":4,"on_screen":true,"value":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","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}]...
|
-7287184300264252456
|
-8385861013499833196
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use Carbon\Carbon;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\In;
use Illuminate\Validation\ValidationException;
use InvalidArgumentException;
use Jiminny\Component\ActivityAnalytics;
use Jiminny\Component\ActivitySearch;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Queue\Constants;
use Jiminny\Contracts\ES\Events\UpdateSingleEntity;
use Jiminny\Contracts\ES\UpdateTargetEnum;
use Jiminny\Contracts\Nudge\NudgeFactoryInterface;
use Jiminny\Contracts\Playlist\PlaylistTrackFactoryInterface;
use Jiminny\Contracts\Repositories\PlaylistActivityRepository;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Enums\TeamSetting;
use Jiminny\Events\Activities\AiAutomation\ActivityProspectAdded;
use Jiminny\Events\Activities\Coaching\Coached;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Controllers\CommentContextInterface;
use Jiminny\Http\Responses\Api\AbstractResponse;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\ActivityCommentTransformer;
use Jiminny\Http\Transformers\ActivityTopicTriggerTransformer;
use Jiminny\Http\Transformers\ActivityTransformer;
use Jiminny\Http\Transformers\AvailabilityNotificationTransformer;
use Jiminny\Http\Transformers\CoachingFeedbackTransformer;
use Jiminny\Http\Transformers\CoachingSectionsTransformer;
use Jiminny\Http\Transformers\SearchTransformer;
use Jiminny\Http\Transformers\StatsTransformer;
use Jiminny\Jobs\Crm\SaveActivity;
use Jiminny\Jobs\Crm\UpdateStage;
use Jiminny\Jobs\Telephony\StartRecording;
use Jiminny\Jobs\Telephony\StopRecording;
use Jiminny\Jobs\Telephony\ToggleRecording;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\CoachingFeedback;
use Jiminny\Models\CoachingSection;
use Jiminny\Models\CoachingSectionCriterion;
use Jiminny\Models\CoachingSectionFeedback;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\LanguageDialect;
use Jiminny\Models\Lead;
use Jiminny\Models\Nudge;
use Jiminny\Models\PlaybookCategory;
use Jiminny\Models\Playlist;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\Track;
use Jiminny\Models\User;
use Jiminny\Repositories\CoachingFeedbackRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Rules\CrmReference;
use Jiminny\Rules\MultidimensionalArrayMaxCharRule;
use Jiminny\Services\ActivityService;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Services\PlaybackService;
use Jiminny\Services\UserService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
use Ramsey\Uuid\Uuid;
use Sentry;
use Symfony\Component\HttpFoundation;
final class ActivityController extends Controller implements CommentContextInterface
{
// Number of minutes to look back on activities. i.e. a timeout on activity duration.
private const int LOOK_BACK = 180;
public function __construct(
private ProviderRegistry $providerRegistry,
private ActivityService $activityService,
Response $response,
private UserService $userService,
private ActivitySearch\Service\ActivitySearch $activitySearch,
private NudgeFactoryInterface $nudgeFactory,
private ActivityCommentService $activityCommentService,
private LoggerInterface $logger,
private readonly CoachingFeedbackRepository $coachingFeedbackRepository,
private readonly TeamRepository $teamRepository,
) {
parent::__construct($response);
}
public static function getCommentImplementation(): string
{
return Comment::class;
}
public function delete()
{
$this->request->validate([
'*' => 'uuid:activities',
]);
$deletedIds = [];
foreach ($this->request->all() as $activityId) {
$activity = Activity::idOrUuId($activityId);
try {
if ($this->authorize('delete', $activity)) {
$activity->delete();
$deletedIds[] = $activityId;
\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);
}
} catch (AuthorizationException $authorizationException) {
// They didn't have permission.
}
}
return $this->response->withArray($deletedIds);
}
public function update(Request $request, Activity $activity)
{
$this->authorize('updateMetadata', $activity);
$request->validate([
'title' => 'string|max:250',
'category_id' => 'uuid:playbook_categories',
'language' => [
new In(
LanguageDialect::query()
->with('language')
->cursor()
->map(static function (LanguageDialect $languageDialect): string {
return $languageDialect->getLanguageLocale();
})
->all()
),
],
]);
if ($request->has('title')) {
$activity->title = $request->input('title');
}
if ($request->has('category_id')) {
$category = PlaybookCategory::uuid($request->input('category_id'));
if ($category->playbook->team_id !== $request->user()->team_id) {
return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
if ($request->has('language')) {
if (! $activity->isInProgress()) {
return $this->response->withError(
'Activity language can only be set while the meeting is in progress.',
400
);
}
$activity->setLanguageCode($request->input('language'));
}
$activity->save();
return $this->response->withOk();
}
// XXX: This should be merged with the update method.
/**
* @param Activity $activity
*
* @throws AuthorizationException
* @throws SocialAccountTokenInvalidException
*
* @return mixed
*/
public function summarize(Activity $activity): mixed
{
$this->logger->info('[Log Activity] Summarizing activity ', [
'activityId' => $activity->getUuid(),
'payload' => $this->request->all(),
]);
$this->authorize('update', $activity);
$this->logger->info('[Log Activity] Validating summary');
// Validate the payload.
$this->validateSummary($activity);
// All objects must belong to this team.
/** @var User $user */
$user = $this->request->user();
$team = $user->getTeam();
$crmService = $this->providerRegistry->get($team->crm->provider);
try {
$crmUser = $user;
if ($user->isCrmRequired() === false) {
$crmUser = $team->owner;
}
$crmService->setUser($crmUser);
} catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());
}
$rawEntities = $this->request->input('entities');
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid(
$this->request->input('layout_id')
);
// Delay execution of CRM jobs to avoid locking issues.
$jobDelay = 0;
// If we have arrived from a notification, mark it as read.
$notificationId = $this->request->input('nId');
if ($notificationId) {
$notification = $user->unreadNotifications->where('id', $notificationId)->first();
if ($notification) {
$notification->markAsRead();
}
}
$title = $this->request->input('title');
$prospects = $this->request->input('prospects');
$opportunityId = $this->request->input('opportunity_id');
$stageId = $this->request->input('stage_id');
$categoryId = $this->request->input('category_id');
$summary = $this->request->input('summary');
$crmProviderId = $this->request->input('crm_id');
$isInternal = $this->request->input('is_internal') ?? false;
$lead = null;
$category = null;
$account = null;
$contact = null;
$opportunity = null;
$stage = null;
$callStage = null;
foreach ($prospects as $prospectData) {
$objectId = $prospectData['id'];
if ($objectId === null) {
continue;
}
$objectType = $prospectData['type'];
$this->logger->info('debug', ['prospect_data' => $prospectData]);
try {
if ($objectType === null) {
$this->logger->info('no object type');
if ($crmService instanceof SupportsObjectTypeParseInterface) {
$objectType = $crmService->parseObjectType($objectId);
}
}
switch ($objectType) {
case 'lead':
$this->logger->info('Processing lead');
/** @var Lead|null $lead */
$lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();
// Lead does not exist locally, import it.
if ($lead === null) {
$this->logger->info('Lead does not exist locally');
/** @var Lead $lead */
$lead = $crmService->syncLead($objectId);
}
$this->logger->info('Lead found', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
if ($stageId === null) {
$this->logger->info('Stage ID is null');
// If it was not provided, just assume it is the current stage.
$callStage = $lead->stage;
break;
}
$this->logger->info('Looking for stage');
// Determine if they have changed the stage.
/** @var Stage $stage */
$stage = $team->crm->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_LEAD)
->firstOrFail();
$this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);
if ($lead->stage_id && $lead->stage_id !== $stage->id) {
$this->logger->info('Stage has changed');
// Storage current stage on activity.
$callStage = $lead->stage;
// The stage has changed, update in remote CRM.
dispatch(new UpdateStage($activity, $lead, $callStage, $stage));
$this->logger->info(
sprintf(
'[%s] User changing lead stage from %s to %s',
$crmService->getDisplayName(),
$callStage->getName(),
$stage->getName()
),
[
'user' => $user->getUuid(),
'lead' => $lead->getUuid(),
]
);
} else {
$this->logger->info('Stage has not changed');
// Stage remains as current.
$callStage = $stage;
}
break;
case 'account':
$this->logger->info('Processing account');
// If the object is not a lead, it should be an account.
$account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();
// Account does not exist locally, import it.
if ($account === null) {
$this->logger->info('Account does not exist locally');
$account = $crmService->syncAccount($objectId);
}
$this->logger->info('Account found', ['accountId' => $account->id]);
break;
case 'contact':
$this->logger->info('processing contact');
$contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$this->logger->info('contact does not exist locally');
$contact = $crmService->syncContact($objectId);
}
$this->logger->info('resolving account');
$account = $this->resolveAccount($team, $contact, $crmService, $prospects);
break;
}
// If they have specified an opportunity, retrieve this with stage.
if ($opportunityId) {
$this->logger->info('opportunity id is set');
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if ($opportunity === null) {
$this->logger->info('opportunity does not exist locally');
$opportunity = $crmService->syncOpportunity($opportunityId);
}
if ($stageId === null) {
$this->logger->info('stage id is null');
// If it was not provided, just assume it is the current stage.
$callStage = $opportunity->stage ?? null;
} else {
$this->logger->info('looking for stage');
/** @var ?Stage $opportunityStage */
$opportunityStage = $team->crm
->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
// There is a chance we still cannot import this opportunity.
if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {
$this->logger->info('opportunity stage has changed');
// Storage current stage on activity.
$callStage = $opportunity->stage;
dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));
$this->logger->info(
sprintf(
'[%s] User changing opportunity stage from %s to %s',
$crmService->getDisplayName(),
$callStage->name,
$opportunityStage->name
),
[
'userId' => $user->id_string,
'opportunityId' => $opportunity->id_string,
]
);
} else {
$this->logger->info('opportunity stage has not changed');
// Stage remains as current.
$callStage = $opportunityStage;
}
}
}
if ($crmProviderId) {
// Cast $crmProviderId to string otherwise it won't use database index for some records
$linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();
// Check if this activity has already been assigned to a different activity.
if ($linkedActivity && $linkedActivity->id !== $activity->id) {
throw new InvalidArgumentException(
'Sorry, the linked task has already been logged under a different call. '
. 'Please choose another linked task.'
);
}
}
} catch (InvalidArgumentException $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($exception->getMessage());
} catch (Exception $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorInternalError(
'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'
);
}
}
if ($categoryId) {
$category = PlaybookCategory::uuid($categoryId);
if ($category->playbook->team_id !== $team->id) {
throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
$this->logger->info('Prospect data', [
'lead_id' => $lead?->getId(),
'account_id' => $account?->getId(),
'contact_id' => $contact?->getId(),
'opportunity_id' => $opportunity?->getId(),
'stage_id' => $stage?->getId(),
]);
if ($title) {
$activity->title = $title;
}
if ($summary) {
$activity->summary = $summary;
}
if ($crmProviderId) {
$activity->crm_provider_id = $crmProviderId;
}
if ($callStage) {
$this->logger->info('Setting stage id', ['stageId' => $callStage->id]);
$activity->stage_id = $callStage->id;
}
if ($lead) {
$this->logger->info('Setting lead id', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
// If we are changed from an account > lead, unset the account data.
$this->logger->info('Unsetting account id, opportunity id, contact id, value');
$activity->account_id = null;
$activity->opportunity_id = null;
$activity->contact_id = null;
$activity->value = null;
}
if ($account) {
$this->logger->info('Setting account id', ['accountId' => $account->id]);
$activity->account_id = $account->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('unsetting lead id');
$activity->lead_id = null;
// Unset the contact if switching different accounts. Will be set up below if still applicable.
if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {
$this->logger->info('Unsetting contact id');
$activity->contact_id = null;
}
}
if ($opportunity) {
$this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);
$this->logger->info('unsetting lead id');
$activity->opportunity_id = $opportunity->id;
$activity->value = $opportunity->value;
// If we are changed from an lead > account, unset the lead data.
$activity->lead_id = null;
}
if ($contact) {
$this->logger->info('setting contact id', ['contactId' => $contact->id]);
$activity->contact_id = $contact->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('Unsetting lead id');
$activity->lead_id = null;
}
$activity->is_internal = $isInternal;
$activity->save();
$activity->refresh();
$this->logger->notice('Activity saved', [
'activity_id' => $activity->getId(),
'lead_id' => $activity->lead_id,
'account_id' => $activity->account_id,
'contact_id' => $activity->contact_id,
'opportunity_id' => $activity->opportunity_id,
'stage_id' => $activity->stage_id,
'crm_provider_id' => $activity->getCrmProviderId(),
]);
// Store entities as field data on the activity.
$updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);
if ($activity->isLoggable()) {
// Follow-up Task or Event data.
$followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);
$this->logger->info('CRM LOG manual log triggered', [
'activityId' => $activity->getUuid(),
'followupData' => $followupData,
'userId' => $user->getUuid(),
]);
// Store data in the CRM.
// ++add check for crm_required
$job = new SaveActivity($activity, $followupData);
if ($updatedData) {
$job->delay(Carbon::now()->addMinutes($jobDelay));
}
dispatch($job);
// Manually dispatch log for Opportunity or Prospect added
if ($activity->hasOpportunity() || $activity->hasProspect()) {
event(new ActivityProspectAdded(
activity: $activity,
eventSource: 'manually-log-crm-data'
));
}
}
return $this->response->withOk();
}
/**
* Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.
*
* @param ServiceInterface $service
* @param Activity $activity
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array
{
$updatedData = [];
$existingData = $activity->data()->get();
// We need to delete any existing data to overwrite with latest values.
$activity->data()->delete();
$layoutEntities = $layout->entities()
->with('field', 'parent')
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->get();
/** @var LayoutEntity $entity */
foreach ($layoutEntities as $entity) {
// If the user has provided a value for this entity
if (array_key_exists($entity->id_string, $entities)) {
$value = $entities[$entity->id_string];
// Convert raw data into values that the CRM can consume.
if ($value) {
$value = $service->normalizeValue($entity->field->type, $value);
}
// Check the field is part of the activity-summary section.
if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {
// This is the internal database ID, not the external CRM ID.
$objectId = null;
switch ($entity->field->object_type) {
case Field::OBJECT_ACCOUNT:
$objectId = $activity->account_id;
break;
case Field::OBJECT_CONTACT:
$objectId = $activity->contact_id;
break;
case Field::OBJECT_OPPORTUNITY:
$objectId = $activity->opportunity_id;
break;
case Field::OBJECT_LEAD:
$objectId = $activity->lead_id;
break;
case Field::OBJECT_TASK:
case Field::OBJECT_EVENT:
$objectId = $activity->id;
break;
}
if ($objectId) {
/** @var FieldData $data */
$data = $activity->data()->create([
'crm_layout_entity_id' => $entity->id,
'crm_field_id' => $entity->crm_field_id,
'object_type' => $entity->field->object_type,
'object_id' => $objectId,
'value' => $value,
]);
// Never send read-only field data to the CRM.
if ($entity->read_only === false && $entity->is_visible) {
$existingValue = $existingData
->where('crm_layout_entity_id', $entity->id)
->where('crm_field_id', $entity->crm_field_id)
->where('object_type', $entity->field->object_type)
->where('object_id', $objectId)
->first();
// If the field was actually changed, we need to reflect this in the CRM too.
if ($existingValue === null || $existingValue->value !== $value) {
$updatedData[] = $data->id;
}
}
}
}
}
}
return $updatedData;
}
/**
* Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.
*
* @param ServiceInterface $crmService
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array
{
$fieldData = [];
foreach ($entities as $entityId => $value) {
// Only bother with fields that have a value.
if ($value) {
// Extract the entity from the UUID. Check the field is valid and part of the follow-up section.
$entity = $layout->entities()
->uuid($entityId, false)
->whereHas('parent', function ($query) {
$query->where('label', 'follow-up');
})
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->first();
if ($entity) {
// Convert raw data into values that the CRM can consume.
$value = $crmService->normalizeValue($entity->field->type, $value);
// Add the field and value to the payload.
$fieldData += [
$entity->field->crm_provider_id => $value,
];
}
}
}
return $fieldData;
}
/**
* @param Activity $activity
*/
private function validateSummary(Activity $activity): void
{
$team = $activity->user->team;
$crmProvider = $team->crm->provider;
$attributes = [];
$rules = [
'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,
'title' => 'string|max:250',
'prospects' => 'required|array',
'opportunity_id' => new CrmReference($crmProvider),
'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',
'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator
'summary' => 'max:50000',
'nId' => 'exists:notifications,id',
'crm_id' => new CrmReference($crmProvider),
'entities' => 'array',
'is_internal' => 'boolean',
];
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));
// Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.
$entities = $layout->entities()
->where('read_only', 0)
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->whereHas('parent', function ($query) use ($activity) {
if ($activity->isLoggable() === false) {
$query->where('label', '<>', 'follow-up');
}
});
$isInternal = $this->request->input('is_internal', false);
foreach ($entities->get() as $entity) {
$rules += $this->buildFieldValidator($entity, $isInternal);
$attributes += $this->buildFieldMessage($entity);
}
$this->request->validate($rules, [], $attributes);
}
private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array
{
return [
'entities.' . $entity->id_string => $entity->getValidator($isInternal),
];
}
/**
* @param LayoutEntity $entity
*
* @return array
*/
private function buildFieldMessage(LayoutEntity $entity): array
{
$label = $entity->label;
if ($label === null) {
$label = $entity->field->label;
}
return [
'entities.' . $entity->id_string => $label,
];
}
public function search(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->debugLog(
$user,
'User extracted from request',
['user' => $user->getId(), 'tz' => $user->getTimezone()]
);
$searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());
$this->debugLog(
$user,
'ActivitySearch criteria built',
['searchCriteria' => $searchCriteria]
);
$filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);
$this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);
$this->validateSearch($request, $filterSet);
$this->debugLog($user, 'Request validated');
$searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);
/** @var Collection<Activity> $activities */
$activities = $searchResponse['results'];
$this->debugLog($user, 'Activities ES response extracted');
$hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(
$user->getTeamId(),
TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),
);
if ($hideInternalMeetingsSetting?->getValue() === '1') {
$activities = $activities->filter(function (Activity $activity) {
if ($activity->is_internal && empty($activity->actual_start_time)) {
return false;
}
return true;
});
}
$this->debugLog($user, 'Internal meetings (?!) filtered');
$this->response->getManager()
->parseIncludes([
'category',
'organizer.group',
'prospect',
'stage',
'opportunity',
'stats',
'scorecards',
'masterTrack',
'activeParticipants',
'notification',
])
->setSerializer(new JsonSerializer());
$transformerExcludes = $this->request->input('exclude');
if ($transformerExcludes) {
$this->response->getManager()->parseExcludes($transformerExcludes);
}
$this->debugLog($user, 'Response Manager (?!) applied');
$transformer = new ActivityTransformer();
$transformer->setConsumer($user);
$this->debugLog($user, 'Activity Transformer added');
$resource = new \League\Fractal\Resource\Collection($activities, $transformer);
$page = $searchCriteria->getPageNumber();
$this->debugLog($user, 'Search criteria page number called', ['page' => $page]);
$histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');
$this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);
return $this->response->withArray([
'pagination' => [
'total' => $searchResponse['totalHits'],
'current' => $page,
'prev' => max($page - 1, 1),
'next' => $page + 1,
],
'results' => $this->response->getManager()->createData($resource)->toArray(),
'histogram' => $histogram,
]);
}
private function debugLog(User $user, string $logMessage, ?array $context = []): void
{
// Debug for Learning People Only
if ($user->getTeamId() !== 260) {
return;
}
Log::notice(
sprintf('[activity-search-controller] %s', $logMessage),
$context
);
}
/** @throws ValidationException */
private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void
{
$rules = [
'exclude' => 'array',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
];
if ($prefix !== null && mb_strpos($prefix, '.') !== false) {
$rules[rtrim($prefix, '.')] = sprintf(
'required|array|max:%d',
$filterSet->count()
);
}
$validationRules = $filterSet->getValidationRules($prefix)
->merge($rules)
->all();
$request->validate($validationRules);
}
public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$search = $this->updateOrCreateActivitySearch($request);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function updateActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('update', $search);
$this->updateOrCreateActivitySearch($request, $search);
return $this->response->withOk();
}
private function storeNamedSearchFilters(
Collection $request,
Search $search,
FilterDefinitionCollection $filterSet,
?string $prefix = null,
): self {
$arrayTypeProperties = $filterSet
->getPropertyTypes([
FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,
])
->all();
$supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);
foreach ($supportedRequestProperties as $requestPropertyName) {
if (! array_has($request, $requestPropertyName)) {
continue;
}
/** @var string|string[] $propertyValue */
$propertyValue = array_get($request, $requestPropertyName);
$propertyName = $prefix === null
? $requestPropertyName
: mb_substr($requestPropertyName, mb_strlen($prefix));
$isArrayType = array_has($arrayTypeProperties, $propertyName);
if (! $isArrayType) {
/** @var string $requestPropertyValue */
$search->filters()->updateOrCreate(
[
'filter' => $propertyName,
],
[
'value' => $propertyValue,
]
);
continue;
}
/** @var string[] $requestPropertyValue */
/** @var SearchFilter[]|Collection $existingFilterValues */
$existingFilterValuesKeyed = $search->filters()
->where('filter', $propertyName)
->get()
->keyBy('id');
// Iterate over values provided as request parameters
foreach ($propertyValue as $value) {
/** @var SearchFilter|null $valueFilter */
$valueFilter = $search->filters()
->where(
[
'filter' => $propertyName,
'value' => $value,
]
)
->first();
if ($valueFilter !== null) {
// Remove filter value pair from list to be deleted
$existingFilterValuesKeyed->forget($valueFilter->id);
} else {
// Add new filter/value pair
$search->filters()->updateOrCreate([
'filter' => $propertyName,
'value' => $value,
]);
}
}
// Delete filter value pairs for this filter that no longer exist in request parameters
foreach ($existingFilterValuesKeyed as $existingFilter) {
$existingFilter->delete();
}
}
/** @var Collection<int, SearchFilter> $filtersKeyed */
$filtersKeyed = $search->filters()->get()->keyBy('filter');
// wipe removed filters from this search
foreach ($filtersKeyed as $filterName => $filter) {
if (array_has($request, $prefix . $filterName)) {
continue;
}
// Remove all filter values for this filter
$search->filters()->where('filter', $filterName)->delete();
}
return $this;
}
/**
* @throws AuthorizationException
*/
public function fetchActivitySearch(
Search $search,
Request $request,
SearchTransformer $searchTransformer,
): JsonResponse {
$this->authorize('view', $search);
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withCollection(
$user->searches()->get(),
$searchTransformer
->withConsumer($user)
);
}
/**
* Deletes a saved search
*
* @param Request $request
* @param Search $search
*
* @throws Exception
*
* @return JsonResponse
*/
public function deleteActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('delete', $search);
// Orphan any AutomatedReports that use this search
$search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);
// Delete filters and the search itself
$search->filters()->delete();
$search->delete();
return $this->response->withOk();
}
public function live(Request $request, ElasticActivityRepository $repository): JsonResponse
{
$user = $this->getUserFromRequest($request);
$this->request->validate([
'sort_direction' => 'in:asc,desc',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
]);
$activities = $repository->getLiveCoachingEligibleActivities(
user: $user,
lookBackMinutes: self::LOOK_BACK,
limit: (int) $this->request->input('limit', 25),
page: (int) $this->request->input('page', 1),
sortBy: ['actual_start_time', 'scheduled_start_time'],
sortDirection: (string) $this->request->input('sort_direction', 'asc'),
);
$this->response
->getManager()
->parseIncludes(['organizer.group', 'prospect'])
->setSerializer(new JsonSerializer());
return $this->response->withCollection($activities, new ActivityTransformer());
}
/**
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function show(Activity $activity, ActivityService $activityService): JsonResponse
{
$this->authorize('show', $activity);
$user = $activity->getUser();
$team = $user->getTeam();
// Sync the opportunity with the latest data if possible.
if ($activity->opportunity_id) {
try {
$crmService = $this->providerRegistry->get($team->crm->provider);
if (! $user->isCrmRequired()) {
$crmService->setUser($team->getOwner());
} else {
$crmService->setUser($user);
}
$crmService->syncOpportunity($activity->opportunity->crm_provider_id);
} catch (Exception $exception) {
// Move on.
}
}
$activityData = $activityService->getActivityData($this->request->user(), $activity);
return response()->json($activityData);
}
public function createRecording(Activity $activity)
{
$this->authorize('record', $activity);
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Tell Twilio to start recording this activity.
if ($activity->recording_state === Activity::RECORDING_OFF) {
$job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withCreated();
}
return $this->response->errorGone('Activity is already recording.');
}
public function updateRecording(Request $request, Activity $activity)
{
$this->authorize('record', $activity);
$request->validate([
'preference' => 'boolean',
'state' => [
'string',
Rule::in([
Activity::RECORDING_IN_PROGRESS,
Activity::RECORDING_PAUSED,
]),
],
]);
if ($request->has('state')) {
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Toggle the recording state between paused and resumed.
if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {
$job = (new ToggleRecording($activity, $request->input('state')))
->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Recording is not toggleable.');
}
if ($request->has('preference')) {
$activity->update([
'recording_preference' => $request->input('preference') ? 1 : 0,
]);
return $this->response->withOk();
}
return $this->response->errorWrongArgs('Something went wrong');
}
public function stopRecording(Activity $activity)
{
$this->authorize('stopRecord', $activity);
// Tell Twilio to stop recording this activity.
if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {
$job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Activity is not recording.');
}
/**
* Add activity to this user's favorites playlist
*
* @throws AuthorizationException
*/
public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse
{
$this->authorize('favorite', $activity);
$user = $this->getUserFromRequest($this->request);
$favorite = $activity->wasFavoritedBy($user);
$name = $activity->activity_title ?? '';
// It needs to check at least one record.
if (! $favorite) {
$favoritePlaylist = $user->favoritePlaylist();
$playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(
$activity,
$user,
$favoritePlaylist
);
if ($playlistActivity !== null) {
$playlistActivity->update(
// Just update, don't sort.
['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],
);
} else {
$playlistActivity = $activity->playlistActivities()->create([
'playlist_id' => $favoritePlaylist->getId(),
'user_id' => $user->getId(),
'start_time' => 0,
'name' => mb_strimwidth($name, 0, 100),
]);
// Sort it on top.
$playlistActivity->update(
[
'sort' => $playlistActivityRepository->calculateNewSortOrder(
null,
$playlistActivity,
),
],
);
}
$playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);
return new JsonResponse([], JsonResponse::HTTP_CREATED);
}
return new JsonResponse(
[
'error' => [
'code' => AbstractResponse::CODE_CONFLICT,
'http_code' => JsonResponse::HTTP_CONFLICT,
'message' => 'Resource Already Exists',
],
],
JsonResponse::HTTP_CONFLICT,
);
}
/**
* Remove activity from this user's favorites playlist
*
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function unfavorite(Activity $activity)
{
$user = $t...
|
32865
|
NULL
|
NULL
|
NULL
|
|
32870
|
1257
|
0
|
2026-05-13T09:43:20.089686+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665400089_m2.jpg...
|
PhpStorm
|
faVsco.js – ActivityController.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.034242023,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-943456739835505562
|
-8636494053633454656
|
idle
|
hybrid
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
PhostormProiect vVIeWINavicareCodeLaravelKeractorTOOISWindowFV faVsco.js"9 master~(C ActivityController.pnp|aravel.l0gA SF (jiminny@localhost]4 HS_local [jiminny@localhost]& console (PROD] X A console [EU]D Teaminsights, m Themesv D UserAutomatedRep -007final class ActivityController extends Controller implements CommentContextInterfaceA console [STAGING]v Dv2c) ACuviLyvzconuroAskAnythingCorLL0/(C) AskJiminnyRepc© DealsV2Controll 410%(C) OnDemandV2Cc€ PlavlistControlleC) PlavlistSharecorC PlavlistTrackCor111131114(C) UoloadControlleC) [EMAIL]) AiCrmNotesControl(c) Rasecontroller nhn@ ClientTokenControl 1157(e) CrmController.pnp11158© DealLevelPromptsC 115$c) DealRiskcontroller.@ InctantMeetinaCont 116111164C) Languagecontrolle© LayoutManagemen 1163Ca) livoCoodControllor1164 |9© MeetingsController 1192© MessageController. 1193 l >C MotadataControllor L214© MobileSettingsCont 1212 (g >© MomentController.r 125gc) Nudgecontroller.phNumberAllocatorCc 12/e11271OraanizationMembi 1212C) OraanizationRetentC) OraanizationSvnce@ PartnerController.o1276 1g) PlavbackController1133480 PlavlictController pl 1335g ScimController.nhn9) SidekickController , 13379a) SoftnhoneControlle© SsoController.php(e) CnbccrintionGontrae ToamAiAutomationt6) ToamAiContovtCar0 ToamControllor nhr 1343 (@9 >public function ListActivitySearch(Request Srequest, SearchTransformer SsearchTransformer): JsonResponses: 569— 571* Deletes a saved search— 573* @param Request $request* apanam Search $search575* achrows except1or* drecurn Jsonkesponse-57%578579— 586pubLic tunccion deleteActivicysearch kequest srequest, search ssearch: Jsonkesponse.582oubunc tunction uivelrequest srequest, clastcactIvirvkedosirory srepostrory: usonkesponse....* dparam Activitu Sactivitu*Gthrows_AuthorizationExcent.ion589* Greturn mixedpublic function show(Activity Sactivity, ActivityService $activityService): JsonResponse{...}public function createRecordingActivity Sactivity)i...h597593594public function updateRecording(Request Srequest, Activity $activity)1...h~ 596public function stopRecording(Activity Sactivity)(...}* Add activity to this user's favorites playlist_ 601=602* athrows AuthorizationException604public function favorite(Activity Sactivitv. PlavlistActivitvRepository SolavlistActivitvRepositorv): J501605606=607* Remove activitu from this user's favorites plaulisti60S•Goarom Actvatu sactvitu*athrowsAuthorizationExcent.ion* Greturn mixednublic function unfavorite Activitv Sactivitv)-Tx: AutovCONCAT(u.id, CASE WHEN U.id = t.owner_id THEN ' (owner)' ELSE'' END) AS user_id,sa.*t.owner_id FROM social_accounts saNolN usens u on u.id e sa.sociablle i.diJOIN teams t .n<->l: on t.id = u.team_icWHERE u.team_id = 581 and sa.provider = 'salesforce';SELECT * FROM automated_report_results order by id desc;select * from features;select * from team_features where feature_id = 40;select * from teams where id = 556:select * from automated_reports:where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044"pat", "podcast"]SELECT * FROM automated report_ results WHERE uuid to bin( '822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid:select * from automated_report_results order by za desc;SELECT * FROM automated report resultsWHEkE 10 =17141select * from automated report results WHERE report id = 54:select * from opportunities where 1d = 75943494SELE * FROM teams WHERE name LIKE "%Les%': # 711, 692. 16067 - Timinnvintearationdlesmils.comselect * from playbooks where team id = 711: # event 226147SELEd * FROM Davbook catedonies WHERE Dlavbook 10 e 55151SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_typeSELECT * EROM eom fields WHERE 1d = 226147÷SELECT * EROM eom field values WHERE com field 1d = 226147.SELECT * FROM crm_configurations WHERE id = 692;SEISCTCONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '• END) AS user_id,nemailiSa.xt.owner id FROM social accounts saJOIN users u on u.id = sa.sociable idJOIN teams t 1..n<->1: on t.id = u.team_idWHERE U.team id = 711 and sa.provider = 'salesforce':SELECT * FROM crm profiles co JOIN users u 1..n<->1: on u.id = co.user id WHERE u.team_id = 711:select * from leads:select * from calendars:SELECThelsuppont Dally • In Zn 1/m100% S2• Wed 13 May 12:43:19AskJiminnyReportActivityServiceTest v+0 ..So jiminny4041440 X.04 ATrial Owner Role Senoices should only be - Recorder, Recorder & Voice, Analysithis option shouldn't appear when editing an organisationI'II review the current flow for the trial creation and owner role assianment. Let me create a oian and investigate the1) Find Create Team / trial creation logic in backendUnderstand current owner role assianment flowLocate Import Opportunities Sync Period field locationSind frontend Create Team comnonentiReview current role assignment when owner signs inhought for 1sSearched Create TeamlcreateTeam in ~fiiminnvlabolSearched owner.*role|ownerRole in ~/jiminny/appSearched Imoort Opportunities Svnc Periodlimoort "opportunities "svnc in ~/iminnvlaodsearched controller.onp and pertormed 1 otner quenyAnalyzed app/nutp/controttersInought tor isThought for 2s >1/5 tasks done21 Understand current owner role assianment flowSearched class UserinvitationDTO in ~fiminny/appPoad Invitel IcerToTeamAction nhn and 2 other filesCoarchod pol e pecopnepipole analyctipole pecOpnep AND VOICE in cfliminnulonnAsk anvthina (84L)"Code SWF-1.6WN Windsurf Toams 1120-1UTF.8Po 4 spaces...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
32882
|
1256
|
8
|
2026-05-13T09:44:18.235928+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665458235_m1.jpg...
|
PhpStorm
|
faVsco.js – ActivityController.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
SlackFileEditViewGoHistoryWindowHelp•APPDOCKER381D SlackFileEditViewGoHistoryWindowHelp•APPDOCKER381DEV (docker)₴82APP (-zshtests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleterTest.phptests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesProviderTest.phptests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesUploaderTest.phptests/Unit/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeeches?tests/Unit/Component/Transcription/Diarization/Source/MeetingBotSourceTest.phptests/Unit/Contracts/Services/Calendar/CalendarTraitTest.phptests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.phptests/Unit/Jobs/Activity/Import/ImportTwilioVideoSpeechesJobTest.phptests/Unit/Jobs/Activity/Import/IsActivityReadyForProcessingJobTest.phptests/Unit/Jobs/Calendar/SetupCalendarSyncTest.phptests/Unit/Services/Activity/ParticipantsServiceTest.phptests/Unit/Services/Calendar/Command/ImportParticipantsTest.phptests/Unit/Services/Calendar/GoogleCalendarServiceTest.phptests/Unit/Services/Crm/Close/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTest.phptests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTraitMatchActivitiesTest.phytests/Unit/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTraitOpportunitiesTe:tests/Unit/Services/Crm/Pipedrive/ImportOpportunityMatchActivitiesTest.phptests/Unit/Services/Crm/Salesforce/ServiceTest.phptests/Unit/Services/Mail/Office/EmailApiClientTest.phptests/Unit/Services/RecallAI/RecallAIServiceTest.php113 files changed, 4143 insertions(+), 1740 deletions(-)create mode 120000 CLAUDE.mdcreate mode 100644 app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.phpdelete mode 100644 app/Component/ES/ElasticSearchWorkerManager.phpdelete mode 100644 app/Component/ES/Worker/ActivityWorker.phpdelete mode 100644 app/Component/ES/Worker/EntityWorker.phpdelete mode100644 app/Component/ES/Worker/WorkerAmount.phpdelete mode100644 app/Component/ES/Worker/WorkerInterface.phpcreate mode100644 app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.phtcreate mode100644 app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/Assembl:create mode100644 app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNot(create mode 100644 app/Console/Commands/Crm/Backfill0pportunityUserFromAccountCommand.phpdelete mode 100644 app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.phpcreate mode100644 front-end/src/components/shared/modals/EntityPickerModal/__tests__/uscreate mode 100644 tests/Feature/Component/Nudge/Process0rganisationImmediateNudgesJobTe:create mode 100644 tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheck‹delete mode 100644 tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/ActivityWorkerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/EntityWorkerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/WorkerAmountTest.phpcreate mode 100644 tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCr‹create mode 100644 tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.phpLukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ I|HomeDMsActivityFilesLater..•More+ablSupport Daily - in 2 h 16 m100% C8•Wed 13 May 12:44:17-→Describe what you arBluetoothJiminny ...cunoartylau# engineering# general# jiminny-bg# platform-tickets# product_launches#random# releases# sofia-office# support# thank-yous# the_people_of_jimi...° Direct messages& Nikolay Ivanovdo James Graham. Stoyan Tanev. Galya Dimitrova. Steliyan Georgievo Petko KashinskiP. Aneliya Angelovaã. Stefka Stoyanova•. Vasil Vasilev •!Lukas Kovalik y...AppsJira CloudToastNikDevicesLukas's Magic Mouse35% 0Messagessoundcore AeroClipLukas Kмен всеhttps://aboardinLakyLak bose qc35 llM720 TriathlonMagic KeyboardNikolayХм, ДжLukas Kще питMagic KeyboardSoundcore Life Dot 2 NCBluetooth Settings...да мерсиNikolay Ivanov 11:01 AMмдаМОЛЯLukas Kovalik 12:13 PMНики сори, още един въпрос имамкогато ги правеше ти FE ли оправяима vulnerabilities no npmNikolay Ivanov 12:28 PMнетях ги оставямLukas Kovalik 12:29 PMаз погледнах твоя тикет и там друго нямашесамо FEкак стигна до WorkerMessage Nikolay Ivanov...
|
NULL
|
5420711338192692124
|
NULL
|
click
|
ocr
|
NULL
|
SlackFileEditViewGoHistoryWindowHelp•APPDOCKER381D SlackFileEditViewGoHistoryWindowHelp•APPDOCKER381DEV (docker)₴82APP (-zshtests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleterTest.phptests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesProviderTest.phptests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesUploaderTest.phptests/Unit/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeeches?tests/Unit/Component/Transcription/Diarization/Source/MeetingBotSourceTest.phptests/Unit/Contracts/Services/Calendar/CalendarTraitTest.phptests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.phptests/Unit/Jobs/Activity/Import/ImportTwilioVideoSpeechesJobTest.phptests/Unit/Jobs/Activity/Import/IsActivityReadyForProcessingJobTest.phptests/Unit/Jobs/Calendar/SetupCalendarSyncTest.phptests/Unit/Services/Activity/ParticipantsServiceTest.phptests/Unit/Services/Calendar/Command/ImportParticipantsTest.phptests/Unit/Services/Calendar/GoogleCalendarServiceTest.phptests/Unit/Services/Crm/Close/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTest.phptests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTraitMatchActivitiesTest.phytests/Unit/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTraitOpportunitiesTe:tests/Unit/Services/Crm/Pipedrive/ImportOpportunityMatchActivitiesTest.phptests/Unit/Services/Crm/Salesforce/ServiceTest.phptests/Unit/Services/Mail/Office/EmailApiClientTest.phptests/Unit/Services/RecallAI/RecallAIServiceTest.php113 files changed, 4143 insertions(+), 1740 deletions(-)create mode 120000 CLAUDE.mdcreate mode 100644 app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.phpdelete mode 100644 app/Component/ES/ElasticSearchWorkerManager.phpdelete mode 100644 app/Component/ES/Worker/ActivityWorker.phpdelete mode 100644 app/Component/ES/Worker/EntityWorker.phpdelete mode100644 app/Component/ES/Worker/WorkerAmount.phpdelete mode100644 app/Component/ES/Worker/WorkerInterface.phpcreate mode100644 app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.phtcreate mode100644 app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/Assembl:create mode100644 app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNot(create mode 100644 app/Console/Commands/Crm/Backfill0pportunityUserFromAccountCommand.phpdelete mode 100644 app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.phpcreate mode100644 front-end/src/components/shared/modals/EntityPickerModal/__tests__/uscreate mode 100644 tests/Feature/Component/Nudge/Process0rganisationImmediateNudgesJobTe:create mode 100644 tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheck‹delete mode 100644 tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/ActivityWorkerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/EntityWorkerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/WorkerAmountTest.phpcreate mode 100644 tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCr‹create mode 100644 tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.phpLukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ I|HomeDMsActivityFilesLater..•More+ablSupport Daily - in 2 h 16 m100% C8•Wed 13 May 12:44:17-→Describe what you arBluetoothJiminny ...cunoartylau# engineering# general# jiminny-bg# platform-tickets# product_launches#random# releases# sofia-office# support# thank-yous# the_people_of_jimi...° Direct messages& Nikolay Ivanovdo James Graham. Stoyan Tanev. Galya Dimitrova. Steliyan Georgievo Petko KashinskiP. Aneliya Angelovaã. Stefka Stoyanova•. Vasil Vasilev •!Lukas Kovalik y...AppsJira CloudToastNikDevicesLukas's Magic Mouse35% 0Messagessoundcore AeroClipLukas Kмен всеhttps://aboardinLakyLak bose qc35 llM720 TriathlonMagic KeyboardNikolayХм, ДжLukas Kще питMagic KeyboardSoundcore Life Dot 2 NCBluetooth Settings...да мерсиNikolay Ivanov 11:01 AMмдаМОЛЯLukas Kovalik 12:13 PMНики сори, още един въпрос имамкогато ги правеше ти FE ли оправяима vulnerabilities no npmNikolay Ivanov 12:28 PMнетях ги оставямLukas Kovalik 12:29 PMаз погледнах твоя тикет и там друго нямашесамо FEкак стигна до WorkerMessage Nikolay Ivanov...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
32883
|
1257
|
5
|
2026-05-13T09:44:18.245126+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665458245_m2.jpg...
|
PhpStorm
|
faVsco.js – ActivityController.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhostorimProledeyINavicatecodeFV faVsco.js°9 maste PhostorimProledeyINavicatecodeFV faVsco.js°9 master© ActivityController.php>|aravel.l0gA SF (jiminny@localhost]4 HS_local [jiminny@localhost]& console (PROD] X A console [EU]D Teaminsights, m Themes• @ UserAutomatedRep -uo?final class ActivityController extends Controller implements CommentContextInterfaceA console [STAGING]Userautomatedlv Dv2c) ACuviLyvzconuroAskAnythingCorLL0/() AskJiminnyRepc© DealsV2Controll 410%(C) OnDemandV2Cc€ PlavlistControlleC) PlavlistSharecorC PlavlistTrackCor(C) Transcriotionsui111131114(C) UoloadControlleC) [EMAIL]) AiCrmNotesControl(c) Racecontroller nhn@ ClientTokenControl 1157(e) CrmController.pnp11158© DealLevelPromptsC 115$c) DealRiskcontroller.@ InctantMeetinaCont 11611164C) Languagecontrolle© LayoutManagemen 1163Ca) livoCoodControllor1164 |0© MeetingsController 11921193 |U>c Messacecontroller.C) MotadntoControllor L214© MobileSettingsCont 1212 (g >© MomentController.r 125g1256 09>c) Nudgecontroller.phNumberAllocatorCc 12/e11271OraanizationMembi 1212C) OraanizationRetent• OraanizationRolesC 1214C) OraanizationSvnceФ PartnerController.p1276 1@ PhoneNumberGonti 1333g) PlavbackController1133480 PlavlictController pl 1335g ScimController.nhn9) SidekickController , 13379a) SoftnhoneControlle© SsoController.php() CnbccrintionGontrae ToamAiAutamation(e) ToamAiContovtCor0 ToamContrallor nhr 1343 (Q9 >public function ListActivitySearch(Request Srequest, SearchTransformen SsearchTransformer): JsonResponses: 569— 571* Deletes a saved search— 573* @param Request $request* apanam Search $search575* achrows except1or* drecurn Jsonkesponse578579— 580pubLic tunccion deleteActivicysearch kequest srequest, search ssearch: Jsonkesponse.582oubunc tunction uivelrequest srequest, clastcactIvirvkedosirory srepostrory: usonkesponse....* dparam Activitu Sactivitu*Gthrows_AuthorizationExcent.zon589* Greturn mixedpublic function show(Activity Sactivity, ActivityService $activityService): JsonResponse{...}public function createRecording(Activity Sactivity)1...h597593594public function updateRecording(Request Srequest, Activity $activity)i...h~ 596public function stopRecording(Activity Sactivity)(...}60€* Add activity to this user's favorites playlist_ 601=602* athrows AuthorizationException604public function favorite(Activity Sactivitv. PlavlistActivitvRepository SolavlistActivitvRepositorv): J501605606=607* Remove activitu from this user's favorites plaulist60S•Goarom Actvatu sactvitu*athrowsAuthorizationExcent.ionnublic function unfavorite Activity Sactivitv ?Tx: AutovCONCAT(u.id, CASE WHEN U.id = t.owner_id THEN ' (owner)' ELSE"' END) AS user_id,sa.*t.owner_id FROM social_accounts saNolN usens u on u.id e sa.sociable idJOIN teams t .n<->l: on t.id = u.team_icWHERE u.team_id = 581 and sa.provider = 'salesforce';SELECT * FROM automated_report_results order by id desc;select * from features;select * from team_features where feature_id = 40;select * from teams where id = 556:select * from automated_reports:where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044"pat", "podcast"]SELECT * FROM automated report results WHERE uuid to bin( '822fa41b-afd3-43a9-a248-86b0e36f3131') = vuid:select * from automated_report_results order by za desc;SELECT * FROM automated report resultsWHEKE 10 =144select * from automated report results WHERE report id = 54:select * from opportunities where 1d = 7594349÷SELE * FROM teams WHERE name LIKE "%Les%': # 711, 692. 16067 - Timinnvintearationdlesmils.comselect * from playbooks where team id = 711: # event 226147SELEd * FROM Davbook catedonies WHERE DLavbook 10 = 55151SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_typeSELECT * EROM eom fields WHERE 1d = 226147÷SELECT * EROM eom field values WHERE com field 1d = 226147.SELECT * FROM crm_configurations WHERE id = 692;SEISCTCONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE "' END) AS user_id,nemailiSa.xt.owner id FROM social accounts saJOIN users u on u.id = sa.sociable idJOIN teams t 1.n<->1: on t.id = u.team_idWHERE U.team id = 711 and sa.provider = 'salesforce':SELECT * FROM crm profiles co JOIN users u 1..n<->1: on u.id = co.user id WHERE u.team_id = 711:select * from leads:select * from calendars:SELECTSo jiminny40 41 440 X.04>0 llsuppont Dally • In Zn 10h100% 52• Wed 13 May 12:44:17CascadeTrial Owner Role Selec+0 ..kead kegistercontroller.pnp and OnboardController.pnpSearched UserRegistered invitation. accept in ~/iminnyappThought for 3s ›Read UpdateProtile.phg0// tasks done ?7 Document findinas and provide imolementation olanInoughttor 4s7 7 tasks done)Ihought for 4SCurrent Flow Analvsis: Owner Role Assianment in Trial CreationBackend Flow1. Team Creation Entrv Point• TeamController::store() (lines 24-45)Calls CreateTeam interaction to create the team• Calls InviteUserToTeamAction with UserInvitationDTO: : for0wner(Srequest, Steam)2. Owner Role Assianment (HARDCODED)• UserInvitationDTO:: for0wner() (lines 52-72 in/app/DTO/Invitation/UserInvitationDT0.php)•Lines 54-57: This is where the owner's role is hardcodediohrUser:: ROLE RECORDER,→>oluck("id'→>toArravor•Alwavs assians ROLE ADMIN + ROLE RECORDER to the ownenThic ic the koy ioention that noode modification3. Invitation Creatior•InviteUserToTeamAction::execute@ (lines 28-81)• Creates an Invitation with roles from the DTO (line 45: Sinvitation->roles()->sync(Sdto->roleIds))• Sends OwnerInvitedToTrial notificationl1 Owner Sian-in FlowOwner receives email invitation• Regrstercontroller:: showRegnstratonformo shows registration form with invitation dataOwner redisters and accents invitationRoles are already assigned via the invitation, so owner gets ROLE ADMIN + ROLE RECORDER automaticallvFrontend FlowAsk anvthina (84-D)« Code SWF-1.6O0 1Po. 4 space...
|
NULL
|
-3392663941957884711
|
NULL
|
click
|
ocr
|
NULL
|
PhostorimProledeyINavicatecodeFV faVsco.js°9 maste PhostorimProledeyINavicatecodeFV faVsco.js°9 master© ActivityController.php>|aravel.l0gA SF (jiminny@localhost]4 HS_local [jiminny@localhost]& console (PROD] X A console [EU]D Teaminsights, m Themes• @ UserAutomatedRep -uo?final class ActivityController extends Controller implements CommentContextInterfaceA console [STAGING]Userautomatedlv Dv2c) ACuviLyvzconuroAskAnythingCorLL0/() AskJiminnyRepc© DealsV2Controll 410%(C) OnDemandV2Cc€ PlavlistControlleC) PlavlistSharecorC PlavlistTrackCor(C) Transcriotionsui111131114(C) UoloadControlleC) [EMAIL]) AiCrmNotesControl(c) Racecontroller nhn@ ClientTokenControl 1157(e) CrmController.pnp11158© DealLevelPromptsC 115$c) DealRiskcontroller.@ InctantMeetinaCont 11611164C) Languagecontrolle© LayoutManagemen 1163Ca) livoCoodControllor1164 |0© MeetingsController 11921193 |U>c Messacecontroller.C) MotadntoControllor L214© MobileSettingsCont 1212 (g >© MomentController.r 125g1256 09>c) Nudgecontroller.phNumberAllocatorCc 12/e11271OraanizationMembi 1212C) OraanizationRetent• OraanizationRolesC 1214C) OraanizationSvnceФ PartnerController.p1276 1@ PhoneNumberGonti 1333g) PlavbackController1133480 PlavlictController pl 1335g ScimController.nhn9) SidekickController , 13379a) SoftnhoneControlle© SsoController.php() CnbccrintionGontrae ToamAiAutamation(e) ToamAiContovtCor0 ToamContrallor nhr 1343 (Q9 >public function ListActivitySearch(Request Srequest, SearchTransformen SsearchTransformer): JsonResponses: 569— 571* Deletes a saved search— 573* @param Request $request* apanam Search $search575* achrows except1or* drecurn Jsonkesponse578579— 580pubLic tunccion deleteActivicysearch kequest srequest, search ssearch: Jsonkesponse.582oubunc tunction uivelrequest srequest, clastcactIvirvkedosirory srepostrory: usonkesponse....* dparam Activitu Sactivitu*Gthrows_AuthorizationExcent.zon589* Greturn mixedpublic function show(Activity Sactivity, ActivityService $activityService): JsonResponse{...}public function createRecording(Activity Sactivity)1...h597593594public function updateRecording(Request Srequest, Activity $activity)i...h~ 596public function stopRecording(Activity Sactivity)(...}60€* Add activity to this user's favorites playlist_ 601=602* athrows AuthorizationException604public function favorite(Activity Sactivitv. PlavlistActivitvRepository SolavlistActivitvRepositorv): J501605606=607* Remove activitu from this user's favorites plaulist60S•Goarom Actvatu sactvitu*athrowsAuthorizationExcent.ionnublic function unfavorite Activity Sactivitv ?Tx: AutovCONCAT(u.id, CASE WHEN U.id = t.owner_id THEN ' (owner)' ELSE"' END) AS user_id,sa.*t.owner_id FROM social_accounts saNolN usens u on u.id e sa.sociable idJOIN teams t .n<->l: on t.id = u.team_icWHERE u.team_id = 581 and sa.provider = 'salesforce';SELECT * FROM automated_report_results order by id desc;select * from features;select * from team_features where feature_id = 40;select * from teams where id = 556:select * from automated_reports:where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044"pat", "podcast"]SELECT * FROM automated report results WHERE uuid to bin( '822fa41b-afd3-43a9-a248-86b0e36f3131') = vuid:select * from automated_report_results order by za desc;SELECT * FROM automated report resultsWHEKE 10 =144select * from automated report results WHERE report id = 54:select * from opportunities where 1d = 7594349÷SELE * FROM teams WHERE name LIKE "%Les%': # 711, 692. 16067 - Timinnvintearationdlesmils.comselect * from playbooks where team id = 711: # event 226147SELEd * FROM Davbook catedonies WHERE DLavbook 10 = 55151SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_typeSELECT * EROM eom fields WHERE 1d = 226147÷SELECT * EROM eom field values WHERE com field 1d = 226147.SELECT * FROM crm_configurations WHERE id = 692;SEISCTCONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE "' END) AS user_id,nemailiSa.xt.owner id FROM social accounts saJOIN users u on u.id = sa.sociable idJOIN teams t 1.n<->1: on t.id = u.team_idWHERE U.team id = 711 and sa.provider = 'salesforce':SELECT * FROM crm profiles co JOIN users u 1..n<->1: on u.id = co.user id WHERE u.team_id = 711:select * from leads:select * from calendars:SELECTSo jiminny40 41 440 X.04>0 llsuppont Dally • In Zn 10h100% 52• Wed 13 May 12:44:17CascadeTrial Owner Role Selec+0 ..kead kegistercontroller.pnp and OnboardController.pnpSearched UserRegistered invitation. accept in ~/iminnyappThought for 3s ›Read UpdateProtile.phg0// tasks done ?7 Document findinas and provide imolementation olanInoughttor 4s7 7 tasks done)Ihought for 4SCurrent Flow Analvsis: Owner Role Assianment in Trial CreationBackend Flow1. Team Creation Entrv Point• TeamController::store() (lines 24-45)Calls CreateTeam interaction to create the team• Calls InviteUserToTeamAction with UserInvitationDTO: : for0wner(Srequest, Steam)2. Owner Role Assianment (HARDCODED)• UserInvitationDTO:: for0wner() (lines 52-72 in/app/DTO/Invitation/UserInvitationDT0.php)•Lines 54-57: This is where the owner's role is hardcodediohrUser:: ROLE RECORDER,→>oluck("id'→>toArravor•Alwavs assians ROLE ADMIN + ROLE RECORDER to the ownenThic ic the koy ioention that noode modification3. Invitation Creatior•InviteUserToTeamAction::execute@ (lines 28-81)• Creates an Invitation with roles from the DTO (line 45: Sinvitation->roles()->sync(Sdto->roleIds))• Sends OwnerInvitedToTrial notificationl1 Owner Sian-in FlowOwner receives email invitation• Regrstercontroller:: showRegnstratonformo shows registration form with invitation dataOwner redisters and accents invitationRoles are already assigned via the invitation, so owner gets ROLE ADMIN + ROLE RECORDER automaticallvFrontend FlowAsk anvthina (84-D)« Code SWF-1.6O0 1Po. 4 space...
|
32881
|
NULL
|
NULL
|
NULL
|
|
32884
|
1257
|
6
|
2026-05-13T09:44:22.195088+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665462195_m2.jpg...
|
PhpStorm
|
faVsco.js – TeamController.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
3
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\Settings\Teams;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
use Jiminny\Actions\InviteUserToTeamAction;
use Jiminny\Interactions\Settings\Teams\CreateTeam;
use Jiminny\DTO\Invitation\UserInvitationDTO;
use Jiminny\Http\Requests\Settings\Teams\CreateTeamRequest;
use Jiminny\Http\Controllers\Controller;
use Jiminny\Http\Requests\Settings\Teams\EditTeamRequest;
use Jiminny\Interactions\Settings\Teams\EditTeam;
use Jiminny\Models\Team;
use Jiminny\Models\User;
final class TeamController extends Controller
{
/**
* Create a new team, subscription and invitation.
*/
public function store(
CreateTeamRequest $request,
CreateTeam $createTeam,
InviteUserToTeamAction $inviteUserToTeamAction,
): void {
/** @var User $teamCreator */
$teamCreator = $request->user();
try {
$data = $request->all();
$team = $createTeam->handle($teamCreator, $data, $request->getDomain());
$inviteUserToTeamAction->execute(UserInvitationDTO::forOwner($request, $team));
} catch (\Exception $exception) {
Log::error('An error occurred while creating team', [
'e_message' => $exception->getMessage(),
'e_code' => $exception->getCode(),
]);
throw $exception;
}
}
public function edit(
Team $team,
EditTeamRequest $request,
EditTeam $editTeam,
): JsonResponse {
/** @var User $teamEditor */
$teamEditor = $request->user();
$editTeam->handle($team, $teamEditor, $request->all(), $request);
return response()->json([], JsonResponse::HTTP_OK);
}
}
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
40
1
40
64
Previous Highlighted Error
Next Highlighted Error
SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993
SELECT * FROM users WHERE id = 25061;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 994;
SELECT * FROM crm_profiles WHERE user_id = 25061;
select * from crm_configurations where id = 834;
SELECT * FROM teams WHERE id = 882;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;
SELECT * FROM contacts where crm_configuration_id = 834;
SELECT * FROM opportunities WHERE team_id = 933
# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');
AND id IN (8482561,18352941,19042734,19232139,19445140,19472541);
SELECT * FROM opportunity_contacts
WHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 485; #
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
select crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id
where crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')
# and l.converted_at IS NOT NULL
;
# [PASSWORD_DOTS]
SELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')
and opportunity_id IS NULL
order by id desc;
SELECT * FROM teams WHERE id = 604; # 598
SELECT * FROM activities WHERE id = 74410828; # [EMAIL]
SELECT * FROM accounts WHERE id = 20068382;
SELECT * FROM accounts WHERE id = 35186038;
SELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 559 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;
select * from sidekick_settings where team_id = 781;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100
SELECT * FROM crm_layouts WHERE crm_configuration_id = 711;
SELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL
and is_internal = 0 and status = 'completed'
order by id desc;
SELECT * FROM crm_layout_entities
WHERE crm_layout_id IN (2352, 2353);
;
SELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 556 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;
SELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;
select * from contacts
where crm_configuration_id = 530
and crm_provider_id = 872252;
select * from activities where crm_configuration_id = 530
and user_id = 14343 and type like '%softphone%'
and created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);
SELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t
JOIN crm_configurations c ON t.id = c.team_id
WHERE t.status = 'active';
SELECT * FROM teams where id = 1091;
SELECT * FROM crm_configurations where team_id = 1091;
SELECT * FROM activity_providers where team_id = 1091;
SELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT * FROM teams WHERE name LIKE '%Leadventure%';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1091 and sa.provider = 'salesforce';
SELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812
SELECT * FROM teams where id = 862;
SELECT * FROM crm_configurations where team_id = 862;
SELECT * FROM activity_providers where team_id = 862;
SELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT t.id, crm.id, crm.provider, ap.* FROM teams t
join crm_configurations crm on t.id = crm.team_id
join activity_providers ap on t.id = ap.team_id
where t.status = 'active' and ap.is_enabled = 1
and crm.provider = 'hubspot'
and ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',
'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');
SELECT * FROM teams where id = 1068;
SELECT * FROM crm_configurations where team_id = 1068;
SELECT * FROM activity_providers where team_id = 1068;
SELECT * FROM activities a
where crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')
and a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'
)
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by a.id desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1068 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262
SELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
select * from crm_layouts where crm_configuration_id = 834;
select * from crm_layout_entities where crm_layout_id = 2780;
select * from crm_fields where id IN (321153,321192,321193,321194);
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1057 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8
SELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20
SELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10
SELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #
SELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;
select * from users where team_id = 51; # 7783
SELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130
select * from activity_searches where user_id = 7783;
select * from activity_search_filters where activity_search_id IN (32291, 32292);
SELECT asf.activity_search_id, asf.id, asf.value
FROM activity_search_filters asf
WHERE asf.filter = 'group_id'
AND asf.value IN (
SELECT CONCAT(
HEX(SUBSTR(uuid, 5, 4)), '-',
HEX(SUBSTR(uuid, 3, 2)), '-',
HEX(SUBSTR(uuid, 1, 2)), '-',
HEX(SUBSTR(uuid, 9, 2)), '-',
HEX(SUBSTR(uuid, 11))
)
FROM groups
WHERE deleted_at IS NOT NULL
);
SELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where provider = 'hubspot';
SELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133
SELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null
# [PASSWORD_DOTS]
select * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';
select
cp.*
# DISTINCT t.id
# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields
FROM crm_profiles cp
JOIN crm_configurations crm on crm.id = cp.crm_configuration_id
JOIN users u on u.id = cp.user_id
JOIN teams t ON t.id = crm.team_id
WHERE crm.provider = 'salesforce' and t.status = 'active'
and cp.archived_at IS NULL and u.deleted_at IS NULL
and t.id NOT IN (1093)
and t.id = 2
and cp.contact_fields IS NULL;
# and c.crm_provider_id = '003Uu00000ojD4NIAU';
SELECT * FROM users WHERE id = 26484;
SELECT * FROM crm_profiles WHERE user_id = 26484;
SELECT * FROM social_accounts WHERE sociable_id = 26484;
SELECT * FROM crm_configurations where provider = 'salesforce';
select * from users where id IN (10022, 10403);
select * from users where team_id IN (526);
select * from teams where id IN (526, 532);
select * from crm_configurations where id IN (500, 516);
select * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);
select * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 526 and sa.provider = 'salesforce';
select * from team_settings where team_id IN (526, 532);
select * from users where id IN (22824);
select * from crm_profiles where crm_configuration_id IN (1026);
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1093 and sa.provider = 'salesforce';
select * from teams where id = 1099;
select * from users where id = 29643
select * from activity_processing_states;
SELECT * FROM teams where name LIKE '%Fare%'; # 233
SELECT * FROM opportunities where crm_configuration_id = 215
# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'
;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1088 and sa.provider = 'hubspot';
SELECT * FROM teams order by updated_at DESC
SELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account
select * from crm_configurations where provider = 'pipedrive';
select * from teams where id = 957;
select * from crm_configurations where id = 957;
SELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743
SELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;
select * from users where team_id = 1; # 26726 - Gabriela Dureva
SELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific
select * from activities where user_id = 26726 order by id desc;
select * from contacts where crm_configuration_id = 1
and email IN ('[EMAIL]', '[EMAIL]'); # 2094416, 2093620
SELECT * FROM contacts WHERE id = 6284931;
SELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id
WHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;
select * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);
select * from crm_configurations where id = 1;
43801692-1aeb-32ce-acba-5b80a479701a
44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b
405975c0-b3d0-7aaa-821f-09d59cae6dd1
4caf848d-4bed-2299-b248-7788d41f9fca
49bedc3f-f196-eef3-89c3-dea6a3b4aa63
43420989-a09d-b8f8-9806-c8bbf7a02aac
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
SELECT * FROM activities WHERE id = 75461988;
SELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;
select * from contacts where id = 17900517;
select * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id
where crm.provider != 'salesforce';
select * from users where id = 21047;
SELECT * FROM crm_configurations WHERE id = 892;
SELECT * FROM teams WHERE id = 942;
select * from opportunities where team_id = 942 order by updated_at desc;
select * from contacts where team_id = 942 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 942 and sa.provider = 'hubspot';
SELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430
SELECT * FROM crm_configurations WHERE id = 1;
SELECT * FROM teams WHERE crm_id = 1;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
select id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1
SELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430
select * from teams where id = 852;
select * from groups where id = 2286;
select * from sidekick_settings where team_id = 852;
select * from default_activity_types where team_id = 852;
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1 AND u.deleted_at IS NULL
AND u.crm_required = 1
AND u.team_id = 1
ORDER BY u.team_id;
SELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (
18481
);
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1
AND u.deleted_at IS NULL
AND u.crm_required = 1
# AND u.team_id = 1
AND p.id IS NULL -- Move this condition to WHERE clause
ORDER BY u.team_id;
SELECT * FROM opportunities WHERE id = 20002609;
select * from teams where id = 1122; # Velatir, 29953 - [EMAIL]
select * from crm_configurations where id = 1060;
select * from crm_layouts where crm_configuration_id = 1060;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1122 and sa.provider = 'hubspot';
select * from opportunities where team_id = 1122 order by updated_at desc;
select * from crm_field_data where object_type = 'contact';
SELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 248 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS
SELECT * FROM users where id = 24115;
SELECT * FROM accounts where id = 4002896;
SELECT * FROM teams WHERE name LIKE '%adswerve%';
SELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN ("0069N000003GIQ9QAO","0061r000019yGP9AAM","0066900001S2KWlAAN","0066900001TDpj2AAD","0066900001b8uEwAAI","0069N000001rQi0QAE","006QF00000KD40mYAD","006QF00000LzpRJYAZ","0069N000002uomtQAA","0069N000002xlMLQAY","0066900001NV6ubAAD","0061r00001HJp45AAD","006QF00000uTlUoYAK","006QF00000v0bZqYAI");
SELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203
SELECT u.id, u.email, ac.name, a.* FROM activities a
JOIN users u ON a.user_id = u.id
JOIN accounts ac ON a.account_id = ac.id
WHERE
uuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or
uuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or
uuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;
select * from users where id = 5825;
SELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;
select * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;
19594, 862
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 862 and sa.provider = 'salesforce';
select * from automated_reports where id = 36;
select ar.frequency, r.*, ar.* from automated_report_results r
join automated_reports ar on r.report_id = ar.id
where ar.frequency != 'one_off';
select s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;
select * from nudges n where n.activity_search_id
select * from teams where created_at > '2026-03-09';
SELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;
select * from users where team_id = 1 and name like '%Lukas%'; # 7160
SELECT * FROM teams WHERE id = 575;
select * from opportunities where team_id = 575;
SELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,
select * from opportunities where team_id = 1126;
SELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,
select * from opportunities where team_id = 1125;
select * from contacts c
where c.team_id = 882;
SELECT * FROM activities WHERE id = 76822967;
SELECT * FROM crm_profiles WHERE user_id = 15440;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 555;
SELECT * FROM crm_configurations WHERE id = 555;
SELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 581 and sa.provider = 'salesforce';
SELECT * FROM automated_report_results order by id desc;
select * from features;
select * from team_features where feature_id = 40;
select * from teams where id = 556;
select * from automated_reports;
where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , ["pdf","podcast"]
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
select * from automated_report_results order by id desc;
SELECT * FROM automated_report_results WHERE id = 1919;
select * from automated_report_results WHERE report_id = 54;
select * from opportunities where id = 7594349;
SELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - [EMAIL]
select * from playbooks where team_id = 711; # event 226147
SELECT * FROM playbook_categories WHERE playbook_id = 5515;
SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';
SELECT * FROM crm_fields WHERE id = 226147;
SELECT * FROM crm_field_values WHERE crm_field_id = 226147;
SELECT * FROM crm_configurations WHERE id = 692;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 711 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;
select * from leads;
select * from calendars;
SELECT
t.id AS team_id,
t.name,
LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain
FROM teams t
JOIN users u ON u.team_id = t.id
JOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'
LEFT JOIN team_domains td
ON td.team_id = t.id
AND td.deleted_at IS NULL
AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))
GROUP BY t.id, t.name, calendar_domain
ORDER BY t.name, calendar_domain;
select * from users u join calendars c on c.user_id = u.id
where u.team_id = 882;
select * from activities where id = 74049485; # team 563 crm 537
select * from activities where id = 73272382; # team 563 crm 537
select * from activities where id = 64400389; # team 563 crm 537
select * from activities where id = 58081273; # team 563 crm 537
select * from activities where id = 54520297; # team 563 crm 537
select * from participants where activity_id = 58081273;
select * from activities where crm_configuration_id = 537 and provider = 'aircall'
and account_id = 19003658 order by updated_at desc;
select * from contacts where crm_configuration_id = 537 and id = 35957759;
select * from accounts where crm_configuration_id = 537 and id = 19003658;
select * from automated_report_results where id = 1976;
select * from automated_reports where id = 583;
select * from activity_searches where id = 87714;
select * from activity_search_filters where activity_search_id = 87714;
SELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid
or uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;
SELECT * FROM crm_configurations WHERE provider = 'hubspot';
select * from rate_limits;
select * from automated_report_results where media_type = 'pdf' and status = 2
and id IN (18, 1872);
select * from automated_reports where id = 54;
SELECT * FROM users WHERE id IN (24623,29443,29613);
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.034242023,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"3","depth":4,"bounds":{"left":0.38397607,"top":0.07581804,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.39361703,"top":0.074221864,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.40093085,"top":0.074221864,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Http\\Controllers\\Settings\\Teams;\n\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Actions\\InviteUserToTeamAction;\nuse Jiminny\\Interactions\\Settings\\Teams\\CreateTeam;\nuse Jiminny\\DTO\\Invitation\\UserInvitationDTO;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\CreateTeamRequest;\nuse Jiminny\\Http\\Controllers\\Controller;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\EditTeamRequest;\nuse Jiminny\\Interactions\\Settings\\Teams\\EditTeam;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\n\nfinal class TeamController extends Controller\n{\n /**\n * Create a new team, subscription and invitation.\n */\n public function store(\n CreateTeamRequest $request,\n CreateTeam $createTeam,\n InviteUserToTeamAction $inviteUserToTeamAction,\n ): void {\n /** @var User $teamCreator */\n $teamCreator = $request->user();\n\n try {\n $data = $request->all();\n $team = $createTeam->handle($teamCreator, $data, $request->getDomain());\n\n $inviteUserToTeamAction->execute(UserInvitationDTO::forOwner($request, $team));\n } catch (\\Exception $exception) {\n Log::error('An error occurred while creating team', [\n 'e_message' => $exception->getMessage(),\n 'e_code' => $exception->getCode(),\n ]);\n\n throw $exception;\n }\n }\n\n public function edit(\n Team $team,\n EditTeamRequest $request,\n EditTeam $editTeam,\n ): JsonResponse {\n /** @var User $teamEditor */\n $teamEditor = $request->user();\n $editTeam->handle($team, $teamEditor, $request->all(), $request);\n\n return response()->json([], JsonResponse::HTTP_OK);\n }\n}","depth":4,"bounds":{"left":0.11968085,"top":0.0726257,"width":0.28823137,"height":0.9066241},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Http\\Controllers\\Settings\\Teams;\n\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Actions\\InviteUserToTeamAction;\nuse Jiminny\\Interactions\\Settings\\Teams\\CreateTeam;\nuse Jiminny\\DTO\\Invitation\\UserInvitationDTO;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\CreateTeamRequest;\nuse Jiminny\\Http\\Controllers\\Controller;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\EditTeamRequest;\nuse Jiminny\\Interactions\\Settings\\Teams\\EditTeam;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\n\nfinal class TeamController extends Controller\n{\n /**\n * Create a new team, subscription and invitation.\n */\n public function store(\n CreateTeamRequest $request,\n CreateTeam $createTeam,\n InviteUserToTeamAction $inviteUserToTeamAction,\n ): void {\n /** @var User $teamCreator */\n $teamCreator = $request->user();\n\n try {\n $data = $request->all();\n $team = $createTeam->handle($teamCreator, $data, $request->getDomain());\n\n $inviteUserToTeamAction->execute(UserInvitationDTO::forOwner($request, $team));\n } catch (\\Exception $exception) {\n Log::error('An error occurred while creating team', [\n 'e_message' => $exception->getMessage(),\n 'e_code' => $exception->getCode(),\n ]);\n\n throw $exception;\n }\n }\n\n public function edit(\n Team $team,\n EditTeamRequest $request,\n EditTeam $editTeam,\n ): JsonResponse {\n /** @var User $teamEditor */\n $teamEditor = $request->user();\n $editTeam->handle($team, $teamEditor, $request->all(), $request);\n\n return response()->json([], JsonResponse::HTTP_OK);\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.40957448,"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.41821808,"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.42918882,"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.43783244,"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.44647607,"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.4574468,"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.46841756,"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.4950133,"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.50598407,"top":0.09896249,"width":0.029587766,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"bounds":{"left":0.7084442,"top":0.09896249,"width":0.02825798,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"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":"40","depth":4,"bounds":{"left":0.67785907,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.69015956,"top":0.123703115,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"40","depth":4,"bounds":{"left":0.6994681,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"64","depth":4,"bounds":{"left":0.7117686,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.7237367,"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.73105055,"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 * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","depth":4,"on_screen":true,"value":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
5037790698670708153
|
1065678670634825285
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
3
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\Settings\Teams;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
use Jiminny\Actions\InviteUserToTeamAction;
use Jiminny\Interactions\Settings\Teams\CreateTeam;
use Jiminny\DTO\Invitation\UserInvitationDTO;
use Jiminny\Http\Requests\Settings\Teams\CreateTeamRequest;
use Jiminny\Http\Controllers\Controller;
use Jiminny\Http\Requests\Settings\Teams\EditTeamRequest;
use Jiminny\Interactions\Settings\Teams\EditTeam;
use Jiminny\Models\Team;
use Jiminny\Models\User;
final class TeamController extends Controller
{
/**
* Create a new team, subscription and invitation.
*/
public function store(
CreateTeamRequest $request,
CreateTeam $createTeam,
InviteUserToTeamAction $inviteUserToTeamAction,
): void {
/** @var User $teamCreator */
$teamCreator = $request->user();
try {
$data = $request->all();
$team = $createTeam->handle($teamCreator, $data, $request->getDomain());
$inviteUserToTeamAction->execute(UserInvitationDTO::forOwner($request, $team));
} catch (\Exception $exception) {
Log::error('An error occurred while creating team', [
'e_message' => $exception->getMessage(),
'e_code' => $exception->getCode(),
]);
throw $exception;
}
}
public function edit(
Team $team,
EditTeamRequest $request,
EditTeam $editTeam,
): JsonResponse {
/** @var User $teamEditor */
$teamEditor = $request->user();
$editTeam->handle($team, $teamEditor, $request->all(), $request);
return response()->json([], JsonResponse::HTTP_OK);
}
}
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
40
1
40
64
Previous Highlighted Error
Next Highlighted Error
SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993
SELECT * FROM users WHERE id = 25061;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 994;
SELECT * FROM crm_profiles WHERE user_id = 25061;
select * from crm_configurations where id = 834;
SELECT * FROM teams WHERE id = 882;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;
SELECT * FROM contacts where crm_configuration_id = 834;
SELECT * FROM opportunities WHERE team_id = 933
# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');
AND id IN (8482561,18352941,19042734,19232139,19445140,19472541);
SELECT * FROM opportunity_contacts
WHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 485; #
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
select crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id
where crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')
# and l.converted_at IS NOT NULL
;
# [PASSWORD_DOTS]
SELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')
and opportunity_id IS NULL
order by id desc;
SELECT * FROM teams WHERE id = 604; # 598
SELECT * FROM activities WHERE id = 74410828; # [EMAIL]
SELECT * FROM accounts WHERE id = 20068382;
SELECT * FROM accounts WHERE id = 35186038;
SELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 559 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;
select * from sidekick_settings where team_id = 781;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100
SELECT * FROM crm_layouts WHERE crm_configuration_id = 711;
SELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL
and is_internal = 0 and status = 'completed'
order by id desc;
SELECT * FROM crm_layout_entities
WHERE crm_layout_id IN (2352, 2353);
;
SELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 556 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;
SELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;
select * from contacts
where crm_configuration_id = 530
and crm_provider_id = 872252;
select * from activities where crm_configuration_id = 530
and user_id = 14343 and type like '%softphone%'
and created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);
SELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t
JOIN crm_configurations c ON t.id = c.team_id
WHERE t.status = 'active';
SELECT * FROM teams where id = 1091;
SELECT * FROM crm_configurations where team_id = 1091;
SELECT * FROM activity_providers where team_id = 1091;
SELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT * FROM teams WHERE name LIKE '%Leadventure%';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1091 and sa.provider = 'salesforce';
SELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812
SELECT * FROM teams where id = 862;
SELECT * FROM crm_configurations where team_id = 862;
SELECT * FROM activity_providers where team_id = 862;
SELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT t.id, crm.id, crm.provider, ap.* FROM teams t
join crm_configurations crm on t.id = crm.team_id
join activity_providers ap on t.id = ap.team_id
where t.status = 'active' and ap.is_enabled = 1
and crm.provider = 'hubspot'
and ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',
'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');
SELECT * FROM teams where id = 1068;
SELECT * FROM crm_configurations where team_id = 1068;
SELECT * FROM activity_providers where team_id = 1068;
SELECT * FROM activities a
where crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')
and a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'
)
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by a.id desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1068 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262
SELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
select * from crm_layouts where crm_configuration_id = 834;
select * from crm_layout_entities where crm_layout_id = 2780;
select * from crm_fields where id IN (321153,321192,321193,321194);
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1057 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8
SELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20
SELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10
SELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #
SELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;
select * from users where team_id = 51; # 7783
SELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130
select * from activity_searches where user_id = 7783;
select * from activity_search_filters where activity_search_id IN (32291, 32292);
SELECT asf.activity_search_id, asf.id, asf.value
FROM activity_search_filters asf
WHERE asf.filter = 'group_id'
AND asf.value IN (
SELECT CONCAT(
HEX(SUBSTR(uuid, 5, 4)), '-',
HEX(SUBSTR(uuid, 3, 2)), '-',
HEX(SUBSTR(uuid, 1, 2)), '-',
HEX(SUBSTR(uuid, 9, 2)), '-',
HEX(SUBSTR(uuid, 11))
)
FROM groups
WHERE deleted_at IS NOT NULL
);
SELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where provider = 'hubspot';
SELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133
SELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null
# [PASSWORD_DOTS]
select * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';
select
cp.*
# DISTINCT t.id
# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields
FROM crm_profiles cp
JOIN crm_configurations crm on crm.id = cp.crm_configuration_id
JOIN users u on u.id = cp.user_id
JOIN teams t ON t.id = crm.team_id
WHERE crm.provider = 'salesforce' and t.status = 'active'
and cp.archived_at IS NULL and u.deleted_at IS NULL
and t.id NOT IN (1093)
and t.id = 2
and cp.contact_fields IS NULL;
# and c.crm_provider_id = '003Uu00000ojD4NIAU';
SELECT * FROM users WHERE id = 26484;
SELECT * FROM crm_profiles WHERE user_id = 26484;
SELECT * FROM social_accounts WHERE sociable_id = 26484;
SELECT * FROM crm_configurations where provider = 'salesforce';
select * from users where id IN (10022, 10403);
select * from users where team_id IN (526);
select * from teams where id IN (526, 532);
select * from crm_configurations where id IN (500, 516);
select * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);
select * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 526 and sa.provider = 'salesforce';
select * from team_settings where team_id IN (526, 532);
select * from users where id IN (22824);
select * from crm_profiles where crm_configuration_id IN (1026);
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1093 and sa.provider = 'salesforce';
select * from teams where id = 1099;
select * from users where id = 29643
select * from activity_processing_states;
SELECT * FROM teams where name LIKE '%Fare%'; # 233
SELECT * FROM opportunities where crm_configuration_id = 215
# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'
;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1088 and sa.provider = 'hubspot';
SELECT * FROM teams order by updated_at DESC
SELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account
select * from crm_configurations where provider = 'pipedrive';
select * from teams where id = 957;
select * from crm_configurations where id = 957;
SELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743
SELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;
select * from users where team_id = 1; # 26726 - Gabriela Dureva
SELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific
select * from activities where user_id = 26726 order by id desc;
select * from contacts where crm_configuration_id = 1
and email IN ('[EMAIL]', '[EMAIL]'); # 2094416, 2093620
SELECT * FROM contacts WHERE id = 6284931;
SELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id
WHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;
select * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);
select * from crm_configurations where id = 1;
43801692-1aeb-32ce-acba-5b80a479701a
44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b
405975c0-b3d0-7aaa-821f-09d59cae6dd1
4caf848d-4bed-2299-b248-7788d41f9fca
49bedc3f-f196-eef3-89c3-dea6a3b4aa63
43420989-a09d-b8f8-9806-c8bbf7a02aac
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
SELECT * FROM activities WHERE id = 75461988;
SELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;
select * from contacts where id = 17900517;
select * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id
where crm.provider != 'salesforce';
select * from users where id = 21047;
SELECT * FROM crm_configurations WHERE id = 892;
SELECT * FROM teams WHERE id = 942;
select * from opportunities where team_id = 942 order by updated_at desc;
select * from contacts where team_id = 942 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 942 and sa.provider = 'hubspot';
SELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430
SELECT * FROM crm_configurations WHERE id = 1;
SELECT * FROM teams WHERE crm_id = 1;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
select id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1
SELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430
select * from teams where id = 852;
select * from groups where id = 2286;
select * from sidekick_settings where team_id = 852;
select * from default_activity_types where team_id = 852;
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1 AND u.deleted_at IS NULL
AND u.crm_required = 1
AND u.team_id = 1
ORDER BY u.team_id;
SELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (
18481
);
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1
AND u.deleted_at IS NULL
AND u.crm_required = 1
# AND u.team_id = 1
AND p.id IS NULL -- Move this condition to WHERE clause
ORDER BY u.team_id;
SELECT * FROM opportunities WHERE id = 20002609;
select * from teams where id = 1122; # Velatir, 29953 - [EMAIL]
select * from crm_configurations where id = 1060;
select * from crm_layouts where crm_configuration_id = 1060;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1122 and sa.provider = 'hubspot';
select * from opportunities where team_id = 1122 order by updated_at desc;
select * from crm_field_data where object_type = 'contact';
SELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 248 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS
SELECT * FROM users where id = 24115;
SELECT * FROM accounts where id = 4002896;
SELECT * FROM teams WHERE name LIKE '%adswerve%';
SELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN ("0069N000003GIQ9QAO","0061r000019yGP9AAM","0066900001S2KWlAAN","0066900001TDpj2AAD","0066900001b8uEwAAI","0069N000001rQi0QAE","006QF00000KD40mYAD","006QF00000LzpRJYAZ","0069N000002uomtQAA","0069N000002xlMLQAY","0066900001NV6ubAAD","0061r00001HJp45AAD","006QF00000uTlUoYAK","006QF00000v0bZqYAI");
SELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203
SELECT u.id, u.email, ac.name, a.* FROM activities a
JOIN users u ON a.user_id = u.id
JOIN accounts ac ON a.account_id = ac.id
WHERE
uuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or
uuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or
uuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;
select * from users where id = 5825;
SELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;
select * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;
19594, 862
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 862 and sa.provider = 'salesforce';
select * from automated_reports where id = 36;
select ar.frequency, r.*, ar.* from automated_report_results r
join automated_reports ar on r.report_id = ar.id
where ar.frequency != 'one_off';
select s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;
select * from nudges n where n.activity_search_id
select * from teams where created_at > '2026-03-09';
SELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;
select * from users where team_id = 1 and name like '%Lukas%'; # 7160
SELECT * FROM teams WHERE id = 575;
select * from opportunities where team_id = 575;
SELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,
select * from opportunities where team_id = 1126;
SELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,
select * from opportunities where team_id = 1125;
select * from contacts c
where c.team_id = 882;
SELECT * FROM activities WHERE id = 76822967;
SELECT * FROM crm_profiles WHERE user_id = 15440;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 555;
SELECT * FROM crm_configurations WHERE id = 555;
SELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 581 and sa.provider = 'salesforce';
SELECT * FROM automated_report_results order by id desc;
select * from features;
select * from team_features where feature_id = 40;
select * from teams where id = 556;
select * from automated_reports;
where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , ["pdf","podcast"]
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
select * from automated_report_results order by id desc;
SELECT * FROM automated_report_results WHERE id = 1919;
select * from automated_report_results WHERE report_id = 54;
select * from opportunities where id = 7594349;
SELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - [EMAIL]
select * from playbooks where team_id = 711; # event 226147
SELECT * FROM playbook_categories WHERE playbook_id = 5515;
SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';
SELECT * FROM crm_fields WHERE id = 226147;
SELECT * FROM crm_field_values WHERE crm_field_id = 226147;
SELECT * FROM crm_configurations WHERE id = 692;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 711 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;
select * from leads;
select * from calendars;
SELECT
t.id AS team_id,
t.name,
LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain
FROM teams t
JOIN users u ON u.team_id = t.id
JOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'
LEFT JOIN team_domains td
ON td.team_id = t.id
AND td.deleted_at IS NULL
AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))
GROUP BY t.id, t.name, calendar_domain
ORDER BY t.name, calendar_domain;
select * from users u join calendars c on c.user_id = u.id
where u.team_id = 882;
select * from activities where id = 74049485; # team 563 crm 537
select * from activities where id = 73272382; # team 563 crm 537
select * from activities where id = 64400389; # team 563 crm 537
select * from activities where id = 58081273; # team 563 crm 537
select * from activities where id = 54520297; # team 563 crm 537
select * from participants where activity_id = 58081273;
select * from activities where crm_configuration_id = 537 and provider = 'aircall'
and account_id = 19003658 order by updated_at desc;
select * from contacts where crm_configuration_id = 537 and id = 35957759;
select * from accounts where crm_configuration_id = 537 and id = 19003658;
select * from automated_report_results where id = 1976;
select * from automated_reports where id = 583;
select * from activity_searches where id = 87714;
select * from activity_search_filters where activity_search_id = 87714;
SELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid
or uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;
SELECT * FROM crm_configurations WHERE provider = 'hubspot';
select * from rate_limits;
select * from automated_report_results where media_type = 'pdf' and status = 2
and id IN (18, 1872);
select * from automated_reports where id = 54;
SELECT * FROM users WHERE id IN (24623,29443,29613);
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
32885
|
1256
|
9
|
2026-05-13T09:44:20.309582+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665460309_m1.jpg...
|
PhpStorm
|
faVsco.js – CreateTeam.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-7673782238848625796
|
-8646559087753982588
|
visual_change
|
hybrid
|
NULL
|
Project: faVsco.js, menu
master, menu
SlackFile Ed Project: faVsco.js, menu
master, menu
SlackFile Edit ViewGoHistoryWindowHelpAPPDOCKERDEV (docker)₴82APP (-zshtests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleterTest.phptests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesProviderTest.phptests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesUploaderTest.phptests/Unit/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeeches?tests/Unit/Component/Transcription/Diarization/Source/MeetingBotSourceTest.phptests/Unit/Contracts/Services/Calendar/CalendarTraitTest.phptests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.phptests/Unit/Jobs/Activity/Import/ImportTwilioVideoSpeechesJobTest.phptests/Unit/Jobs/Activity/Import/IsActivityReadyForProcessingJobTest.phptests/Unit/Jobs/Calendar/SetupCalendarSyncTest.phptests/Unit/Services/Activity/ParticipantsServiceTest.phptests/Unit/Services/Calendar/Command/ImportParticipantsTest.phptests/Unit/Services/Calendar/GoogleCalendarServiceTest.phptests/Unit/Services/Crm/Close/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTest.phptests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTraitMatchActivitiesTest.phytests/Unit/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTraitOpportunitiesTe:tests/Unit/Services/Crm/Pipedrive/ImportOpportunityMatchActivitiesTest.phptests/Unit/Services/Crm/Salesforce/ServiceTest.phptests/Unit/Services/Mail/0ffice/EmailApiClientTest.phptests/Unit/Services/RecallAI/RecallAIServiceTest.php113 files changed, 4143 insertions(+), 1740 deletions(-)create mode 120000 CLAUDE.mdcreate mode 100644 app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.phpdelete mode 100644 app/Component/ES/ElasticSearchWorkerManager.phpdelete mode 100644 app/Component/ES/Worker/ActivityWorker.phpdelete mode 100644 app/Component/ES/Worker/EntityWorker.phpdelete mode100644 app/Component/ES/Worker/WorkerAmount.phpdelete mode100644 app/Component/ES/Worker/WorkerInterface.phpcreate mode100644 app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.phtcreate mode100644 app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/Assembl:create mode100644 app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNot(create mode 100644 app/Console/Commands/Crm/Backfill0pportunityUserFromAccountCommand.phpdelete mode 100644 app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.phpcreate mode100644 front-end/src/components/shared/modals/EntityPickerModal/__tests__/us‹create mode 100644 tests/Feature/Component/Nudge/Process0rganisationImmediateNudgesJobTe:create mode 100644 tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheck‹delete mode 100644 tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/ActivityWorkerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/EntityWorkerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/WorkerAmountTest.phpcreate mode 100644 tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCrcreate mode 100644 tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.phpLukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ I|HomeDMsActivityFilesLaterMore(aol• Support Daily - in 2 h 16 m100% <78•Wed 13 May 12:44:19ED-→Describe what you are looking forJiminny ...cunoartylau# engineering# general# jiminny-bg# platform-tickets# product_launches#random# releases# sofia-office# support# thank-yous# the_people_of jimi...° Direct messages& Nikolay Ivanovdo James Graham. Stoyan Tanev. Galya Dimitrova. Steliyan Georgievo Petko Kashinski®. Aneliya Angelovaã. Stefka Stoyanova•. Vasil Vasilev •!Lukas Kovalik y...l:: AppsJira CloudToastNikolay Ivanov6 0MessagesAdd canvas@ Files+Lukas Kovalik 11.Today ~мен все ме праща наhttps://app.vanta.com/c/jiminny.com/employee/onboardingNikolay Ivanov 11:01 AMХм, Джейс дали не може да ти помогне?Lukas Kovalik 11:01 AMще питам James, предполагам че нямам правада мерсиNikolay Ivanov 11:01 AMмдаМОЛЯLukas Kovalik 12:13 PMНики сори, още един въпрос имамкогато ги правеше ти FE ли оправяима vulnerabilities no npmNikolay Ivanov 12:28 PMнетях ги оставямLukas Kovalik 12:29 PMаз погледнах твоя тикет и там друго нямашесамо FEкак стигна до WorkerMessage Nikolay Ivanov...
|
32882
|
NULL
|
NULL
|
NULL
|
|
32886
|
1256
|
10
|
2026-05-13T09:44:23.726034+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665463726_m1.jpg...
|
PhpStorm
|
faVsco.js – TeamController.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
3
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\Settings\Teams;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
use Jiminny\Actions\InviteUserToTeamAction;
use Jiminny\Interactions\Settings\Teams\CreateTeam;
use Jiminny\DTO\Invitation\UserInvitationDTO;
use Jiminny\Http\Requests\Settings\Teams\CreateTeamRequest;
use Jiminny\Http\Controllers\Controller;
use Jiminny\Http\Requests\Settings\Teams\EditTeamRequest;
use Jiminny\Interactions\Settings\Teams\EditTeam;
use Jiminny\Models\Team;
use Jiminny\Models\User;
final class TeamController extends Controller
{
/**
* Create a new team, subscription and invitation.
*/
public function store(
CreateTeamRequest $request,
CreateTeam $createTeam,
InviteUserToTeamAction $inviteUserToTeamAction,
): void {
/** @var User $teamCreator */
$teamCreator = $request->user();
try {
$data = $request->all();
$team = $createTeam->handle($teamCreator, $data, $request->getDomain());
$inviteUserToTeamAction->execute(UserInvitationDTO::forOwner($request, $team));
} catch (\Exception $exception) {
Log::error('An error occurred while creating team', [
'e_message' => $exception->getMessage(),
'e_code' => $exception->getCode(),
]);
throw $exception;
}
}
public function edit(
Team $team,
EditTeamRequest $request,
EditTeam $editTeam,
): JsonResponse {
/** @var User $teamEditor */
$teamEditor = $request->user();
$editTeam->handle($team, $teamEditor, $request->all(), $request);
return response()->json([], JsonResponse::HTTP_OK);
}
}
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...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"3","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Http\\Controllers\\Settings\\Teams;\n\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Actions\\InviteUserToTeamAction;\nuse Jiminny\\Interactions\\Settings\\Teams\\CreateTeam;\nuse Jiminny\\DTO\\Invitation\\UserInvitationDTO;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\CreateTeamRequest;\nuse Jiminny\\Http\\Controllers\\Controller;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\EditTeamRequest;\nuse Jiminny\\Interactions\\Settings\\Teams\\EditTeam;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\n\nfinal class TeamController extends Controller\n{\n /**\n * Create a new team, subscription and invitation.\n */\n public function store(\n CreateTeamRequest $request,\n CreateTeam $createTeam,\n InviteUserToTeamAction $inviteUserToTeamAction,\n ): void {\n /** @var User $teamCreator */\n $teamCreator = $request->user();\n\n try {\n $data = $request->all();\n $team = $createTeam->handle($teamCreator, $data, $request->getDomain());\n\n $inviteUserToTeamAction->execute(UserInvitationDTO::forOwner($request, $team));\n } catch (\\Exception $exception) {\n Log::error('An error occurred while creating team', [\n 'e_message' => $exception->getMessage(),\n 'e_code' => $exception->getCode(),\n ]);\n\n throw $exception;\n }\n }\n\n public function edit(\n Team $team,\n EditTeamRequest $request,\n EditTeam $editTeam,\n ): JsonResponse {\n /** @var User $teamEditor */\n $teamEditor = $request->user();\n $editTeam->handle($team, $teamEditor, $request->all(), $request);\n\n return response()->json([], JsonResponse::HTTP_OK);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Http\\Controllers\\Settings\\Teams;\n\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Actions\\InviteUserToTeamAction;\nuse Jiminny\\Interactions\\Settings\\Teams\\CreateTeam;\nuse Jiminny\\DTO\\Invitation\\UserInvitationDTO;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\CreateTeamRequest;\nuse Jiminny\\Http\\Controllers\\Controller;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\EditTeamRequest;\nuse Jiminny\\Interactions\\Settings\\Teams\\EditTeam;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\n\nfinal class TeamController extends Controller\n{\n /**\n * Create a new team, subscription and invitation.\n */\n public function store(\n CreateTeamRequest $request,\n CreateTeam $createTeam,\n InviteUserToTeamAction $inviteUserToTeamAction,\n ): void {\n /** @var User $teamCreator */\n $teamCreator = $request->user();\n\n try {\n $data = $request->all();\n $team = $createTeam->handle($teamCreator, $data, $request->getDomain());\n\n $inviteUserToTeamAction->execute(UserInvitationDTO::forOwner($request, $team));\n } catch (\\Exception $exception) {\n Log::error('An error occurred while creating team', [\n 'e_message' => $exception->getMessage(),\n 'e_code' => $exception->getCode(),\n ]);\n\n throw $exception;\n }\n }\n\n public function edit(\n Team $team,\n EditTeamRequest $request,\n EditTeam $editTeam,\n ): JsonResponse {\n /** @var User $teamEditor */\n $teamEditor = $request->user();\n $editTeam->handle($team, $teamEditor, $request->all(), $request);\n\n return response()->json([], JsonResponse::HTTP_OK);\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}]...
|
1416299784951314072
|
-8974528256362210363
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
3
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\Settings\Teams;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
use Jiminny\Actions\InviteUserToTeamAction;
use Jiminny\Interactions\Settings\Teams\CreateTeam;
use Jiminny\DTO\Invitation\UserInvitationDTO;
use Jiminny\Http\Requests\Settings\Teams\CreateTeamRequest;
use Jiminny\Http\Controllers\Controller;
use Jiminny\Http\Requests\Settings\Teams\EditTeamRequest;
use Jiminny\Interactions\Settings\Teams\EditTeam;
use Jiminny\Models\Team;
use Jiminny\Models\User;
final class TeamController extends Controller
{
/**
* Create a new team, subscription and invitation.
*/
public function store(
CreateTeamRequest $request,
CreateTeam $createTeam,
InviteUserToTeamAction $inviteUserToTeamAction,
): void {
/** @var User $teamCreator */
$teamCreator = $request->user();
try {
$data = $request->all();
$team = $createTeam->handle($teamCreator, $data, $request->getDomain());
$inviteUserToTeamAction->execute(UserInvitationDTO::forOwner($request, $team));
} catch (\Exception $exception) {
Log::error('An error occurred while creating team', [
'e_message' => $exception->getMessage(),
'e_code' => $exception->getCode(),
]);
throw $exception;
}
}
public function edit(
Team $team,
EditTeamRequest $request,
EditTeam $editTeam,
): JsonResponse {
/** @var User $teamEditor */
$teamEditor = $request->user();
$editTeam->handle($team, $teamEditor, $request->all(), $request);
return response()->json([], JsonResponse::HTTP_OK);
}
}
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...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
32887
|
1257
|
7
|
2026-05-13T09:44:23.726052+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665463726_m2.jpg...
|
PhpStorm
|
faVsco.js – TeamController.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
3
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\Settings\Teams;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
use Jiminny\Actions\InviteUserToTeamAction;
use Jiminny\Interactions\Settings\Teams\CreateTeam;
use Jiminny\DTO\Invitation\UserInvitationDTO;
use Jiminny\Http\Requests\Settings\Teams\CreateTeamRequest;
use Jiminny\Http\Controllers\Controller;
use Jiminny\Http\Requests\Settings\Teams\EditTeamRequest;
use Jiminny\Interactions\Settings\Teams\EditTeam;
use Jiminny\Models\Team;
use Jiminny\Models\User;
final class TeamController extends Controller
{
/**
* Create a new team, subscription and invitation.
*/
public function store(
CreateTeamRequest $request,
CreateTeam $createTeam,
InviteUserToTeamAction $inviteUserToTeamAction,
): void {
/** @var User $teamCreator */
$teamCreator = $request->user();
try {
$data = $request->all();
$team = $createTeam->handle($teamCreator, $data, $request->getDomain());
$inviteUserToTeamAction->execute(UserInvitationDTO::forOwner($request, $team));
} catch (\Exception $exception) {
Log::error('An error occurred while creating team', [
'e_message' => $exception->getMessage(),
'e_code' => $exception->getCode(),
]);
throw $exception;
}
}
public function edit(
Team $team,
EditTeamRequest $request,
EditTeam $editTeam,
): JsonResponse {
/** @var User $teamEditor */
$teamEditor = $request->user();
$editTeam->handle($team, $teamEditor, $request->all(), $request);
return response()->json([], JsonResponse::HTTP_OK);
}
}
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...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.034242023,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"3","depth":4,"bounds":{"left":0.38397607,"top":0.07581804,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.39361703,"top":0.074221864,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.40093085,"top":0.074221864,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Http\\Controllers\\Settings\\Teams;\n\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Actions\\InviteUserToTeamAction;\nuse Jiminny\\Interactions\\Settings\\Teams\\CreateTeam;\nuse Jiminny\\DTO\\Invitation\\UserInvitationDTO;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\CreateTeamRequest;\nuse Jiminny\\Http\\Controllers\\Controller;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\EditTeamRequest;\nuse Jiminny\\Interactions\\Settings\\Teams\\EditTeam;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\n\nfinal class TeamController extends Controller\n{\n /**\n * Create a new team, subscription and invitation.\n */\n public function store(\n CreateTeamRequest $request,\n CreateTeam $createTeam,\n InviteUserToTeamAction $inviteUserToTeamAction,\n ): void {\n /** @var User $teamCreator */\n $teamCreator = $request->user();\n\n try {\n $data = $request->all();\n $team = $createTeam->handle($teamCreator, $data, $request->getDomain());\n\n $inviteUserToTeamAction->execute(UserInvitationDTO::forOwner($request, $team));\n } catch (\\Exception $exception) {\n Log::error('An error occurred while creating team', [\n 'e_message' => $exception->getMessage(),\n 'e_code' => $exception->getCode(),\n ]);\n\n throw $exception;\n }\n }\n\n public function edit(\n Team $team,\n EditTeamRequest $request,\n EditTeam $editTeam,\n ): JsonResponse {\n /** @var User $teamEditor */\n $teamEditor = $request->user();\n $editTeam->handle($team, $teamEditor, $request->all(), $request);\n\n return response()->json([], JsonResponse::HTTP_OK);\n }\n}","depth":4,"bounds":{"left":0.11968085,"top":0.0726257,"width":0.28823137,"height":0.9066241},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Http\\Controllers\\Settings\\Teams;\n\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Actions\\InviteUserToTeamAction;\nuse Jiminny\\Interactions\\Settings\\Teams\\CreateTeam;\nuse Jiminny\\DTO\\Invitation\\UserInvitationDTO;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\CreateTeamRequest;\nuse Jiminny\\Http\\Controllers\\Controller;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\EditTeamRequest;\nuse Jiminny\\Interactions\\Settings\\Teams\\EditTeam;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\n\nfinal class TeamController extends Controller\n{\n /**\n * Create a new team, subscription and invitation.\n */\n public function store(\n CreateTeamRequest $request,\n CreateTeam $createTeam,\n InviteUserToTeamAction $inviteUserToTeamAction,\n ): void {\n /** @var User $teamCreator */\n $teamCreator = $request->user();\n\n try {\n $data = $request->all();\n $team = $createTeam->handle($teamCreator, $data, $request->getDomain());\n\n $inviteUserToTeamAction->execute(UserInvitationDTO::forOwner($request, $team));\n } catch (\\Exception $exception) {\n Log::error('An error occurred while creating team', [\n 'e_message' => $exception->getMessage(),\n 'e_code' => $exception->getCode(),\n ]);\n\n throw $exception;\n }\n }\n\n public function edit(\n Team $team,\n EditTeamRequest $request,\n EditTeam $editTeam,\n ): JsonResponse {\n /** @var User $teamEditor */\n $teamEditor = $request->user();\n $editTeam->handle($team, $teamEditor, $request->all(), $request);\n\n return response()->json([], JsonResponse::HTTP_OK);\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.40957448,"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.41821808,"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.42918882,"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.43783244,"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.44647607,"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.4574468,"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.46841756,"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.4950133,"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.50598407,"top":0.09896249,"width":0.029587766,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"bounds":{"left":0.7084442,"top":0.09896249,"width":0.02825798,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"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}]...
|
1416299784951314072
|
-8974528256362210363
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
3
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\Settings\Teams;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
use Jiminny\Actions\InviteUserToTeamAction;
use Jiminny\Interactions\Settings\Teams\CreateTeam;
use Jiminny\DTO\Invitation\UserInvitationDTO;
use Jiminny\Http\Requests\Settings\Teams\CreateTeamRequest;
use Jiminny\Http\Controllers\Controller;
use Jiminny\Http\Requests\Settings\Teams\EditTeamRequest;
use Jiminny\Interactions\Settings\Teams\EditTeam;
use Jiminny\Models\Team;
use Jiminny\Models\User;
final class TeamController extends Controller
{
/**
* Create a new team, subscription and invitation.
*/
public function store(
CreateTeamRequest $request,
CreateTeam $createTeam,
InviteUserToTeamAction $inviteUserToTeamAction,
): void {
/** @var User $teamCreator */
$teamCreator = $request->user();
try {
$data = $request->all();
$team = $createTeam->handle($teamCreator, $data, $request->getDomain());
$inviteUserToTeamAction->execute(UserInvitationDTO::forOwner($request, $team));
} catch (\Exception $exception) {
Log::error('An error occurred while creating team', [
'e_message' => $exception->getMessage(),
'e_code' => $exception->getCode(),
]);
throw $exception;
}
}
public function edit(
Team $team,
EditTeamRequest $request,
EditTeam $editTeam,
): JsonResponse {
/** @var User $teamEditor */
$teamEditor = $request->user();
$editTeam->handle($team, $teamEditor, $request->all(), $request);
return response()->json([], JsonResponse::HTTP_OK);
}
}
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...
|
32884
|
NULL
|
NULL
|
NULL
|
|
32888
|
1256
|
11
|
2026-05-13T09:44:25.449824+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665465449_m1.jpg...
|
PhpStorm
|
faVsco.js – TeamController.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
3
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\Settings\Teams;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
use Jiminny\Actions\InviteUserToTeamAction;
use Jiminny\Interactions\Settings\Teams\CreateTeam;
use Jiminny\DTO\Invitation\UserInvitationDTO;
use Jiminny\Http\Requests\Settings\Teams\CreateTeamRequest;
use Jiminny\Http\Controllers\Controller;
use Jiminny\Http\Requests\Settings\Teams\EditTeamRequest;
use Jiminny\Interactions\Settings\Teams\EditTeam;
use Jiminny\Models\Team;
use Jiminny\Models\User;
final class TeamController extends Controller
{
/**
* Create a new team, subscription and invitation.
*/
public function store(
CreateTeamRequest $request,
CreateTeam $createTeam,
InviteUserToTeamAction $inviteUserToTeamAction,
): void {
/** @var User $teamCreator */
$teamCreator = $request->user();
try {
$data = $request->all();
$team = $createTeam->handle($teamCreator, $data, $request->getDomain());
$inviteUserToTeamAction->execute(UserInvitationDTO::forOwner($request, $team));
} catch (\Exception $exception) {
Log::error('An error occurred while creating team', [
'e_message' => $exception->getMessage(),
'e_code' => $exception->getCode(),
]);
throw $exception;
}
}
public function edit(
Team $team,
EditTeamRequest $request,
EditTeam $editTeam,
): JsonResponse {
/** @var User $teamEditor */
$teamEditor = $request->user();
$editTeam->handle($team, $teamEditor, $request->all(), $request);
return response()->json([], JsonResponse::HTTP_OK);
}
}
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
40
1
40
64
Previous Highlighted Error
Next Highlighted Error
SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993
SELECT * FROM users WHERE id = 25061;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 994;
SELECT * FROM crm_profiles WHERE user_id = 25061;
select * from crm_configurations where id = 834;
SELECT * FROM teams WHERE id = 882;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;
SELECT * FROM contacts where crm_configuration_id = 834;
SELECT * FROM opportunities WHERE team_id = 933
# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');
AND id IN (8482561,18352941,19042734,19232139,19445140,19472541);
SELECT * FROM opportunity_contacts
WHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 485; #
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
select crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id
where crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')
# and l.converted_at IS NOT NULL
;
# [PASSWORD_DOTS]
SELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')
and opportunity_id IS NULL
order by id desc;
SELECT * FROM teams WHERE id = 604; # 598
SELECT * FROM activities WHERE id = 74410828; # [EMAIL]
SELECT * FROM accounts WHERE id = 20068382;
SELECT * FROM accounts WHERE id = 35186038;
SELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 559 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;
select * from sidekick_settings where team_id = 781;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100
SELECT * FROM crm_layouts WHERE crm_configuration_id = 711;
SELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL
and is_internal = 0 and status = 'completed'
order by id desc;
SELECT * FROM crm_layout_entities
WHERE crm_layout_id IN (2352, 2353);
;
SELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 556 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;
SELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;
select * from contacts
where crm_configuration_id = 530
and crm_provider_id = 872252;
select * from activities where crm_configuration_id = 530
and user_id = 14343 and type like '%softphone%'
and created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);
SELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t
JOIN crm_configurations c ON t.id = c.team_id
WHERE t.status = 'active';
SELECT * FROM teams where id = 1091;
SELECT * FROM crm_configurations where team_id = 1091;
SELECT * FROM activity_providers where team_id = 1091;
SELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT * FROM teams WHERE name LIKE '%Leadventure%';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1091 and sa.provider = 'salesforce';
SELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812
SELECT * FROM teams where id = 862;
SELECT * FROM crm_configurations where team_id = 862;
SELECT * FROM activity_providers where team_id = 862;
SELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT t.id, crm.id, crm.provider, ap.* FROM teams t
join crm_configurations crm on t.id = crm.team_id
join activity_providers ap on t.id = ap.team_id
where t.status = 'active' and ap.is_enabled = 1
and crm.provider = 'hubspot'
and ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',
'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');
SELECT * FROM teams where id = 1068;
SELECT * FROM crm_configurations where team_id = 1068;
SELECT * FROM activity_providers where team_id = 1068;
SELECT * FROM activities a
where crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')
and a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'
)
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by a.id desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1068 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262
SELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
select * from crm_layouts where crm_configuration_id = 834;
select * from crm_layout_entities where crm_layout_id = 2780;
select * from crm_fields where id IN (321153,321192,321193,321194);
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1057 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8
SELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20
SELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10
SELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #
SELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;
select * from users where team_id = 51; # 7783
SELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130
select * from activity_searches where user_id = 7783;
select * from activity_search_filters where activity_search_id IN (32291, 32292);
SELECT asf.activity_search_id, asf.id, asf.value
FROM activity_search_filters asf
WHERE asf.filter = 'group_id'
AND asf.value IN (
SELECT CONCAT(
HEX(SUBSTR(uuid, 5, 4)), '-',
HEX(SUBSTR(uuid, 3, 2)), '-',
HEX(SUBSTR(uuid, 1, 2)), '-',
HEX(SUBSTR(uuid, 9, 2)), '-',
HEX(SUBSTR(uuid, 11))
)
FROM groups
WHERE deleted_at IS NOT NULL
);
SELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where provider = 'hubspot';
SELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133
SELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null
# [PASSWORD_DOTS]
select * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';
select
cp.*
# DISTINCT t.id
# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields
FROM crm_profiles cp
JOIN crm_configurations crm on crm.id = cp.crm_configuration_id
JOIN users u on u.id = cp.user_id
JOIN teams t ON t.id = crm.team_id
WHERE crm.provider = 'salesforce' and t.status = 'active'
and cp.archived_at IS NULL and u.deleted_at IS NULL
and t.id NOT IN (1093)
and t.id = 2
and cp.contact_fields IS NULL;
# and c.crm_provider_id = '003Uu00000ojD4NIAU';
SELECT * FROM users WHERE id = 26484;
SELECT * FROM crm_profiles WHERE user_id = 26484;
SELECT * FROM social_accounts WHERE sociable_id = 26484;
SELECT * FROM crm_configurations where provider = 'salesforce';
select * from users where id IN (10022, 10403);
select * from users where team_id IN (526);
select * from teams where id IN (526, 532);
select * from crm_configurations where id IN (500, 516);
select * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);
select * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 526 and sa.provider = 'salesforce';
select * from team_settings where team_id IN (526, 532);
select * from users where id IN (22824);
select * from crm_profiles where crm_configuration_id IN (1026);
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1093 and sa.provider = 'salesforce';
select * from teams where id = 1099;
select * from users where id = 29643
select * from activity_processing_states;
SELECT * FROM teams where name LIKE '%Fare%'; # 233
SELECT * FROM opportunities where crm_configuration_id = 215
# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'
;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1088 and sa.provider = 'hubspot';
SELECT * FROM teams order by updated_at DESC
SELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account
select * from crm_configurations where provider = 'pipedrive';
select * from teams where id = 957;
select * from crm_configurations where id = 957;
SELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743
SELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;
select * from users where team_id = 1; # 26726 - Gabriela Dureva
SELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific
select * from activities where user_id = 26726 order by id desc;
select * from contacts where crm_configuration_id = 1
and email IN ('[EMAIL]', '[EMAIL]'); # 2094416, 2093620
SELECT * FROM contacts WHERE id = 6284931;
SELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id
WHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;
select * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);
select * from crm_configurations where id = 1;
43801692-1aeb-32ce-acba-5b80a479701a
44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b
405975c0-b3d0-7aaa-821f-09d59cae6dd1
4caf848d-4bed-2299-b248-7788d41f9fca
49bedc3f-f196-eef3-89c3-dea6a3b4aa63
43420989-a09d-b8f8-9806-c8bbf7a02aac
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
SELECT * FROM activities WHERE id = 75461988;
SELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;
select * from contacts where id = 17900517;
select * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id
where crm.provider != 'salesforce';
select * from users where id = 21047;
SELECT * FROM crm_configurations WHERE id = 892;
SELECT * FROM teams WHERE id = 942;
select * from opportunities where team_id = 942 order by updated_at desc;
select * from contacts where team_id = 942 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 942 and sa.provider = 'hubspot';
SELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430
SELECT * FROM crm_configurations WHERE id = 1;
SELECT * FROM teams WHERE crm_id = 1;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
select id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1
SELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430
select * from teams where id = 852;
select * from groups where id = 2286;
select * from sidekick_settings where team_id = 852;
select * from default_activity_types where team_id = 852;
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1 AND u.deleted_at IS NULL
AND u.crm_required = 1
AND u.team_id = 1
ORDER BY u.team_id;
SELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (
18481
);
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1
AND u.deleted_at IS NULL
AND u.crm_required = 1
# AND u.team_id = 1
AND p.id IS NULL -- Move this condition to WHERE clause
ORDER BY u.team_id;
SELECT * FROM opportunities WHERE id = 20002609;
select * from teams where id = 1122; # Velatir, 29953 - [EMAIL]
select * from crm_configurations where id = 1060;
select * from crm_layouts where crm_configuration_id = 1060;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1122 and sa.provider = 'hubspot';
select * from opportunities where team_id = 1122 order by updated_at desc;
select * from crm_field_data where object_type = 'contact';
SELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 248 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS
SELECT * FROM users where id = 24115;
SELECT * FROM accounts where id = 4002896;
SELECT * FROM teams WHERE name LIKE '%adswerve%';
SELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN ("0069N000003GIQ9QAO","0061r000019yGP9AAM","0066900001S2KWlAAN","0066900001TDpj2AAD","0066900001b8uEwAAI","0069N000001rQi0QAE","006QF00000KD40mYAD","006QF00000LzpRJYAZ","0069N000002uomtQAA","0069N000002xlMLQAY","0066900001NV6ubAAD","0061r00001HJp45AAD","006QF00000uTlUoYAK","006QF00000v0bZqYAI");
SELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203
SELECT u.id, u.email, ac.name, a.* FROM activities a
JOIN users u ON a.user_id = u.id
JOIN accounts ac ON a.account_id = ac.id
WHERE
uuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or
uuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or
uuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;
select * from users where id = 5825;
SELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;
select * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;
19594, 862
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 862 and sa.provider = 'salesforce';
select * from automated_reports where id = 36;
select ar.frequency, r.*, ar.* from automated_report_results r
join automated_reports ar on r.report_id = ar.id
where ar.frequency != 'one_off';
select s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;
select * from nudges n where n.activity_search_id
select * from teams where created_at > '2026-03-09';
SELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;
select * from users where team_id = 1 and name like '%Lukas%'; # 7160
SELECT * FROM teams WHERE id = 575;
select * from opportunities where team_id = 575;
SELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,
select * from opportunities where team_id = 1126;
SELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,
select * from opportunities where team_id = 1125;
select * from contacts c
where c.team_id = 882;
SELECT * FROM activities WHERE id = 76822967;
SELECT * FROM crm_profiles WHERE user_id = 15440;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 555;
SELECT * FROM crm_configurations WHERE id = 555;
SELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 581 and sa.provider = 'salesforce';
SELECT * FROM automated_report_results order by id desc;
select * from features;
select * from team_features where feature_id = 40;
select * from teams where id = 556;
select * from automated_reports;
where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , ["pdf","podcast"]
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
select * from automated_report_results order by id desc;
SELECT * FROM automated_report_results WHERE id = 1919;
select * from automated_report_results WHERE report_id = 54;
select * from opportunities where id = 7594349;
SELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - [EMAIL]
select * from playbooks where team_id = 711; # event 226147
SELECT * FROM playbook_categories WHERE playbook_id = 5515;
SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';
SELECT * FROM crm_fields WHERE id = 226147;
SELECT * FROM crm_field_values WHERE crm_field_id = 226147;
SELECT * FROM crm_configurations WHERE id = 692;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 711 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;
select * from leads;
select * from calendars;
SELECT
t.id AS team_id,
t.name,
LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain
FROM teams t
JOIN users u ON u.team_id = t.id
JOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'
LEFT JOIN team_domains td
ON td.team_id = t.id
AND td.deleted_at IS NULL
AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))
GROUP BY t.id, t.name, calendar_domain
ORDER BY t.name, calendar_domain;
select * from users u join calendars c on c.user_id = u.id
where u.team_id = 882;
select * from activities where id = 74049485; # team 563 crm 537
select * from activities where id = 73272382; # team 563 crm 537
select * from activities where id = 64400389; # team 563 crm 537
select * from activities where id = 58081273; # team 563 crm 537
select * from activities where id = 54520297; # team 563 crm 537
select * from participants where activity_id = 58081273;
select * from activities where crm_configuration_id = 537 and provider = 'aircall'
and account_id = 19003658 order by updated_at desc;
select * from contacts where crm_configuration_id = 537 and id = 35957759;
select * from accounts where crm_configuration_id = 537 and id = 19003658;
select * from automated_report_results where id = 1976;
select * from automated_reports where id = 583;
select * from activity_searches where id = 87714;
select * from activity_search_filters where activity_search_id = 87714;
SELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid
or uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;
SELECT * FROM crm_configurations WHERE provider = 'hubspot';
select * from rate_limits;
select * from automated_report_results where media_type = 'pdf' and status = 2
and id IN (18, 1872);
select * from automated_reports where id = 54;
SELECT * FROM users WHERE id IN (24623,29443,29613);
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"3","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Http\\Controllers\\Settings\\Teams;\n\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Actions\\InviteUserToTeamAction;\nuse Jiminny\\Interactions\\Settings\\Teams\\CreateTeam;\nuse Jiminny\\DTO\\Invitation\\UserInvitationDTO;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\CreateTeamRequest;\nuse Jiminny\\Http\\Controllers\\Controller;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\EditTeamRequest;\nuse Jiminny\\Interactions\\Settings\\Teams\\EditTeam;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\n\nfinal class TeamController extends Controller\n{\n /**\n * Create a new team, subscription and invitation.\n */\n public function store(\n CreateTeamRequest $request,\n CreateTeam $createTeam,\n InviteUserToTeamAction $inviteUserToTeamAction,\n ): void {\n /** @var User $teamCreator */\n $teamCreator = $request->user();\n\n try {\n $data = $request->all();\n $team = $createTeam->handle($teamCreator, $data, $request->getDomain());\n\n $inviteUserToTeamAction->execute(UserInvitationDTO::forOwner($request, $team));\n } catch (\\Exception $exception) {\n Log::error('An error occurred while creating team', [\n 'e_message' => $exception->getMessage(),\n 'e_code' => $exception->getCode(),\n ]);\n\n throw $exception;\n }\n }\n\n public function edit(\n Team $team,\n EditTeamRequest $request,\n EditTeam $editTeam,\n ): JsonResponse {\n /** @var User $teamEditor */\n $teamEditor = $request->user();\n $editTeam->handle($team, $teamEditor, $request->all(), $request);\n\n return response()->json([], JsonResponse::HTTP_OK);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Http\\Controllers\\Settings\\Teams;\n\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Actions\\InviteUserToTeamAction;\nuse Jiminny\\Interactions\\Settings\\Teams\\CreateTeam;\nuse Jiminny\\DTO\\Invitation\\UserInvitationDTO;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\CreateTeamRequest;\nuse Jiminny\\Http\\Controllers\\Controller;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\EditTeamRequest;\nuse Jiminny\\Interactions\\Settings\\Teams\\EditTeam;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\n\nfinal class TeamController extends Controller\n{\n /**\n * Create a new team, subscription and invitation.\n */\n public function store(\n CreateTeamRequest $request,\n CreateTeam $createTeam,\n InviteUserToTeamAction $inviteUserToTeamAction,\n ): void {\n /** @var User $teamCreator */\n $teamCreator = $request->user();\n\n try {\n $data = $request->all();\n $team = $createTeam->handle($teamCreator, $data, $request->getDomain());\n\n $inviteUserToTeamAction->execute(UserInvitationDTO::forOwner($request, $team));\n } catch (\\Exception $exception) {\n Log::error('An error occurred while creating team', [\n 'e_message' => $exception->getMessage(),\n 'e_code' => $exception->getCode(),\n ]);\n\n throw $exception;\n }\n }\n\n public function edit(\n Team $team,\n EditTeamRequest $request,\n EditTeam $editTeam,\n ): JsonResponse {\n /** @var User $teamEditor */\n $teamEditor = $request->user();\n $editTeam->handle($team, $teamEditor, $request->all(), $request);\n\n return response()->json([], JsonResponse::HTTP_OK);\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":"40","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"40","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"64","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","depth":4,"on_screen":true,"value":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","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}]...
|
7072317158041286516
|
1065678670634825285
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
3
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\Settings\Teams;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
use Jiminny\Actions\InviteUserToTeamAction;
use Jiminny\Interactions\Settings\Teams\CreateTeam;
use Jiminny\DTO\Invitation\UserInvitationDTO;
use Jiminny\Http\Requests\Settings\Teams\CreateTeamRequest;
use Jiminny\Http\Controllers\Controller;
use Jiminny\Http\Requests\Settings\Teams\EditTeamRequest;
use Jiminny\Interactions\Settings\Teams\EditTeam;
use Jiminny\Models\Team;
use Jiminny\Models\User;
final class TeamController extends Controller
{
/**
* Create a new team, subscription and invitation.
*/
public function store(
CreateTeamRequest $request,
CreateTeam $createTeam,
InviteUserToTeamAction $inviteUserToTeamAction,
): void {
/** @var User $teamCreator */
$teamCreator = $request->user();
try {
$data = $request->all();
$team = $createTeam->handle($teamCreator, $data, $request->getDomain());
$inviteUserToTeamAction->execute(UserInvitationDTO::forOwner($request, $team));
} catch (\Exception $exception) {
Log::error('An error occurred while creating team', [
'e_message' => $exception->getMessage(),
'e_code' => $exception->getCode(),
]);
throw $exception;
}
}
public function edit(
Team $team,
EditTeamRequest $request,
EditTeam $editTeam,
): JsonResponse {
/** @var User $teamEditor */
$teamEditor = $request->user();
$editTeam->handle($team, $teamEditor, $request->all(), $request);
return response()->json([], JsonResponse::HTTP_OK);
}
}
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
40
1
40
64
Previous Highlighted Error
Next Highlighted Error
SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993
SELECT * FROM users WHERE id = 25061;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 994;
SELECT * FROM crm_profiles WHERE user_id = 25061;
select * from crm_configurations where id = 834;
SELECT * FROM teams WHERE id = 882;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;
SELECT * FROM contacts where crm_configuration_id = 834;
SELECT * FROM opportunities WHERE team_id = 933
# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');
AND id IN (8482561,18352941,19042734,19232139,19445140,19472541);
SELECT * FROM opportunity_contacts
WHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 485; #
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
select crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id
where crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')
# and l.converted_at IS NOT NULL
;
# [PASSWORD_DOTS]
SELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')
and opportunity_id IS NULL
order by id desc;
SELECT * FROM teams WHERE id = 604; # 598
SELECT * FROM activities WHERE id = 74410828; # [EMAIL]
SELECT * FROM accounts WHERE id = 20068382;
SELECT * FROM accounts WHERE id = 35186038;
SELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 559 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;
select * from sidekick_settings where team_id = 781;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100
SELECT * FROM crm_layouts WHERE crm_configuration_id = 711;
SELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL
and is_internal = 0 and status = 'completed'
order by id desc;
SELECT * FROM crm_layout_entities
WHERE crm_layout_id IN (2352, 2353);
;
SELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 556 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;
SELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;
select * from contacts
where crm_configuration_id = 530
and crm_provider_id = 872252;
select * from activities where crm_configuration_id = 530
and user_id = 14343 and type like '%softphone%'
and created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);
SELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t
JOIN crm_configurations c ON t.id = c.team_id
WHERE t.status = 'active';
SELECT * FROM teams where id = 1091;
SELECT * FROM crm_configurations where team_id = 1091;
SELECT * FROM activity_providers where team_id = 1091;
SELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT * FROM teams WHERE name LIKE '%Leadventure%';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1091 and sa.provider = 'salesforce';
SELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812
SELECT * FROM teams where id = 862;
SELECT * FROM crm_configurations where team_id = 862;
SELECT * FROM activity_providers where team_id = 862;
SELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT t.id, crm.id, crm.provider, ap.* FROM teams t
join crm_configurations crm on t.id = crm.team_id
join activity_providers ap on t.id = ap.team_id
where t.status = 'active' and ap.is_enabled = 1
and crm.provider = 'hubspot'
and ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',
'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');
SELECT * FROM teams where id = 1068;
SELECT * FROM crm_configurations where team_id = 1068;
SELECT * FROM activity_providers where team_id = 1068;
SELECT * FROM activities a
where crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')
and a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'
)
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by a.id desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1068 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262
SELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
select * from crm_layouts where crm_configuration_id = 834;
select * from crm_layout_entities where crm_layout_id = 2780;
select * from crm_fields where id IN (321153,321192,321193,321194);
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1057 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8
SELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20
SELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10
SELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #
SELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;
select * from users where team_id = 51; # 7783
SELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130
select * from activity_searches where user_id = 7783;
select * from activity_search_filters where activity_search_id IN (32291, 32292);
SELECT asf.activity_search_id, asf.id, asf.value
FROM activity_search_filters asf
WHERE asf.filter = 'group_id'
AND asf.value IN (
SELECT CONCAT(
HEX(SUBSTR(uuid, 5, 4)), '-',
HEX(SUBSTR(uuid, 3, 2)), '-',
HEX(SUBSTR(uuid, 1, 2)), '-',
HEX(SUBSTR(uuid, 9, 2)), '-',
HEX(SUBSTR(uuid, 11))
)
FROM groups
WHERE deleted_at IS NOT NULL
);
SELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where provider = 'hubspot';
SELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133
SELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null
# [PASSWORD_DOTS]
select * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';
select
cp.*
# DISTINCT t.id
# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields
FROM crm_profiles cp
JOIN crm_configurations crm on crm.id = cp.crm_configuration_id
JOIN users u on u.id = cp.user_id
JOIN teams t ON t.id = crm.team_id
WHERE crm.provider = 'salesforce' and t.status = 'active'
and cp.archived_at IS NULL and u.deleted_at IS NULL
and t.id NOT IN (1093)
and t.id = 2
and cp.contact_fields IS NULL;
# and c.crm_provider_id = '003Uu00000ojD4NIAU';
SELECT * FROM users WHERE id = 26484;
SELECT * FROM crm_profiles WHERE user_id = 26484;
SELECT * FROM social_accounts WHERE sociable_id = 26484;
SELECT * FROM crm_configurations where provider = 'salesforce';
select * from users where id IN (10022, 10403);
select * from users where team_id IN (526);
select * from teams where id IN (526, 532);
select * from crm_configurations where id IN (500, 516);
select * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);
select * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 526 and sa.provider = 'salesforce';
select * from team_settings where team_id IN (526, 532);
select * from users where id IN (22824);
select * from crm_profiles where crm_configuration_id IN (1026);
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1093 and sa.provider = 'salesforce';
select * from teams where id = 1099;
select * from users where id = 29643
select * from activity_processing_states;
SELECT * FROM teams where name LIKE '%Fare%'; # 233
SELECT * FROM opportunities where crm_configuration_id = 215
# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'
;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1088 and sa.provider = 'hubspot';
SELECT * FROM teams order by updated_at DESC
SELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account
select * from crm_configurations where provider = 'pipedrive';
select * from teams where id = 957;
select * from crm_configurations where id = 957;
SELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743
SELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;
select * from users where team_id = 1; # 26726 - Gabriela Dureva
SELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific
select * from activities where user_id = 26726 order by id desc;
select * from contacts where crm_configuration_id = 1
and email IN ('[EMAIL]', '[EMAIL]'); # 2094416, 2093620
SELECT * FROM contacts WHERE id = 6284931;
SELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id
WHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;
select * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);
select * from crm_configurations where id = 1;
43801692-1aeb-32ce-acba-5b80a479701a
44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b
405975c0-b3d0-7aaa-821f-09d59cae6dd1
4caf848d-4bed-2299-b248-7788d41f9fca
49bedc3f-f196-eef3-89c3-dea6a3b4aa63
43420989-a09d-b8f8-9806-c8bbf7a02aac
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
SELECT * FROM activities WHERE id = 75461988;
SELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;
select * from contacts where id = 17900517;
select * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id
where crm.provider != 'salesforce';
select * from users where id = 21047;
SELECT * FROM crm_configurations WHERE id = 892;
SELECT * FROM teams WHERE id = 942;
select * from opportunities where team_id = 942 order by updated_at desc;
select * from contacts where team_id = 942 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 942 and sa.provider = 'hubspot';
SELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430
SELECT * FROM crm_configurations WHERE id = 1;
SELECT * FROM teams WHERE crm_id = 1;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
select id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1
SELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430
select * from teams where id = 852;
select * from groups where id = 2286;
select * from sidekick_settings where team_id = 852;
select * from default_activity_types where team_id = 852;
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1 AND u.deleted_at IS NULL
AND u.crm_required = 1
AND u.team_id = 1
ORDER BY u.team_id;
SELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (
18481
);
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1
AND u.deleted_at IS NULL
AND u.crm_required = 1
# AND u.team_id = 1
AND p.id IS NULL -- Move this condition to WHERE clause
ORDER BY u.team_id;
SELECT * FROM opportunities WHERE id = 20002609;
select * from teams where id = 1122; # Velatir, 29953 - [EMAIL]
select * from crm_configurations where id = 1060;
select * from crm_layouts where crm_configuration_id = 1060;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1122 and sa.provider = 'hubspot';
select * from opportunities where team_id = 1122 order by updated_at desc;
select * from crm_field_data where object_type = 'contact';
SELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 248 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS
SELECT * FROM users where id = 24115;
SELECT * FROM accounts where id = 4002896;
SELECT * FROM teams WHERE name LIKE '%adswerve%';
SELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN ("0069N000003GIQ9QAO","0061r000019yGP9AAM","0066900001S2KWlAAN","0066900001TDpj2AAD","0066900001b8uEwAAI","0069N000001rQi0QAE","006QF00000KD40mYAD","006QF00000LzpRJYAZ","0069N000002uomtQAA","0069N000002xlMLQAY","0066900001NV6ubAAD","0061r00001HJp45AAD","006QF00000uTlUoYAK","006QF00000v0bZqYAI");
SELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203
SELECT u.id, u.email, ac.name, a.* FROM activities a
JOIN users u ON a.user_id = u.id
JOIN accounts ac ON a.account_id = ac.id
WHERE
uuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or
uuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or
uuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;
select * from users where id = 5825;
SELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;
select * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;
19594, 862
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 862 and sa.provider = 'salesforce';
select * from automated_reports where id = 36;
select ar.frequency, r.*, ar.* from automated_report_results r
join automated_reports ar on r.report_id = ar.id
where ar.frequency != 'one_off';
select s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;
select * from nudges n where n.activity_search_id
select * from teams where created_at > '2026-03-09';
SELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;
select * from users where team_id = 1 and name like '%Lukas%'; # 7160
SELECT * FROM teams WHERE id = 575;
select * from opportunities where team_id = 575;
SELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,
select * from opportunities where team_id = 1126;
SELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,
select * from opportunities where team_id = 1125;
select * from contacts c
where c.team_id = 882;
SELECT * FROM activities WHERE id = 76822967;
SELECT * FROM crm_profiles WHERE user_id = 15440;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 555;
SELECT * FROM crm_configurations WHERE id = 555;
SELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 581 and sa.provider = 'salesforce';
SELECT * FROM automated_report_results order by id desc;
select * from features;
select * from team_features where feature_id = 40;
select * from teams where id = 556;
select * from automated_reports;
where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , ["pdf","podcast"]
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
select * from automated_report_results order by id desc;
SELECT * FROM automated_report_results WHERE id = 1919;
select * from automated_report_results WHERE report_id = 54;
select * from opportunities where id = 7594349;
SELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - [EMAIL]
select * from playbooks where team_id = 711; # event 226147
SELECT * FROM playbook_categories WHERE playbook_id = 5515;
SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';
SELECT * FROM crm_fields WHERE id = 226147;
SELECT * FROM crm_field_values WHERE crm_field_id = 226147;
SELECT * FROM crm_configurations WHERE id = 692;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 711 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;
select * from leads;
select * from calendars;
SELECT
t.id AS team_id,
t.name,
LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain
FROM teams t
JOIN users u ON u.team_id = t.id
JOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'
LEFT JOIN team_domains td
ON td.team_id = t.id
AND td.deleted_at IS NULL
AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))
GROUP BY t.id, t.name, calendar_domain
ORDER BY t.name, calendar_domain;
select * from users u join calendars c on c.user_id = u.id
where u.team_id = 882;
select * from activities where id = 74049485; # team 563 crm 537
select * from activities where id = 73272382; # team 563 crm 537
select * from activities where id = 64400389; # team 563 crm 537
select * from activities where id = 58081273; # team 563 crm 537
select * from activities where id = 54520297; # team 563 crm 537
select * from participants where activity_id = 58081273;
select * from activities where crm_configuration_id = 537 and provider = 'aircall'
and account_id = 19003658 order by updated_at desc;
select * from contacts where crm_configuration_id = 537 and id = 35957759;
select * from accounts where crm_configuration_id = 537 and id = 19003658;
select * from automated_report_results where id = 1976;
select * from automated_reports where id = 583;
select * from activity_searches where id = 87714;
select * from activity_search_filters where activity_search_id = 87714;
SELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid
or uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;
SELECT * FROM crm_configurations WHERE provider = 'hubspot';
select * from rate_limits;
select * from automated_report_results where media_type = 'pdf' and status = 2
and id IN (18, 1872);
select * from automated_reports where id = 54;
SELECT * FROM users WHERE id IN (24623,29443,29613);
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
32886
|
NULL
|
NULL
|
NULL
|
|
32889
|
1257
|
8
|
2026-05-13T09:44:25.411606+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665465411_m2.jpg...
|
PhpStorm
|
faVsco.js – TeamController.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
3
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\Settings\Teams;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
use Jiminny\Actions\InviteUserToTeamAction;
use Jiminny\Interactions\Settings\Teams\CreateTeam;
use Jiminny\DTO\Invitation\UserInvitationDTO;
use Jiminny\Http\Requests\Settings\Teams\CreateTeamRequest;
use Jiminny\Http\Controllers\Controller;
use Jiminny\Http\Requests\Settings\Teams\EditTeamRequest;
use Jiminny\Interactions\Settings\Teams\EditTeam;
use Jiminny\Models\Team;
use Jiminny\Models\User;
final class TeamController extends Controller
{
/**
* Create a new team, subscription and invitation.
*/
public function store(
CreateTeamRequest $request,
CreateTeam $createTeam,
InviteUserToTeamAction $inviteUserToTeamAction,
): void {
/** @var User $teamCreator */
$teamCreator = $request->user();
try {
$data = $request->all();
$team = $createTeam->handle($teamCreator, $data, $request->getDomain());
$inviteUserToTeamAction->execute(UserInvitationDTO::forOwner($request, $team));
} catch (\Exception $exception) {
Log::error('An error occurred while creating team', [
'e_message' => $exception->getMessage(),
'e_code' => $exception->getCode(),
]);
throw $exception;
}
}
public function edit(
Team $team,
EditTeamRequest $request,
EditTeam $editTeam,
): JsonResponse {
/** @var User $teamEditor */
$teamEditor = $request->user();
$editTeam->handle($team, $teamEditor, $request->all(), $request);
return response()->json([], JsonResponse::HTTP_OK);
}
}
Execute
Explain Plan
Browse Query History
View Parameters...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.034242023,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"3","depth":4,"bounds":{"left":0.38397607,"top":0.07581804,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.39361703,"top":0.074221864,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.40093085,"top":0.074221864,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Http\\Controllers\\Settings\\Teams;\n\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Actions\\InviteUserToTeamAction;\nuse Jiminny\\Interactions\\Settings\\Teams\\CreateTeam;\nuse Jiminny\\DTO\\Invitation\\UserInvitationDTO;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\CreateTeamRequest;\nuse Jiminny\\Http\\Controllers\\Controller;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\EditTeamRequest;\nuse Jiminny\\Interactions\\Settings\\Teams\\EditTeam;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\n\nfinal class TeamController extends Controller\n{\n /**\n * Create a new team, subscription and invitation.\n */\n public function store(\n CreateTeamRequest $request,\n CreateTeam $createTeam,\n InviteUserToTeamAction $inviteUserToTeamAction,\n ): void {\n /** @var User $teamCreator */\n $teamCreator = $request->user();\n\n try {\n $data = $request->all();\n $team = $createTeam->handle($teamCreator, $data, $request->getDomain());\n\n $inviteUserToTeamAction->execute(UserInvitationDTO::forOwner($request, $team));\n } catch (\\Exception $exception) {\n Log::error('An error occurred while creating team', [\n 'e_message' => $exception->getMessage(),\n 'e_code' => $exception->getCode(),\n ]);\n\n throw $exception;\n }\n }\n\n public function edit(\n Team $team,\n EditTeamRequest $request,\n EditTeam $editTeam,\n ): JsonResponse {\n /** @var User $teamEditor */\n $teamEditor = $request->user();\n $editTeam->handle($team, $teamEditor, $request->all(), $request);\n\n return response()->json([], JsonResponse::HTTP_OK);\n }\n}","depth":4,"bounds":{"left":0.11968085,"top":0.0726257,"width":0.28823137,"height":0.9066241},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Http\\Controllers\\Settings\\Teams;\n\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Actions\\InviteUserToTeamAction;\nuse Jiminny\\Interactions\\Settings\\Teams\\CreateTeam;\nuse Jiminny\\DTO\\Invitation\\UserInvitationDTO;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\CreateTeamRequest;\nuse Jiminny\\Http\\Controllers\\Controller;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\EditTeamRequest;\nuse Jiminny\\Interactions\\Settings\\Teams\\EditTeam;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\n\nfinal class TeamController extends Controller\n{\n /**\n * Create a new team, subscription and invitation.\n */\n public function store(\n CreateTeamRequest $request,\n CreateTeam $createTeam,\n InviteUserToTeamAction $inviteUserToTeamAction,\n ): void {\n /** @var User $teamCreator */\n $teamCreator = $request->user();\n\n try {\n $data = $request->all();\n $team = $createTeam->handle($teamCreator, $data, $request->getDomain());\n\n $inviteUserToTeamAction->execute(UserInvitationDTO::forOwner($request, $team));\n } catch (\\Exception $exception) {\n Log::error('An error occurred while creating team', [\n 'e_message' => $exception->getMessage(),\n 'e_code' => $exception->getCode(),\n ]);\n\n throw $exception;\n }\n }\n\n public function edit(\n Team $team,\n EditTeamRequest $request,\n EditTeam $editTeam,\n ): JsonResponse {\n /** @var User $teamEditor */\n $teamEditor = $request->user();\n $editTeam->handle($team, $teamEditor, $request->all(), $request);\n\n return response()->json([], JsonResponse::HTTP_OK);\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.40957448,"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.41821808,"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.42918882,"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.43783244,"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}]...
|
-8871750741734446825
|
-8974528256362210879
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
3
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\Settings\Teams;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
use Jiminny\Actions\InviteUserToTeamAction;
use Jiminny\Interactions\Settings\Teams\CreateTeam;
use Jiminny\DTO\Invitation\UserInvitationDTO;
use Jiminny\Http\Requests\Settings\Teams\CreateTeamRequest;
use Jiminny\Http\Controllers\Controller;
use Jiminny\Http\Requests\Settings\Teams\EditTeamRequest;
use Jiminny\Interactions\Settings\Teams\EditTeam;
use Jiminny\Models\Team;
use Jiminny\Models\User;
final class TeamController extends Controller
{
/**
* Create a new team, subscription and invitation.
*/
public function store(
CreateTeamRequest $request,
CreateTeam $createTeam,
InviteUserToTeamAction $inviteUserToTeamAction,
): void {
/** @var User $teamCreator */
$teamCreator = $request->user();
try {
$data = $request->all();
$team = $createTeam->handle($teamCreator, $data, $request->getDomain());
$inviteUserToTeamAction->execute(UserInvitationDTO::forOwner($request, $team));
} catch (\Exception $exception) {
Log::error('An error occurred while creating team', [
'e_message' => $exception->getMessage(),
'e_code' => $exception->getCode(),
]);
throw $exception;
}
}
public function edit(
Team $team,
EditTeamRequest $request,
EditTeam $editTeam,
): JsonResponse {
/** @var User $teamEditor */
$teamEditor = $request->user();
$editTeam->handle($team, $teamEditor, $request->all(), $request);
return response()->json([], JsonResponse::HTTP_OK);
}
}
Execute
Explain Plan
Browse Query History
View Parameters...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
32890
|
1256
|
12
|
2026-05-13T09:44:26.420446+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665466420_m1.jpg...
|
PhpStorm
|
faVsco.js – TeamController.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
3
Previous Highlighted Error
Next Highlighted Error...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"3","depth":4,"on_screen":true,"role_description":"text"},{"role":"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}]...
|
8826781061786667221
|
-8168387148547380286
|
click
|
hybrid
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
3
Previous Highlighted Error
Next Highlighted Error
SlackFileEdit ViewGoHistoryWindowHelpAPPDOCKER• ₴1DEV (docker)₴82APP (-zshtests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleterTest.phptests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesProviderTest.phptests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesUploaderTest.phptests/Unit/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeeches?tests/Unit/Component/Transcription/Diarization/Source/MeetingBotSourceTest.phptests/Unit/Contracts/Services/Calendar/CalendarTraitTest.phptests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.phptests/Unit/Jobs/Activity/Import/ImportTwilioVideoSpeechesJobTest.phptests/Unit/Jobs/Activity/Import/IsActivityReadyForProcessingJobTest.phptests/Unit/Jobs/Calendar/SetupCalendarSyncTest.phptests/Unit/Services/Activity/ParticipantsServiceTest.phptests/Unit/Services/Calendar/Command/ImportParticipantsTest.phptests/Unit/Services/Calendar/GoogleCalendarServiceTest.phptests/Unit/Services/Crm/Close/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTest.phptests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTraitMatchActivitiesTest.phytests/Unit/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTraitOpportunitiesTe:tests/Unit/Services/Crm/Pipedrive/ImportOpportunityMatchActivitiesTest.phptests/Unit/Services/Crm/Salesforce/ServiceTest.phptests/Unit/Services/Mail/0ffice/EmailApiClientTest.phptests/Unit/Services/RecallAI/RecallAIServiceTest.php113 files changed, 4143 insertions(+), 1740 deletions(-)create mode 120000 CLAUDE.mdcreate mode 100644 app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.phpdelete mode 100644 app/Component/ES/ElasticSearchWorkerManager.phpdelete mode 100644 app/Component/ES/Worker/ActivityWorker.phpdelete mode 100644 app/Component/ES/Worker/EntityWorker.phpdelete mode100644 app/Component/ES/Worker/WorkerAmount.phpdelete mode100644 app/Component/ES/Worker/WorkerInterface.phpcreate mode100644 app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.phtcreate mode100644 app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/Assembl:create mode100644 app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNot(create mode 100644 app/Console/Commands/Crm/Backfill0pportunityUserFromAccountCommand.phpdelete mode 100644 app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.phpcreate mode100644 front-end/src/components/shared/modals/EntityPickerModal/__tests__/us‹create mode 100644 tests/Feature/Component/Nudge/Process0rganisationImmediateNudgesJobTe:create mode 100644 tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheck‹delete mode 100644 tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/ActivityWorkerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/EntityWorkerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/WorkerAmountTest.phpcreate mode 100644 tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCr‹create mode 100644 tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.phpLukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ I|HomeDMsActivityFilesLaterMore(aol§ Support Daily - in 2h 16 m100% <78•Wed 13 May12:44:25ED-→Describe what you are looking forJiminny ...curoaroylau# engineering# general# jiminny-bg# platform-tickets# product_launches#random# releases# sofia-office# support# thank-yous# the_people_of jimi...° Direct messages& Nikolay Ivanovdo James Graham. Stoyan Tanev. Galya DimitrovaP. Steliyan Georgievo Petko Kashinski®. Aneliya Angelovaã. Stefka Stoyanova•. Vasil Vasilev •!Lukas Kovalik y...l:: AppsJira CloudToastNikolay Ivanov6 0MessagesAdd canvas@ Files+Lukas Kovalik 11.Today ~мен все ме праща наhttps://app.vanta.com/c/jiminny.com/employee/onboardingNikolay Ivanov 11:01 AMХм, Джейс дали не може да ти помогне?Lukas Kovalik 11:01 AMще питам James, предполагам че нямам правада мерсиNikolay Ivanov 11:01 AMмдаМОЛЯLukas Kovalik 12:13 PMНики сори, още един въпрос имамкогато ги правеше ти FE ли оправяима vulnerabilities no npmNikolay Ivanov 12:28 PMнетях ги оставямLukas Kovalik 12:29 PMаз погледнах твоя тикет и там друго нямашесамо FEкак стигна до WorkerMessage Nikolay Ivanov...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
32891
|
1257
|
9
|
2026-05-13T09:44:26.379876+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665466379_m2.jpg...
|
PhpStorm
|
faVsco.js – TeamController.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.034242023,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
5252240045865077800
|
-8204424741936591930
|
click
|
hybrid
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
PhostormINavigarecodeLaravelKeractorJOOISFV faVsco.js°9 master ~ProiectC CreateTeam.pnpYC) IntecrationContr(C) InvitationControYC) OraanizationSet(c) ToamActivitveno reamcoacningsnanespace Jiminny hutp concroulers seutingsleansO leamconterene© TeamController.› use ...C) leamDealinsigh 18© TeamDomainsC( 19tinal class Teamcontroller extends controllen© TeamMemberCc 21© TeamPhotoCont 21C) leamkecording: 22© TeamSettingsCc 23* Create a new team. subscription and invitation.c) leamsorphoneposTaoivlsettinas/oraanizationslkiosk.oraanizations.storel> D Users124109oublic function storedC) DashboardControlle 25CreateTeamRequest Srequest,c) GroupController.ohi 2.CreateTeam Screateteam.C) JobTitleController.r 279 MomentController.r 29InvitelserToTeamAction SinvitelsertoteamAction.l): void 1...}c) PlavbookcatedorvdLAC) PlavbookControlleDUT lanilv1/kiockloroanizations/{team) fkiock oraanizations editil> M Telenhonvnuhlic function edi+d• N WebhookToam Steam.• M HubsootFditTeamPenuest Snequest• M IntecrationAooSubs salEditTeam SeditTeam,(C) ActivitvDroviderCor 51): JsonResponse {...}(C) ActivitvTranccrintio 5o© BaseController.php 59€ CalendarController.(C) PenortController nh9a) SoftnhoneWehhonlAbstractController.ong© CommentContextinter(e) ConforonsocOntinOut© Controller.php4) SynortController.php© FrontendController.ph( FrontendControllerTraGeocodinaController.rC) HealthCheckController@ LiveCoachController.p© MissinaTeamControlleC) MobileController.oho(C) NotificationController.(C) NotificationProviderCd@ PlavbackController.oh@ PlavlistController.ohp(c) PucherControlier ohnYc) SlackController nhn8) SunnortController nhn(C) TeamSetunController= custom.log|aravel.l0gA SF (jiminny@localhost]4 HS_local [jiminny@localhost]« console (PROD] X 4 console [EU]A console [STAGING]587588589596— 597594596606Tx: AutovCONCAT(u.id, CASE WHEN U.id = t.owner_id THEN ' (owner)' ELSE"' END) AS user_id,sa.*t.owner_id FROM social_accounts saNolN usens u on u.id e sa.sociablle i.diJOIN teams t .n<->l: on t.id = u.team_icWHERE u.team_id = 581 and sa.provider = 'salesforce';SELECT * FROM automated_report_results order by id desc;select * from features;select * from team_features where feature_id = 40;select * from teams where id = 556:select * from automated_reports:where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044,["pdf" "podcast"]SELECT * FROM automated report_ results WHERE uuid to bin( '822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;select * from automated_report_results order by za desc;sclzu * Frur automated revort resulrsWHERE id = 1919select * from automated report results WHERE report id = 54:select * from opportunities where 1d = 7594549ªSELE * FROM teams WHERE name LIKE "%Les%': # 711, 692. 16067 - Timinnvintearationdlesmils.comselect * from playbooks where team id = 711; # event 226147SELEd * FROM Davbook catedonies WHERE Dlavbook 10 e 55151SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type =SELECT * EROM eom fields WHERE 1d = 226147-1SELECT * EROM eom field values WHERE com field 1d = 226147.SELECT * FROM crm_configurations WHERE id = 692;SEISCTCONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE "' END) AS user_id,nemailSa.xt.owner id FROM social accounts saJOIN users u on u.id = sa.sociable idJOIN teams t 1..n<->1: on t.id = u.team_idWHERE U.team id = 711 and sa.provider = 'salesforce':SELECT * FROM crm profiles co JOIN users u 1..n<->1: on u.id = co.user id WHERE u.team_id = 711:select * from leads:select * from calendars:SELECTSo jiminny040 A1 A40 V 64 ^S0 hlsuppont Dally • In Zn 10m100% S2• Wed 13 May 12:44:26AskJiminnyReportActivityServiceTest -CascadeTrial Owner Role Selec+0 ..Read kegistercontroller.php ana OnboardController.pnp ›Searched UserRegistered invitation. accept in ~/iminnyappThought for 3s ›Read UpdateProtile.phg0// tasks done ?• Review current role assianment when owner sians in7 Document findinas and provide imolementation olanInoughttor 4s7 7 tasks done)lhought for 4sCurrent Flow Analvsis: Owner Role Assianment in Trial CreationBackend Flow1. Team Creation Entrv Point• TeamController::store() (lines 24-45)Calls CreateTeam interaction to create the team• Calls InviteUserToTeamAction with UserInvitationDTO: : for0wner(Srequest, Steam)2. Owner Role Assianment (HARDCODED)• UserInvitationDTO:: for0wner() (lines 52-72 in/app/DTO/Invitation/UserInvitationDT0.php)•Lines 54-57: This is where the owner's role is hardcodediohrUser:: ROLE RECORDER,→>oluck("id')→>toArravo:•Alwavs assians ROLE ADMIN + ROLE RECORDER to the ownenThic ic the koy ioention that noode modification3. Invitation Creatior•InviteUserToTeamAction::execute@ (lines 28-81)• Creates an Invitation with roles from the DTO (line 45: Sinvitation->roles()->sync(Sdto->roleIds))• Sends OwnerInvitedToTrial notificationl1 Owner Sian-in FlowOwner receives email invitation• Regrstercontroller:: showRegnstratonformo shows registration form with invitation dataOwner redisters and accents invitationRoles are already assigned via the invitation, so owner gets ROLE ADMIN + ROLE RECORDER automaticallvFrontend FlowAsk anvthina (84-D)« Code SWF-1.6O0 1WN Windsurf Teams27•56 UTE.8io 4 spaces...
|
32889
|
NULL
|
NULL
|
NULL
|
|
32892
|
1256
|
13
|
2026-05-13T09:44:28.968322+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665468968_m1.jpg...
|
PhpStorm
|
faVsco.js – TeamController.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
3
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\Settings\Teams;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
use Jiminny\Actions\InviteUserToTeamAction;
use Jiminny\Interactions\Settings\Teams\CreateTeam;
use Jiminny\DTO\Invitation\UserInvitationDTO;
use Jiminny\Http\Requests\Settings\Teams\CreateTeamRequest;
use Jiminny\Http\Controllers\Controller;
use Jiminny\Http\Requests\Settings\Teams\EditTeamRequest;
use Jiminny\Interactions\Settings\Teams\EditTeam;
use Jiminny\Models\Team;
use Jiminny\Models\User;
final class TeamController extends Controller
{
/**
* Create a new team, subscription and invitation.
*/
public function store(
CreateTeamRequest $request,
CreateTeam $createTeam,
InviteUserToTeamAction $inviteUserToTeamAction,
): void {
/** @var User $teamCreator */
$teamCreator = $request->user();
try {
$data = $request->all();
$team = $createTeam->handle($teamCreator, $data, $request->getDomain());
$inviteUserToTeamAction->execute(UserInvitationDTO::forOwner($request, $team));
} catch (\Exception $exception) {
Log::error('An error occurred while creating team', [
'e_message' => $exception->getMessage(),
'e_code' => $exception->getCode(),
]);
throw $exception;
}
}
public function edit(
Team $team,
EditTeamRequest $request,
EditTeam $editTeam,
): JsonResponse {
/** @var User $teamEditor */
$teamEditor = $request->user();
$editTeam->handle($team, $teamEditor, $request->all(), $request);
return response()->json([], JsonResponse::HTTP_OK);
}
}
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
40
1
40
64
Previous Highlighted Error
Next Highlighted Error
SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993
SELECT * FROM users WHERE id = 25061;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 994;
SELECT * FROM crm_profiles WHERE user_id = 25061;
select * from crm_configurations where id = 834;
SELECT * FROM teams WHERE id = 882;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;
SELECT * FROM contacts where crm_configuration_id = 834;
SELECT * FROM opportunities WHERE team_id = 933
# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');
AND id IN (8482561,18352941,19042734,19232139,19445140,19472541);
SELECT * FROM opportunity_contacts
WHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 485; #
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
select crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id
where crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')
# and l.converted_at IS NOT NULL
;
# [PASSWORD_DOTS]
SELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')
and opportunity_id IS NULL
order by id desc;
SELECT * FROM teams WHERE id = 604; # 598
SELECT * FROM activities WHERE id = 74410828; # [EMAIL]
SELECT * FROM accounts WHERE id = 20068382;
SELECT * FROM accounts WHERE id = 35186038;
SELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 559 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;
select * from sidekick_settings where team_id = 781;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100
SELECT * FROM crm_layouts WHERE crm_configuration_id = 711;
SELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL
and is_internal = 0 and status = 'completed'
order by id desc;
SELECT * FROM crm_layout_entities
WHERE crm_layout_id IN (2352, 2353);
;
SELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 556 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;
SELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;
select * from contacts
where crm_configuration_id = 530
and crm_provider_id = 872252;
select * from activities where crm_configuration_id = 530
and user_id = 14343 and type like '%softphone%'
and created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);
SELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t
JOIN crm_configurations c ON t.id = c.team_id
WHERE t.status = 'active';
SELECT * FROM teams where id = 1091;
SELECT * FROM crm_configurations where team_id = 1091;
SELECT * FROM activity_providers where team_id = 1091;
SELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT * FROM teams WHERE name LIKE '%Leadventure%';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1091 and sa.provider = 'salesforce';
SELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812
SELECT * FROM teams where id = 862;
SELECT * FROM crm_configurations where team_id = 862;
SELECT * FROM activity_providers where team_id = 862;
SELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT t.id, crm.id, crm.provider, ap.* FROM teams t
join crm_configurations crm on t.id = crm.team_id
join activity_providers ap on t.id = ap.team_id
where t.status = 'active' and ap.is_enabled = 1
and crm.provider = 'hubspot'
and ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',
'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');
SELECT * FROM teams where id = 1068;
SELECT * FROM crm_configurations where team_id = 1068;
SELECT * FROM activity_providers where team_id = 1068;
SELECT * FROM activities a
where crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')
and a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'
)
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by a.id desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1068 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262
SELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
select * from crm_layouts where crm_configuration_id = 834;
select * from crm_layout_entities where crm_layout_id = 2780;
select * from crm_fields where id IN (321153,321192,321193,321194);
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1057 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8
SELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20
SELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10
SELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #
SELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;
select * from users where team_id = 51; # 7783
SELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130
select * from activity_searches where user_id = 7783;
select * from activity_search_filters where activity_search_id IN (32291, 32292);
SELECT asf.activity_search_id, asf.id, asf.value
FROM activity_search_filters asf
WHERE asf.filter = 'group_id'
AND asf.value IN (
SELECT CONCAT(
HEX(SUBSTR(uuid, 5, 4)), '-',
HEX(SUBSTR(uuid, 3, 2)), '-',
HEX(SUBSTR(uuid, 1, 2)), '-',
HEX(SUBSTR(uuid, 9, 2)), '-',
HEX(SUBSTR(uuid, 11))
)
FROM groups
WHERE deleted_at IS NOT NULL
);
SELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where provider = 'hubspot';
SELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133
SELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null
# [PASSWORD_DOTS]
select * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';
select
cp.*
# DISTINCT t.id
# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields
FROM crm_profiles cp
JOIN crm_configurations crm on crm.id = cp.crm_configuration_id
JOIN users u on u.id = cp.user_id
JOIN teams t ON t.id = crm.team_id
WHERE crm.provider = 'salesforce' and t.status = 'active'
and cp.archived_at IS NULL and u.deleted_at IS NULL
and t.id NOT IN (1093)
and t.id = 2
and cp.contact_fields IS NULL;
# and c.crm_provider_id = '003Uu00000ojD4NIAU';
SELECT * FROM users WHERE id = 26484;
SELECT * FROM crm_profiles WHERE user_id = 26484;
SELECT * FROM social_accounts WHERE sociable_id = 26484;
SELECT * FROM crm_configurations where provider = 'salesforce';
select * from users where id IN (10022, 10403);
select * from users where team_id IN (526);
select * from teams where id IN (526, 532);
select * from crm_configurations where id IN (500, 516);
select * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);
select * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 526 and sa.provider = 'salesforce';
select * from team_settings where team_id IN (526, 532);
select * from users where id IN (22824);
select * from crm_profiles where crm_configuration_id IN (1026);
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1093 and sa.provider = 'salesforce';
select * from teams where id = 1099;
select * from users where id = 29643
select * from activity_processing_states;
SELECT * FROM teams where name LIKE '%Fare%'; # 233
SELECT * FROM opportunities where crm_configuration_id = 215
# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'
;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1088 and sa.provider = 'hubspot';
SELECT * FROM teams order by updated_at DESC
SELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account
select * from crm_configurations where provider = 'pipedrive';
select * from teams where id = 957;
select * from crm_configurations where id = 957;
SELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743
SELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;
select * from users where team_id = 1; # 26726 - Gabriela Dureva
SELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific
select * from activities where user_id = 26726 order by id desc;
select * from contacts where crm_configuration_id = 1
and email IN ('[EMAIL]', '[EMAIL]'); # 2094416, 2093620
SELECT * FROM contacts WHERE id = 6284931;
SELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id
WHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;
select * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);
select * from crm_configurations where id = 1;
43801692-1aeb-32ce-acba-5b80a479701a
44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b
405975c0-b3d0-7aaa-821f-09d59cae6dd1
4caf848d-4bed-2299-b248-7788d41f9fca
49bedc3f-f196-eef3-89c3-dea6a3b4aa63
43420989-a09d-b8f8-9806-c8bbf7a02aac
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
SELECT * FROM activities WHERE id = 75461988;
SELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;
select * from contacts where id = 17900517;
select * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id
where crm.provider != 'salesforce';
select * from users where id = 21047;
SELECT * FROM crm_configurations WHERE id = 892;
SELECT * FROM teams WHERE id = 942;
select * from opportunities where team_id = 942 order by updated_at desc;
select * from contacts where team_id = 942 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 942 and sa.provider = 'hubspot';
SELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430
SELECT * FROM crm_configurations WHERE id = 1;
SELECT * FROM teams WHERE crm_id = 1;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
select id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1
SELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430
select * from teams where id = 852;
select * from groups where id = 2286;
select * from sidekick_settings where team_id = 852;
select * from default_activity_types where team_id = 852;
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1 AND u.deleted_at IS NULL
AND u.crm_required = 1
AND u.team_id = 1
ORDER BY u.team_id;
SELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (
18481
);
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1
AND u.deleted_at IS NULL
AND u.crm_required = 1
# AND u.team_id = 1
AND p.id IS NULL -- Move this condition to WHERE clause
ORDER BY u.team_id;
SELECT * FROM opportunities WHERE id = 20002609;
select * from teams where id = 1122; # Velatir, 29953 - [EMAIL]
select * from crm_configurations where id = 1060;
select * from crm_layouts where crm_configuration_id = 1060;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1122 and sa.provider = 'hubspot';
select * from opportunities where team_id = 1122 order by updated_at desc;
select * from crm_field_data where object_type = 'contact';
SELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 248 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS
SELECT * FROM users where id = 24115;
SELECT * FROM accounts where id = 4002896;
SELECT * FROM teams WHERE name LIKE '%adswerve%';
SELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN ("0069N000003GIQ9QAO","0061r000019yGP9AAM","0066900001S2KWlAAN","0066900001TDpj2AAD","0066900001b8uEwAAI","0069N000001rQi0QAE","006QF00000KD40mYAD","006QF00000LzpRJYAZ","0069N000002uomtQAA","0069N000002xlMLQAY","0066900001NV6ubAAD","0061r00001HJp45AAD","006QF00000uTlUoYAK","006QF00000v0bZqYAI");
SELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203
SELECT u.id, u.email, ac.name, a.* FROM activities a
JOIN users u ON a.user_id = u.id
JOIN accounts ac ON a.account_id = ac.id
WHERE
uuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or
uuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or
uuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;
select * from users where id = 5825;
SELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;
select * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;
19594, 862
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 862 and sa.provider = 'salesforce';
select * from automated_reports where id = 36;
select ar.frequency, r.*, ar.* from automated_report_results r
join automated_reports ar on r.report_id = ar.id
where ar.frequency != 'one_off';
select s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;
select * from nudges n where n.activity_search_id
select * from teams where created_at > '2026-03-09';
SELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;
select * from users where team_id = 1 and name like '%Lukas%'; # 7160
SELECT * FROM teams WHERE id = 575;
select * from opportunities where team_id = 575;
SELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,
select * from opportunities where team_id = 1126;
SELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,
select * from opportunities where team_id = 1125;
select * from contacts c
where c.team_id = 882;
SELECT * FROM activities WHERE id = 76822967;
SELECT * FROM crm_profiles WHERE user_id = 15440;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 555;
SELECT * FROM crm_configurations WHERE id = 555;
SELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 581 and sa.provider = 'salesforce';
SELECT * FROM automated_report_results order by id desc;
select * from features;
select * from team_features where feature_id = 40;
select * from teams where id = 556;
select * from automated_reports;
where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , ["pdf","podcast"]
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
select * from automated_report_results order by id desc;
SELECT * FROM automated_report_results WHERE id = 1919;
select * from automated_report_results WHERE report_id = 54;
select * from opportunities where id = 7594349;
SELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - [EMAIL]
select * from playbooks where team_id = 711; # event 226147
SELECT * FROM playbook_categories WHERE playbook_id = 5515;
SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';
SELECT * FROM crm_fields WHERE id = 226147;
SELECT * FROM crm_field_values WHERE crm_field_id = 226147;
SELECT * FROM crm_configurations WHERE id = 692;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 711 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;
select * from leads;
select * from calendars;
SELECT
t.id AS team_id,
t.name,
LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain
FROM teams t
JOIN users u ON u.team_id = t.id
JOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'
LEFT JOIN team_domains td
ON td.team_id = t.id
AND td.deleted_at IS NULL
AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))
GROUP BY t.id, t.name, calendar_domain
ORDER BY t.name, calendar_domain;
select * from users u join calendars c on c.user_id = u.id
where u.team_id = 882;
select * from activities where id = 74049485; # team 563 crm 537
select * from activities where id = 73272382; # team 563 crm 537
select * from activities where id = 64400389; # team 563 crm 537
select * from activities where id = 58081273; # team 563 crm 537
select * from activities where id = 54520297; # team 563 crm 537
select * from participants where activity_id = 58081273;
select * from activities where crm_configuration_id = 537 and provider = 'aircall'
and account_id = 19003658 order by updated_at desc;
select * from contacts where crm_configuration_id = 537 and id = 35957759;
select * from accounts where crm_configuration_id = 537 and id = 19003658;
select * from automated_report_results where id = 1976;
select * from automated_reports where id = 583;
select * from activity_searches where id = 87714;
select * from activity_search_filters where activity_search_id = 87714;
SELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid
or uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;
SELECT * FROM crm_configurations WHERE provider = 'hubspot';
select * from rate_limits;
select * from automated_report_results where media_type = 'pdf' and status = 2
and id IN (18, 1872);
select * from automated_reports where id = 54;
SELECT * FROM users WHERE id IN (24623,29443,29613);
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"3","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Http\\Controllers\\Settings\\Teams;\n\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Actions\\InviteUserToTeamAction;\nuse Jiminny\\Interactions\\Settings\\Teams\\CreateTeam;\nuse Jiminny\\DTO\\Invitation\\UserInvitationDTO;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\CreateTeamRequest;\nuse Jiminny\\Http\\Controllers\\Controller;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\EditTeamRequest;\nuse Jiminny\\Interactions\\Settings\\Teams\\EditTeam;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\n\nfinal class TeamController extends Controller\n{\n /**\n * Create a new team, subscription and invitation.\n */\n public function store(\n CreateTeamRequest $request,\n CreateTeam $createTeam,\n InviteUserToTeamAction $inviteUserToTeamAction,\n ): void {\n /** @var User $teamCreator */\n $teamCreator = $request->user();\n\n try {\n $data = $request->all();\n $team = $createTeam->handle($teamCreator, $data, $request->getDomain());\n\n $inviteUserToTeamAction->execute(UserInvitationDTO::forOwner($request, $team));\n } catch (\\Exception $exception) {\n Log::error('An error occurred while creating team', [\n 'e_message' => $exception->getMessage(),\n 'e_code' => $exception->getCode(),\n ]);\n\n throw $exception;\n }\n }\n\n public function edit(\n Team $team,\n EditTeamRequest $request,\n EditTeam $editTeam,\n ): JsonResponse {\n /** @var User $teamEditor */\n $teamEditor = $request->user();\n $editTeam->handle($team, $teamEditor, $request->all(), $request);\n\n return response()->json([], JsonResponse::HTTP_OK);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Http\\Controllers\\Settings\\Teams;\n\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Actions\\InviteUserToTeamAction;\nuse Jiminny\\Interactions\\Settings\\Teams\\CreateTeam;\nuse Jiminny\\DTO\\Invitation\\UserInvitationDTO;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\CreateTeamRequest;\nuse Jiminny\\Http\\Controllers\\Controller;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\EditTeamRequest;\nuse Jiminny\\Interactions\\Settings\\Teams\\EditTeam;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\n\nfinal class TeamController extends Controller\n{\n /**\n * Create a new team, subscription and invitation.\n */\n public function store(\n CreateTeamRequest $request,\n CreateTeam $createTeam,\n InviteUserToTeamAction $inviteUserToTeamAction,\n ): void {\n /** @var User $teamCreator */\n $teamCreator = $request->user();\n\n try {\n $data = $request->all();\n $team = $createTeam->handle($teamCreator, $data, $request->getDomain());\n\n $inviteUserToTeamAction->execute(UserInvitationDTO::forOwner($request, $team));\n } catch (\\Exception $exception) {\n Log::error('An error occurred while creating team', [\n 'e_message' => $exception->getMessage(),\n 'e_code' => $exception->getCode(),\n ]);\n\n throw $exception;\n }\n }\n\n public function edit(\n Team $team,\n EditTeamRequest $request,\n EditTeam $editTeam,\n ): JsonResponse {\n /** @var User $teamEditor */\n $teamEditor = $request->user();\n $editTeam->handle($team, $teamEditor, $request->all(), $request);\n\n return response()->json([], JsonResponse::HTTP_OK);\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":"40","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"40","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"64","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","depth":4,"on_screen":true,"value":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","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}]...
|
7072317158041286516
|
1065678670634825285
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
3
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\Settings\Teams;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
use Jiminny\Actions\InviteUserToTeamAction;
use Jiminny\Interactions\Settings\Teams\CreateTeam;
use Jiminny\DTO\Invitation\UserInvitationDTO;
use Jiminny\Http\Requests\Settings\Teams\CreateTeamRequest;
use Jiminny\Http\Controllers\Controller;
use Jiminny\Http\Requests\Settings\Teams\EditTeamRequest;
use Jiminny\Interactions\Settings\Teams\EditTeam;
use Jiminny\Models\Team;
use Jiminny\Models\User;
final class TeamController extends Controller
{
/**
* Create a new team, subscription and invitation.
*/
public function store(
CreateTeamRequest $request,
CreateTeam $createTeam,
InviteUserToTeamAction $inviteUserToTeamAction,
): void {
/** @var User $teamCreator */
$teamCreator = $request->user();
try {
$data = $request->all();
$team = $createTeam->handle($teamCreator, $data, $request->getDomain());
$inviteUserToTeamAction->execute(UserInvitationDTO::forOwner($request, $team));
} catch (\Exception $exception) {
Log::error('An error occurred while creating team', [
'e_message' => $exception->getMessage(),
'e_code' => $exception->getCode(),
]);
throw $exception;
}
}
public function edit(
Team $team,
EditTeamRequest $request,
EditTeam $editTeam,
): JsonResponse {
/** @var User $teamEditor */
$teamEditor = $request->user();
$editTeam->handle($team, $teamEditor, $request->all(), $request);
return response()->json([], JsonResponse::HTTP_OK);
}
}
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
40
1
40
64
Previous Highlighted Error
Next Highlighted Error
SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993
SELECT * FROM users WHERE id = 25061;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 994;
SELECT * FROM crm_profiles WHERE user_id = 25061;
select * from crm_configurations where id = 834;
SELECT * FROM teams WHERE id = 882;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;
SELECT * FROM contacts where crm_configuration_id = 834;
SELECT * FROM opportunities WHERE team_id = 933
# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');
AND id IN (8482561,18352941,19042734,19232139,19445140,19472541);
SELECT * FROM opportunity_contacts
WHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 485; #
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
select crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id
where crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')
# and l.converted_at IS NOT NULL
;
# [PASSWORD_DOTS]
SELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')
and opportunity_id IS NULL
order by id desc;
SELECT * FROM teams WHERE id = 604; # 598
SELECT * FROM activities WHERE id = 74410828; # [EMAIL]
SELECT * FROM accounts WHERE id = 20068382;
SELECT * FROM accounts WHERE id = 35186038;
SELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 559 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;
select * from sidekick_settings where team_id = 781;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100
SELECT * FROM crm_layouts WHERE crm_configuration_id = 711;
SELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL
and is_internal = 0 and status = 'completed'
order by id desc;
SELECT * FROM crm_layout_entities
WHERE crm_layout_id IN (2352, 2353);
;
SELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 556 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;
SELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;
select * from contacts
where crm_configuration_id = 530
and crm_provider_id = 872252;
select * from activities where crm_configuration_id = 530
and user_id = 14343 and type like '%softphone%'
and created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);
SELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t
JOIN crm_configurations c ON t.id = c.team_id
WHERE t.status = 'active';
SELECT * FROM teams where id = 1091;
SELECT * FROM crm_configurations where team_id = 1091;
SELECT * FROM activity_providers where team_id = 1091;
SELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT * FROM teams WHERE name LIKE '%Leadventure%';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1091 and sa.provider = 'salesforce';
SELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812
SELECT * FROM teams where id = 862;
SELECT * FROM crm_configurations where team_id = 862;
SELECT * FROM activity_providers where team_id = 862;
SELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT t.id, crm.id, crm.provider, ap.* FROM teams t
join crm_configurations crm on t.id = crm.team_id
join activity_providers ap on t.id = ap.team_id
where t.status = 'active' and ap.is_enabled = 1
and crm.provider = 'hubspot'
and ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',
'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');
SELECT * FROM teams where id = 1068;
SELECT * FROM crm_configurations where team_id = 1068;
SELECT * FROM activity_providers where team_id = 1068;
SELECT * FROM activities a
where crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')
and a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'
)
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by a.id desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1068 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262
SELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
select * from crm_layouts where crm_configuration_id = 834;
select * from crm_layout_entities where crm_layout_id = 2780;
select * from crm_fields where id IN (321153,321192,321193,321194);
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1057 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8
SELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20
SELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10
SELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #
SELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;
select * from users where team_id = 51; # 7783
SELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130
select * from activity_searches where user_id = 7783;
select * from activity_search_filters where activity_search_id IN (32291, 32292);
SELECT asf.activity_search_id, asf.id, asf.value
FROM activity_search_filters asf
WHERE asf.filter = 'group_id'
AND asf.value IN (
SELECT CONCAT(
HEX(SUBSTR(uuid, 5, 4)), '-',
HEX(SUBSTR(uuid, 3, 2)), '-',
HEX(SUBSTR(uuid, 1, 2)), '-',
HEX(SUBSTR(uuid, 9, 2)), '-',
HEX(SUBSTR(uuid, 11))
)
FROM groups
WHERE deleted_at IS NOT NULL
);
SELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where provider = 'hubspot';
SELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133
SELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null
# [PASSWORD_DOTS]
select * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';
select
cp.*
# DISTINCT t.id
# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields
FROM crm_profiles cp
JOIN crm_configurations crm on crm.id = cp.crm_configuration_id
JOIN users u on u.id = cp.user_id
JOIN teams t ON t.id = crm.team_id
WHERE crm.provider = 'salesforce' and t.status = 'active'
and cp.archived_at IS NULL and u.deleted_at IS NULL
and t.id NOT IN (1093)
and t.id = 2
and cp.contact_fields IS NULL;
# and c.crm_provider_id = '003Uu00000ojD4NIAU';
SELECT * FROM users WHERE id = 26484;
SELECT * FROM crm_profiles WHERE user_id = 26484;
SELECT * FROM social_accounts WHERE sociable_id = 26484;
SELECT * FROM crm_configurations where provider = 'salesforce';
select * from users where id IN (10022, 10403);
select * from users where team_id IN (526);
select * from teams where id IN (526, 532);
select * from crm_configurations where id IN (500, 516);
select * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);
select * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 526 and sa.provider = 'salesforce';
select * from team_settings where team_id IN (526, 532);
select * from users where id IN (22824);
select * from crm_profiles where crm_configuration_id IN (1026);
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1093 and sa.provider = 'salesforce';
select * from teams where id = 1099;
select * from users where id = 29643
select * from activity_processing_states;
SELECT * FROM teams where name LIKE '%Fare%'; # 233
SELECT * FROM opportunities where crm_configuration_id = 215
# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'
;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1088 and sa.provider = 'hubspot';
SELECT * FROM teams order by updated_at DESC
SELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account
select * from crm_configurations where provider = 'pipedrive';
select * from teams where id = 957;
select * from crm_configurations where id = 957;
SELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743
SELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;
select * from users where team_id = 1; # 26726 - Gabriela Dureva
SELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific
select * from activities where user_id = 26726 order by id desc;
select * from contacts where crm_configuration_id = 1
and email IN ('[EMAIL]', '[EMAIL]'); # 2094416, 2093620
SELECT * FROM contacts WHERE id = 6284931;
SELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id
WHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;
select * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);
select * from crm_configurations where id = 1;
43801692-1aeb-32ce-acba-5b80a479701a
44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b
405975c0-b3d0-7aaa-821f-09d59cae6dd1
4caf848d-4bed-2299-b248-7788d41f9fca
49bedc3f-f196-eef3-89c3-dea6a3b4aa63
43420989-a09d-b8f8-9806-c8bbf7a02aac
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
SELECT * FROM activities WHERE id = 75461988;
SELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;
select * from contacts where id = 17900517;
select * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id
where crm.provider != 'salesforce';
select * from users where id = 21047;
SELECT * FROM crm_configurations WHERE id = 892;
SELECT * FROM teams WHERE id = 942;
select * from opportunities where team_id = 942 order by updated_at desc;
select * from contacts where team_id = 942 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 942 and sa.provider = 'hubspot';
SELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430
SELECT * FROM crm_configurations WHERE id = 1;
SELECT * FROM teams WHERE crm_id = 1;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
select id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1
SELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430
select * from teams where id = 852;
select * from groups where id = 2286;
select * from sidekick_settings where team_id = 852;
select * from default_activity_types where team_id = 852;
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1 AND u.deleted_at IS NULL
AND u.crm_required = 1
AND u.team_id = 1
ORDER BY u.team_id;
SELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (
18481
);
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1
AND u.deleted_at IS NULL
AND u.crm_required = 1
# AND u.team_id = 1
AND p.id IS NULL -- Move this condition to WHERE clause
ORDER BY u.team_id;
SELECT * FROM opportunities WHERE id = 20002609;
select * from teams where id = 1122; # Velatir, 29953 - [EMAIL]
select * from crm_configurations where id = 1060;
select * from crm_layouts where crm_configuration_id = 1060;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1122 and sa.provider = 'hubspot';
select * from opportunities where team_id = 1122 order by updated_at desc;
select * from crm_field_data where object_type = 'contact';
SELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 248 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS
SELECT * FROM users where id = 24115;
SELECT * FROM accounts where id = 4002896;
SELECT * FROM teams WHERE name LIKE '%adswerve%';
SELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN ("0069N000003GIQ9QAO","0061r000019yGP9AAM","0066900001S2KWlAAN","0066900001TDpj2AAD","0066900001b8uEwAAI","0069N000001rQi0QAE","006QF00000KD40mYAD","006QF00000LzpRJYAZ","0069N000002uomtQAA","0069N000002xlMLQAY","0066900001NV6ubAAD","0061r00001HJp45AAD","006QF00000uTlUoYAK","006QF00000v0bZqYAI");
SELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203
SELECT u.id, u.email, ac.name, a.* FROM activities a
JOIN users u ON a.user_id = u.id
JOIN accounts ac ON a.account_id = ac.id
WHERE
uuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or
uuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or
uuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;
select * from users where id = 5825;
SELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;
select * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;
19594, 862
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 862 and sa.provider = 'salesforce';
select * from automated_reports where id = 36;
select ar.frequency, r.*, ar.* from automated_report_results r
join automated_reports ar on r.report_id = ar.id
where ar.frequency != 'one_off';
select s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;
select * from nudges n where n.activity_search_id
select * from teams where created_at > '2026-03-09';
SELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;
select * from users where team_id = 1 and name like '%Lukas%'; # 7160
SELECT * FROM teams WHERE id = 575;
select * from opportunities where team_id = 575;
SELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,
select * from opportunities where team_id = 1126;
SELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,
select * from opportunities where team_id = 1125;
select * from contacts c
where c.team_id = 882;
SELECT * FROM activities WHERE id = 76822967;
SELECT * FROM crm_profiles WHERE user_id = 15440;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 555;
SELECT * FROM crm_configurations WHERE id = 555;
SELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 581 and sa.provider = 'salesforce';
SELECT * FROM automated_report_results order by id desc;
select * from features;
select * from team_features where feature_id = 40;
select * from teams where id = 556;
select * from automated_reports;
where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , ["pdf","podcast"]
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
select * from automated_report_results order by id desc;
SELECT * FROM automated_report_results WHERE id = 1919;
select * from automated_report_results WHERE report_id = 54;
select * from opportunities where id = 7594349;
SELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - [EMAIL]
select * from playbooks where team_id = 711; # event 226147
SELECT * FROM playbook_categories WHERE playbook_id = 5515;
SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';
SELECT * FROM crm_fields WHERE id = 226147;
SELECT * FROM crm_field_values WHERE crm_field_id = 226147;
SELECT * FROM crm_configurations WHERE id = 692;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 711 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;
select * from leads;
select * from calendars;
SELECT
t.id AS team_id,
t.name,
LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain
FROM teams t
JOIN users u ON u.team_id = t.id
JOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'
LEFT JOIN team_domains td
ON td.team_id = t.id
AND td.deleted_at IS NULL
AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))
GROUP BY t.id, t.name, calendar_domain
ORDER BY t.name, calendar_domain;
select * from users u join calendars c on c.user_id = u.id
where u.team_id = 882;
select * from activities where id = 74049485; # team 563 crm 537
select * from activities where id = 73272382; # team 563 crm 537
select * from activities where id = 64400389; # team 563 crm 537
select * from activities where id = 58081273; # team 563 crm 537
select * from activities where id = 54520297; # team 563 crm 537
select * from participants where activity_id = 58081273;
select * from activities where crm_configuration_id = 537 and provider = 'aircall'
and account_id = 19003658 order by updated_at desc;
select * from contacts where crm_configuration_id = 537 and id = 35957759;
select * from accounts where crm_configuration_id = 537 and id = 19003658;
select * from automated_report_results where id = 1976;
select * from automated_reports where id = 583;
select * from activity_searches where id = 87714;
select * from activity_search_filters where activity_search_id = 87714;
SELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid
or uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;
SELECT * FROM crm_configurations WHERE provider = 'hubspot';
select * from rate_limits;
select * from automated_report_results where media_type = 'pdf' and status = 2
and id IN (18, 1872);
select * from automated_reports where id = 54;
SELECT * FROM users WHERE id IN (24623,29443,29613);
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
32890
|
NULL
|
NULL
|
NULL
|
|
32893
|
1257
|
10
|
2026-05-13T09:44:28.983413+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665468983_m2.jpg...
|
PhpStorm
|
faVsco.js – TeamController.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
3
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\Settings\Teams;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
use Jiminny\Actions\InviteUserToTeamAction;
use Jiminny\Interactions\Settings\Teams\CreateTeam;
use Jiminny\DTO\Invitation\UserInvitationDTO;
use Jiminny\Http\Requests\Settings\Teams\CreateTeamRequest;
use Jiminny\Http\Controllers\Controller;
use Jiminny\Http\Requests\Settings\Teams\EditTeamRequest;
use Jiminny\Interactions\Settings\Teams\EditTeam;
use Jiminny\Models\Team;
use Jiminny\Models\User;
final class TeamController extends Controller
{
/**
* Create a new team, subscription and invitation.
*/
public function store(
CreateTeamRequest $request,
CreateTeam $createTeam,
InviteUserToTeamAction $inviteUserToTeamAction,
): void {
/** @var User $teamCreator */
$teamCreator = $request->user();
try {
$data = $request->all();
$team = $createTeam->handle($teamCreator, $data, $request->getDomain());
$inviteUserToTeamAction->execute(UserInvitationDTO::forOwner($request, $team));
} catch (\Exception $exception) {
Log::error('An error occurred while creating team', [
'e_message' => $exception->getMessage(),
'e_code' => $exception->getCode(),
]);
throw $exception;
}
}
public function edit(
Team $team,
EditTeamRequest $request,
EditTeam $editTeam,
): JsonResponse {
/** @var User $teamEditor */
$teamEditor = $request->user();
$editTeam->handle($team, $teamEditor, $request->all(), $request);
return response()->json([], JsonResponse::HTTP_OK);
}
}
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
40
1
40
64
Previous Highlighted Error
Next Highlighted Error
SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993
SELECT * FROM users WHERE id = 25061;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 994;
SELECT * FROM crm_profiles WHERE user_id = 25061;
select * from crm_configurations where id = 834;
SELECT * FROM teams WHERE id = 882;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;
SELECT * FROM contacts where crm_configuration_id = 834;
SELECT * FROM opportunities WHERE team_id = 933
# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');
AND id IN (8482561,18352941,19042734,19232139,19445140,19472541);
SELECT * FROM opportunity_contacts
WHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 485; #
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
select crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id
where crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')
# and l.converted_at IS NOT NULL
;
# [PASSWORD_DOTS]
SELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')
and opportunity_id IS NULL
order by id desc;
SELECT * FROM teams WHERE id = 604; # 598
SELECT * FROM activities WHERE id = 74410828; # [EMAIL]
SELECT * FROM accounts WHERE id = 20068382;
SELECT * FROM accounts WHERE id = 35186038;
SELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 559 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;
select * from sidekick_settings where team_id = 781;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100
SELECT * FROM crm_layouts WHERE crm_configuration_id = 711;
SELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL
and is_internal = 0 and status = 'completed'
order by id desc;
SELECT * FROM crm_layout_entities
WHERE crm_layout_id IN (2352, 2353);
;
SELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 556 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;
SELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;
select * from contacts
where crm_configuration_id = 530
and crm_provider_id = 872252;
select * from activities where crm_configuration_id = 530
and user_id = 14343 and type like '%softphone%'
and created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);
SELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t
JOIN crm_configurations c ON t.id = c.team_id
WHERE t.status = 'active';
SELECT * FROM teams where id = 1091;
SELECT * FROM crm_configurations where team_id = 1091;
SELECT * FROM activity_providers where team_id = 1091;
SELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT * FROM teams WHERE name LIKE '%Leadventure%';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1091 and sa.provider = 'salesforce';
SELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812
SELECT * FROM teams where id = 862;
SELECT * FROM crm_configurations where team_id = 862;
SELECT * FROM activity_providers where team_id = 862;
SELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT t.id, crm.id, crm.provider, ap.* FROM teams t
join crm_configurations crm on t.id = crm.team_id
join activity_providers ap on t.id = ap.team_id
where t.status = 'active' and ap.is_enabled = 1
and crm.provider = 'hubspot'
and ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',
'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');
SELECT * FROM teams where id = 1068;
SELECT * FROM crm_configurations where team_id = 1068;
SELECT * FROM activity_providers where team_id = 1068;
SELECT * FROM activities a
where crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')
and a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'
)
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by a.id desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1068 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262
SELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
select * from crm_layouts where crm_configuration_id = 834;
select * from crm_layout_entities where crm_layout_id = 2780;
select * from crm_fields where id IN (321153,321192,321193,321194);
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1057 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8
SELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20
SELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10
SELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #
SELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;
select * from users where team_id = 51; # 7783
SELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130
select * from activity_searches where user_id = 7783;
select * from activity_search_filters where activity_search_id IN (32291, 32292);
SELECT asf.activity_search_id, asf.id, asf.value
FROM activity_search_filters asf
WHERE asf.filter = 'group_id'
AND asf.value IN (
SELECT CONCAT(
HEX(SUBSTR(uuid, 5, 4)), '-',
HEX(SUBSTR(uuid, 3, 2)), '-',
HEX(SUBSTR(uuid, 1, 2)), '-',
HEX(SUBSTR(uuid, 9, 2)), '-',
HEX(SUBSTR(uuid, 11))
)
FROM groups
WHERE deleted_at IS NOT NULL
);
SELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where provider = 'hubspot';
SELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133
SELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null
# [PASSWORD_DOTS]
select * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';
select
cp.*
# DISTINCT t.id
# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields
FROM crm_profiles cp
JOIN crm_configurations crm on crm.id = cp.crm_configuration_id
JOIN users u on u.id = cp.user_id
JOIN teams t ON t.id = crm.team_id
WHERE crm.provider = 'salesforce' and t.status = 'active'
and cp.archived_at IS NULL and u.deleted_at IS NULL
and t.id NOT IN (1093)
and t.id = 2
and cp.contact_fields IS NULL;
# and c.crm_provider_id = '003Uu00000ojD4NIAU';
SELECT * FROM users WHERE id = 26484;
SELECT * FROM crm_profiles WHERE user_id = 26484;
SELECT * FROM social_accounts WHERE sociable_id = 26484;
SELECT * FROM crm_configurations where provider = 'salesforce';
select * from users where id IN (10022, 10403);
select * from users where team_id IN (526);
select * from teams where id IN (526, 532);
select * from crm_configurations where id IN (500, 516);
select * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);
select * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 526 and sa.provider = 'salesforce';
select * from team_settings where team_id IN (526, 532);
select * from users where id IN (22824);
select * from crm_profiles where crm_configuration_id IN (1026);
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1093 and sa.provider = 'salesforce';
select * from teams where id = 1099;
select * from users where id = 29643
select * from activity_processing_states;
SELECT * FROM teams where name LIKE '%Fare%'; # 233
SELECT * FROM opportunities where crm_configuration_id = 215
# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'
;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1088 and sa.provider = 'hubspot';
SELECT * FROM teams order by updated_at DESC
SELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account
select * from crm_configurations where provider = 'pipedrive';
select * from teams where id = 957;
select * from crm_configurations where id = 957;
SELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743
SELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;
select * from users where team_id = 1; # 26726 - Gabriela Dureva
SELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific
select * from activities where user_id = 26726 order by id desc;
select * from contacts where crm_configuration_id = 1
and email IN ('[EMAIL]', '[EMAIL]'); # 2094416, 2093620
SELECT * FROM contacts WHERE id = 6284931;
SELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id
WHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;
select * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);
select * from crm_configurations where id = 1;
43801692-1aeb-32ce-acba-5b80a479701a
44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b
405975c0-b3d0-7aaa-821f-09d59cae6dd1
4caf848d-4bed-2299-b248-7788d41f9fca
49bedc3f-f196-eef3-89c3-dea6a3b4aa63
43420989-a09d-b8f8-9806-c8bbf7a02aac
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
SELECT * FROM activities WHERE id = 75461988;
SELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;
select * from contacts where id = 17900517;
select * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id
where crm.provider != 'salesforce';
select * from users where id = 21047;
SELECT * FROM crm_configurations WHERE id = 892;
SELECT * FROM teams WHERE id = 942;
select * from opportunities where team_id = 942 order by updated_at desc;
select * from contacts where team_id = 942 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 942 and sa.provider = 'hubspot';
SELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430
SELECT * FROM crm_configurations WHERE id = 1;
SELECT * FROM teams WHERE crm_id = 1;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
select id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1
SELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430
select * from teams where id = 852;
select * from groups where id = 2286;
select * from sidekick_settings where team_id = 852;
select * from default_activity_types where team_id = 852;
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1 AND u.deleted_at IS NULL
AND u.crm_required = 1
AND u.team_id = 1
ORDER BY u.team_id;
SELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (
18481
);
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1
AND u.deleted_at IS NULL
AND u.crm_required = 1
# AND u.team_id = 1
AND p.id IS NULL -- Move this condition to WHERE clause
ORDER BY u.team_id;
SELECT * FROM opportunities WHERE id = 20002609;
select * from teams where id = 1122; # Velatir, 29953 - [EMAIL]
select * from crm_configurations where id = 1060;
select * from crm_layouts where crm_configuration_id = 1060;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1122 and sa.provider = 'hubspot';
select * from opportunities where team_id = 1122 order by updated_at desc;
select * from crm_field_data where object_type = 'contact';
SELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 248 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS
SELECT * FROM users where id = 24115;
SELECT * FROM accounts where id = 4002896;
SELECT * FROM teams WHERE name LIKE '%adswerve%';
SELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN ("0069N000003GIQ9QAO","0061r000019yGP9AAM","0066900001S2KWlAAN","0066900001TDpj2AAD","0066900001b8uEwAAI","0069N000001rQi0QAE","006QF00000KD40mYAD","006QF00000LzpRJYAZ","0069N000002uomtQAA","0069N000002xlMLQAY","0066900001NV6ubAAD","0061r00001HJp45AAD","006QF00000uTlUoYAK","006QF00000v0bZqYAI");
SELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203
SELECT u.id, u.email, ac.name, a.* FROM activities a
JOIN users u ON a.user_id = u.id
JOIN accounts ac ON a.account_id = ac.id
WHERE
uuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or
uuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or
uuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;
select * from users where id = 5825;
SELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;
select * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;
19594, 862
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 862 and sa.provider = 'salesforce';
select * from automated_reports where id = 36;
select ar.frequency, r.*, ar.* from automated_report_results r
join automated_reports ar on r.report_id = ar.id
where ar.frequency != 'one_off';
select s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;
select * from nudges n where n.activity_search_id
select * from teams where created_at > '2026-03-09';
SELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;
select * from users where team_id = 1 and name like '%Lukas%'; # 7160
SELECT * FROM teams WHERE id = 575;
select * from opportunities where team_id = 575;
SELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,
select * from opportunities where team_id = 1126;
SELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,
select * from opportunities where team_id = 1125;
select * from contacts c
where c.team_id = 882;
SELECT * FROM activities WHERE id = 76822967;
SELECT * FROM crm_profiles WHERE user_id = 15440;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 555;
SELECT * FROM crm_configurations WHERE id = 555;
SELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 581 and sa.provider = 'salesforce';
SELECT * FROM automated_report_results order by id desc;
select * from features;
select * from team_features where feature_id = 40;
select * from teams where id = 556;
select * from automated_reports;
where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , ["pdf","podcast"]
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
select * from automated_report_results order by id desc;
SELECT * FROM automated_report_results WHERE id = 1919;
select * from automated_report_results WHERE report_id = 54;
select * from opportunities where id = 7594349;
SELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - [EMAIL]
select * from playbooks where team_id = 711; # event 226147
SELECT * FROM playbook_categories WHERE playbook_id = 5515;
SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';
SELECT * FROM crm_fields WHERE id = 226147;
SELECT * FROM crm_field_values WHERE crm_field_id = 226147;
SELECT * FROM crm_configurations WHERE id = 692;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 711 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;
select * from leads;
select * from calendars;
SELECT
t.id AS team_id,
t.name,
LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain
FROM teams t
JOIN users u ON u.team_id = t.id
JOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'
LEFT JOIN team_domains td
ON td.team_id = t.id
AND td.deleted_at IS NULL
AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))
GROUP BY t.id, t.name, calendar_domain
ORDER BY t.name, calendar_domain;
select * from users u join calendars c on c.user_id = u.id
where u.team_id = 882;
select * from activities where id = 74049485; # team 563 crm 537
select * from activities where id = 73272382; # team 563 crm 537
select * from activities where id = 64400389; # team 563 crm 537
select * from activities where id = 58081273; # team 563 crm 537
select * from activities where id = 54520297; # team 563 crm 537
select * from participants where activity_id = 58081273;
select * from activities where crm_configuration_id = 537 and provider = 'aircall'
and account_id = 19003658 order by updated_at desc;
select * from contacts where crm_configuration_id = 537 and id = 35957759;
select * from accounts where crm_configuration_id = 537 and id = 19003658;
select * from automated_report_results where id = 1976;
select * from automated_reports where id = 583;
select * from activity_searches where id = 87714;
select * from activity_search_filters where activity_search_id = 87714;
SELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid
or uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;
SELECT * FROM crm_configurations WHERE provider = 'hubspot';
select * from rate_limits;
select * from automated_report_results where media_type = 'pdf' and status = 2
and id IN (18, 1872);
select * from automated_reports where id = 54;
SELECT * FROM users WHERE id IN (24623,29443,29613);
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
Project
Project
New File or Directory…
Expand Selected
Collapse All...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.034242023,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"3","depth":4,"bounds":{"left":0.38397607,"top":0.07581804,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.39361703,"top":0.074221864,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.40093085,"top":0.074221864,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Http\\Controllers\\Settings\\Teams;\n\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Actions\\InviteUserToTeamAction;\nuse Jiminny\\Interactions\\Settings\\Teams\\CreateTeam;\nuse Jiminny\\DTO\\Invitation\\UserInvitationDTO;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\CreateTeamRequest;\nuse Jiminny\\Http\\Controllers\\Controller;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\EditTeamRequest;\nuse Jiminny\\Interactions\\Settings\\Teams\\EditTeam;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\n\nfinal class TeamController extends Controller\n{\n /**\n * Create a new team, subscription and invitation.\n */\n public function store(\n CreateTeamRequest $request,\n CreateTeam $createTeam,\n InviteUserToTeamAction $inviteUserToTeamAction,\n ): void {\n /** @var User $teamCreator */\n $teamCreator = $request->user();\n\n try {\n $data = $request->all();\n $team = $createTeam->handle($teamCreator, $data, $request->getDomain());\n\n $inviteUserToTeamAction->execute(UserInvitationDTO::forOwner($request, $team));\n } catch (\\Exception $exception) {\n Log::error('An error occurred while creating team', [\n 'e_message' => $exception->getMessage(),\n 'e_code' => $exception->getCode(),\n ]);\n\n throw $exception;\n }\n }\n\n public function edit(\n Team $team,\n EditTeamRequest $request,\n EditTeam $editTeam,\n ): JsonResponse {\n /** @var User $teamEditor */\n $teamEditor = $request->user();\n $editTeam->handle($team, $teamEditor, $request->all(), $request);\n\n return response()->json([], JsonResponse::HTTP_OK);\n }\n}","depth":4,"bounds":{"left":0.11968085,"top":0.0726257,"width":0.28823137,"height":0.9066241},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Http\\Controllers\\Settings\\Teams;\n\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Actions\\InviteUserToTeamAction;\nuse Jiminny\\Interactions\\Settings\\Teams\\CreateTeam;\nuse Jiminny\\DTO\\Invitation\\UserInvitationDTO;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\CreateTeamRequest;\nuse Jiminny\\Http\\Controllers\\Controller;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\EditTeamRequest;\nuse Jiminny\\Interactions\\Settings\\Teams\\EditTeam;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\n\nfinal class TeamController extends Controller\n{\n /**\n * Create a new team, subscription and invitation.\n */\n public function store(\n CreateTeamRequest $request,\n CreateTeam $createTeam,\n InviteUserToTeamAction $inviteUserToTeamAction,\n ): void {\n /** @var User $teamCreator */\n $teamCreator = $request->user();\n\n try {\n $data = $request->all();\n $team = $createTeam->handle($teamCreator, $data, $request->getDomain());\n\n $inviteUserToTeamAction->execute(UserInvitationDTO::forOwner($request, $team));\n } catch (\\Exception $exception) {\n Log::error('An error occurred while creating team', [\n 'e_message' => $exception->getMessage(),\n 'e_code' => $exception->getCode(),\n ]);\n\n throw $exception;\n }\n }\n\n public function edit(\n Team $team,\n EditTeamRequest $request,\n EditTeam $editTeam,\n ): JsonResponse {\n /** @var User $teamEditor */\n $teamEditor = $request->user();\n $editTeam->handle($team, $teamEditor, $request->all(), $request);\n\n return response()->json([], JsonResponse::HTTP_OK);\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.40957448,"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.41821808,"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.42918882,"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.43783244,"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.44647607,"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.4574468,"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.46841756,"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.4950133,"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.50598407,"top":0.09896249,"width":0.029587766,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"bounds":{"left":0.7084442,"top":0.09896249,"width":0.02825798,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"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":"40","depth":4,"bounds":{"left":0.67785907,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.69015956,"top":0.123703115,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"40","depth":4,"bounds":{"left":0.6994681,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"64","depth":4,"bounds":{"left":0.7117686,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.7237367,"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.73105055,"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 * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","depth":4,"on_screen":true,"value":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","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}]...
|
8279452233483258165
|
1065678670634825285
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
3
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\Settings\Teams;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
use Jiminny\Actions\InviteUserToTeamAction;
use Jiminny\Interactions\Settings\Teams\CreateTeam;
use Jiminny\DTO\Invitation\UserInvitationDTO;
use Jiminny\Http\Requests\Settings\Teams\CreateTeamRequest;
use Jiminny\Http\Controllers\Controller;
use Jiminny\Http\Requests\Settings\Teams\EditTeamRequest;
use Jiminny\Interactions\Settings\Teams\EditTeam;
use Jiminny\Models\Team;
use Jiminny\Models\User;
final class TeamController extends Controller
{
/**
* Create a new team, subscription and invitation.
*/
public function store(
CreateTeamRequest $request,
CreateTeam $createTeam,
InviteUserToTeamAction $inviteUserToTeamAction,
): void {
/** @var User $teamCreator */
$teamCreator = $request->user();
try {
$data = $request->all();
$team = $createTeam->handle($teamCreator, $data, $request->getDomain());
$inviteUserToTeamAction->execute(UserInvitationDTO::forOwner($request, $team));
} catch (\Exception $exception) {
Log::error('An error occurred while creating team', [
'e_message' => $exception->getMessage(),
'e_code' => $exception->getCode(),
]);
throw $exception;
}
}
public function edit(
Team $team,
EditTeamRequest $request,
EditTeam $editTeam,
): JsonResponse {
/** @var User $teamEditor */
$teamEditor = $request->user();
$editTeam->handle($team, $teamEditor, $request->all(), $request);
return response()->json([], JsonResponse::HTTP_OK);
}
}
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
40
1
40
64
Previous Highlighted Error
Next Highlighted Error
SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993
SELECT * FROM users WHERE id = 25061;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 994;
SELECT * FROM crm_profiles WHERE user_id = 25061;
select * from crm_configurations where id = 834;
SELECT * FROM teams WHERE id = 882;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;
SELECT * FROM contacts where crm_configuration_id = 834;
SELECT * FROM opportunities WHERE team_id = 933
# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');
AND id IN (8482561,18352941,19042734,19232139,19445140,19472541);
SELECT * FROM opportunity_contacts
WHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 485; #
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
select crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id
where crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')
# and l.converted_at IS NOT NULL
;
# [PASSWORD_DOTS]
SELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')
and opportunity_id IS NULL
order by id desc;
SELECT * FROM teams WHERE id = 604; # 598
SELECT * FROM activities WHERE id = 74410828; # [EMAIL]
SELECT * FROM accounts WHERE id = 20068382;
SELECT * FROM accounts WHERE id = 35186038;
SELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 559 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;
select * from sidekick_settings where team_id = 781;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100
SELECT * FROM crm_layouts WHERE crm_configuration_id = 711;
SELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL
and is_internal = 0 and status = 'completed'
order by id desc;
SELECT * FROM crm_layout_entities
WHERE crm_layout_id IN (2352, 2353);
;
SELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 556 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;
SELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;
select * from contacts
where crm_configuration_id = 530
and crm_provider_id = 872252;
select * from activities where crm_configuration_id = 530
and user_id = 14343 and type like '%softphone%'
and created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);
SELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t
JOIN crm_configurations c ON t.id = c.team_id
WHERE t.status = 'active';
SELECT * FROM teams where id = 1091;
SELECT * FROM crm_configurations where team_id = 1091;
SELECT * FROM activity_providers where team_id = 1091;
SELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT * FROM teams WHERE name LIKE '%Leadventure%';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1091 and sa.provider = 'salesforce';
SELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812
SELECT * FROM teams where id = 862;
SELECT * FROM crm_configurations where team_id = 862;
SELECT * FROM activity_providers where team_id = 862;
SELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT t.id, crm.id, crm.provider, ap.* FROM teams t
join crm_configurations crm on t.id = crm.team_id
join activity_providers ap on t.id = ap.team_id
where t.status = 'active' and ap.is_enabled = 1
and crm.provider = 'hubspot'
and ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',
'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');
SELECT * FROM teams where id = 1068;
SELECT * FROM crm_configurations where team_id = 1068;
SELECT * FROM activity_providers where team_id = 1068;
SELECT * FROM activities a
where crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')
and a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'
)
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by a.id desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1068 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262
SELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
select * from crm_layouts where crm_configuration_id = 834;
select * from crm_layout_entities where crm_layout_id = 2780;
select * from crm_fields where id IN (321153,321192,321193,321194);
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1057 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8
SELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20
SELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10
SELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #
SELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;
select * from users where team_id = 51; # 7783
SELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130
select * from activity_searches where user_id = 7783;
select * from activity_search_filters where activity_search_id IN (32291, 32292);
SELECT asf.activity_search_id, asf.id, asf.value
FROM activity_search_filters asf
WHERE asf.filter = 'group_id'
AND asf.value IN (
SELECT CONCAT(
HEX(SUBSTR(uuid, 5, 4)), '-',
HEX(SUBSTR(uuid, 3, 2)), '-',
HEX(SUBSTR(uuid, 1, 2)), '-',
HEX(SUBSTR(uuid, 9, 2)), '-',
HEX(SUBSTR(uuid, 11))
)
FROM groups
WHERE deleted_at IS NOT NULL
);
SELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where provider = 'hubspot';
SELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133
SELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null
# [PASSWORD_DOTS]
select * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';
select
cp.*
# DISTINCT t.id
# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields
FROM crm_profiles cp
JOIN crm_configurations crm on crm.id = cp.crm_configuration_id
JOIN users u on u.id = cp.user_id
JOIN teams t ON t.id = crm.team_id
WHERE crm.provider = 'salesforce' and t.status = 'active'
and cp.archived_at IS NULL and u.deleted_at IS NULL
and t.id NOT IN (1093)
and t.id = 2
and cp.contact_fields IS NULL;
# and c.crm_provider_id = '003Uu00000ojD4NIAU';
SELECT * FROM users WHERE id = 26484;
SELECT * FROM crm_profiles WHERE user_id = 26484;
SELECT * FROM social_accounts WHERE sociable_id = 26484;
SELECT * FROM crm_configurations where provider = 'salesforce';
select * from users where id IN (10022, 10403);
select * from users where team_id IN (526);
select * from teams where id IN (526, 532);
select * from crm_configurations where id IN (500, 516);
select * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);
select * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 526 and sa.provider = 'salesforce';
select * from team_settings where team_id IN (526, 532);
select * from users where id IN (22824);
select * from crm_profiles where crm_configuration_id IN (1026);
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1093 and sa.provider = 'salesforce';
select * from teams where id = 1099;
select * from users where id = 29643
select * from activity_processing_states;
SELECT * FROM teams where name LIKE '%Fare%'; # 233
SELECT * FROM opportunities where crm_configuration_id = 215
# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'
;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1088 and sa.provider = 'hubspot';
SELECT * FROM teams order by updated_at DESC
SELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account
select * from crm_configurations where provider = 'pipedrive';
select * from teams where id = 957;
select * from crm_configurations where id = 957;
SELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743
SELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;
select * from users where team_id = 1; # 26726 - Gabriela Dureva
SELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific
select * from activities where user_id = 26726 order by id desc;
select * from contacts where crm_configuration_id = 1
and email IN ('[EMAIL]', '[EMAIL]'); # 2094416, 2093620
SELECT * FROM contacts WHERE id = 6284931;
SELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id
WHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;
select * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);
select * from crm_configurations where id = 1;
43801692-1aeb-32ce-acba-5b80a479701a
44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b
405975c0-b3d0-7aaa-821f-09d59cae6dd1
4caf848d-4bed-2299-b248-7788d41f9fca
49bedc3f-f196-eef3-89c3-dea6a3b4aa63
43420989-a09d-b8f8-9806-c8bbf7a02aac
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
SELECT * FROM activities WHERE id = 75461988;
SELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;
select * from contacts where id = 17900517;
select * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id
where crm.provider != 'salesforce';
select * from users where id = 21047;
SELECT * FROM crm_configurations WHERE id = 892;
SELECT * FROM teams WHERE id = 942;
select * from opportunities where team_id = 942 order by updated_at desc;
select * from contacts where team_id = 942 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 942 and sa.provider = 'hubspot';
SELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430
SELECT * FROM crm_configurations WHERE id = 1;
SELECT * FROM teams WHERE crm_id = 1;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
select id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1
SELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430
select * from teams where id = 852;
select * from groups where id = 2286;
select * from sidekick_settings where team_id = 852;
select * from default_activity_types where team_id = 852;
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1 AND u.deleted_at IS NULL
AND u.crm_required = 1
AND u.team_id = 1
ORDER BY u.team_id;
SELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (
18481
);
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1
AND u.deleted_at IS NULL
AND u.crm_required = 1
# AND u.team_id = 1
AND p.id IS NULL -- Move this condition to WHERE clause
ORDER BY u.team_id;
SELECT * FROM opportunities WHERE id = 20002609;
select * from teams where id = 1122; # Velatir, 29953 - [EMAIL]
select * from crm_configurations where id = 1060;
select * from crm_layouts where crm_configuration_id = 1060;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1122 and sa.provider = 'hubspot';
select * from opportunities where team_id = 1122 order by updated_at desc;
select * from crm_field_data where object_type = 'contact';
SELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 248 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS
SELECT * FROM users where id = 24115;
SELECT * FROM accounts where id = 4002896;
SELECT * FROM teams WHERE name LIKE '%adswerve%';
SELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN ("0069N000003GIQ9QAO","0061r000019yGP9AAM","0066900001S2KWlAAN","0066900001TDpj2AAD","0066900001b8uEwAAI","0069N000001rQi0QAE","006QF00000KD40mYAD","006QF00000LzpRJYAZ","0069N000002uomtQAA","0069N000002xlMLQAY","0066900001NV6ubAAD","0061r00001HJp45AAD","006QF00000uTlUoYAK","006QF00000v0bZqYAI");
SELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203
SELECT u.id, u.email, ac.name, a.* FROM activities a
JOIN users u ON a.user_id = u.id
JOIN accounts ac ON a.account_id = ac.id
WHERE
uuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or
uuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or
uuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;
select * from users where id = 5825;
SELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;
select * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;
19594, 862
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 862 and sa.provider = 'salesforce';
select * from automated_reports where id = 36;
select ar.frequency, r.*, ar.* from automated_report_results r
join automated_reports ar on r.report_id = ar.id
where ar.frequency != 'one_off';
select s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;
select * from nudges n where n.activity_search_id
select * from teams where created_at > '2026-03-09';
SELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;
select * from users where team_id = 1 and name like '%Lukas%'; # 7160
SELECT * FROM teams WHERE id = 575;
select * from opportunities where team_id = 575;
SELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,
select * from opportunities where team_id = 1126;
SELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,
select * from opportunities where team_id = 1125;
select * from contacts c
where c.team_id = 882;
SELECT * FROM activities WHERE id = 76822967;
SELECT * FROM crm_profiles WHERE user_id = 15440;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 555;
SELECT * FROM crm_configurations WHERE id = 555;
SELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 581 and sa.provider = 'salesforce';
SELECT * FROM automated_report_results order by id desc;
select * from features;
select * from team_features where feature_id = 40;
select * from teams where id = 556;
select * from automated_reports;
where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , ["pdf","podcast"]
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
select * from automated_report_results order by id desc;
SELECT * FROM automated_report_results WHERE id = 1919;
select * from automated_report_results WHERE report_id = 54;
select * from opportunities where id = 7594349;
SELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - [EMAIL]
select * from playbooks where team_id = 711; # event 226147
SELECT * FROM playbook_categories WHERE playbook_id = 5515;
SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';
SELECT * FROM crm_fields WHERE id = 226147;
SELECT * FROM crm_field_values WHERE crm_field_id = 226147;
SELECT * FROM crm_configurations WHERE id = 692;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 711 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;
select * from leads;
select * from calendars;
SELECT
t.id AS team_id,
t.name,
LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain
FROM teams t
JOIN users u ON u.team_id = t.id
JOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'
LEFT JOIN team_domains td
ON td.team_id = t.id
AND td.deleted_at IS NULL
AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))
GROUP BY t.id, t.name, calendar_domain
ORDER BY t.name, calendar_domain;
select * from users u join calendars c on c.user_id = u.id
where u.team_id = 882;
select * from activities where id = 74049485; # team 563 crm 537
select * from activities where id = 73272382; # team 563 crm 537
select * from activities where id = 64400389; # team 563 crm 537
select * from activities where id = 58081273; # team 563 crm 537
select * from activities where id = 54520297; # team 563 crm 537
select * from participants where activity_id = 58081273;
select * from activities where crm_configuration_id = 537 and provider = 'aircall'
and account_id = 19003658 order by updated_at desc;
select * from contacts where crm_configuration_id = 537 and id = 35957759;
select * from accounts where crm_configuration_id = 537 and id = 19003658;
select * from automated_report_results where id = 1976;
select * from automated_reports where id = 583;
select * from activity_searches where id = 87714;
select * from activity_search_filters where activity_search_id = 87714;
SELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid
or uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;
SELECT * FROM crm_configurations WHERE provider = 'hubspot';
select * from rate_limits;
select * from automated_report_results where media_type = 'pdf' and status = 2
and id IN (18, 1872);
select * from automated_reports where id = 54;
SELECT * FROM users WHERE id IN (24623,29443,29613);
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
Project
Project
New File or Directory…
Expand Selected
Collapse All...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
32894
|
1256
|
14
|
2026-05-13T09:44:45.938648+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665485938_m1.jpg...
|
PhpStorm
|
faVsco.js – TeamController.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
SlackFile Edit ViewGoHistoryWindowHelpAPPDOCKER₴81 SlackFile Edit ViewGoHistoryWindowHelpAPPDOCKER₴81DEV (docker)₴82APP (-zshtests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleterTest.phptests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesProviderTest.phptests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesUploaderTest.phptests/Unit/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeeches?tests/Unit/Component/Transcription/Diarization/Source/MeetingBotSourceTest.phptests/Unit/Contracts/Services/Calendar/CalendarTraitTest.phptests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.phptests/Unit/Jobs/Activity/Import/ImportTwilioVideoSpeechesJobTest.phptests/Unit/Jobs/Activity/Import/IsActivityReadyForProcessingJobTest.phptests/Unit/Jobs/Calendar/SetupCalendarSyncTest.phptests/Unit/Services/Activity/ParticipantsServiceTest.phptests/Unit/Services/Calendar/Command/ImportParticipantsTest.phptests/Unit/Services/Calendar/GoogleCalendarServiceTest.phptests/Unit/Services/Crm/Close/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTest.phptests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTraitMatchActivitiesTest.phytests/Unit/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTraitOpportunitiesTe:tests/Unit/Services/Crm/Pipedrive/ImportOpportunityMatchActivitiesTest.phptests/Unit/Services/Crm/Salesforce/ServiceTest.phptests/Unit/Services/Mail/0ffice/EmailApiClientTest.phptests/Unit/Services/RecallAI/RecallAIServiceTest.php113 files changed, 4143 insertions(+), 1740 deletions(-)create mode 120000 CLAUDE.mdcreate mode 100644 app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.phpdelete mode 100644 app/Component/ES/ElasticSearchWorkerManager.phpdelete mode 100644 app/Component/ES/Worker/ActivityWorker.phpdelete mode 100644 app/Component/ES/Worker/EntityWorker.phpdelete mode100644 app/Component/ES/Worker/WorkerAmount.phpdelete mode100644 app/Component/ES/Worker/WorkerInterface.phpcreate mode100644 app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.phtcreate mode100644 app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/Assembl:create mode100644 app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNot(create mode 100644 app/Console/Commands/Crm/Backfill0pportunityUserFromAccountCommand.phpdelete mode 100644 app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.phpcreate mode100644 front-end/src/components/shared/modals/EntityPickerModal/__tests__/us‹create mode 100644 tests/Feature/Component/Nudge/Process0rganisationImmediateNudgesJobTe:create mode 100644 tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheck‹delete mode 100644 tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/ActivityWorkerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/EntityWorkerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/WorkerAmountTest.phpcreate mode 100644 tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCr‹create mode 100644 tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.phpLukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ I|HomeDMsActivityFilesLaterMore(aol§ Support Daily - in 2h 16 m100% <78•Wed 13 May12:44:45ED-→Describe what you are looking forJiminny ...Nikolay Ivanov6 0curoaroylau# engineering# general# jiminny-bg# platform-tickets# product_launches#random# releases# sofia-office# support# thank-yous# the_people_of jimi...MessagesAdd canvas@ Files+Lukas Kovalik 11.Today ~мен все ме праща наhttps://app.vanta.com/c/jiminny.com/employee/onboardingNikolay Ivanov 11:01 AMХм, Джейс дали не може да ти помогне?Lukas Kovalik 11:01 AMще питам James, предполагам че нямам правада мерсиNikolay Ivanov 11:01 AMмда° Direct messages& Nikolay Ivanovdo James Graham. Stoyan Tanev. Galya Dimitrova. Steliyan Georgievo Petko Kashinski®. Aneliya Angelovaã. Stefka Stoyanova•. Vasil Vasilev •!Lukas Kovalik y...МОЛЯLukas Kovalik 12:13 PMНики сори, още един въпрос имамкогато ги правеше ти FE ли оправяима vulnerabilities no npmNikolay Ivanov 12:28 PMнетях ги оставямLukas Kovalik 12:29 PMаз погледнах твоя тикет и там друго нямашесамо FEкак стигна до Workerl:: AppsJira CloudMessage Nikolay IvanovToast...
|
NULL
|
-8804658197049154370
|
NULL
|
click
|
ocr
|
NULL
|
SlackFile Edit ViewGoHistoryWindowHelpAPPDOCKER₴81 SlackFile Edit ViewGoHistoryWindowHelpAPPDOCKER₴81DEV (docker)₴82APP (-zshtests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleterTest.phptests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesProviderTest.phptests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesUploaderTest.phptests/Unit/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeeches?tests/Unit/Component/Transcription/Diarization/Source/MeetingBotSourceTest.phptests/Unit/Contracts/Services/Calendar/CalendarTraitTest.phptests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.phptests/Unit/Jobs/Activity/Import/ImportTwilioVideoSpeechesJobTest.phptests/Unit/Jobs/Activity/Import/IsActivityReadyForProcessingJobTest.phptests/Unit/Jobs/Calendar/SetupCalendarSyncTest.phptests/Unit/Services/Activity/ParticipantsServiceTest.phptests/Unit/Services/Calendar/Command/ImportParticipantsTest.phptests/Unit/Services/Calendar/GoogleCalendarServiceTest.phptests/Unit/Services/Crm/Close/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTest.phptests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTraitMatchActivitiesTest.phytests/Unit/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTraitOpportunitiesTe:tests/Unit/Services/Crm/Pipedrive/ImportOpportunityMatchActivitiesTest.phptests/Unit/Services/Crm/Salesforce/ServiceTest.phptests/Unit/Services/Mail/0ffice/EmailApiClientTest.phptests/Unit/Services/RecallAI/RecallAIServiceTest.php113 files changed, 4143 insertions(+), 1740 deletions(-)create mode 120000 CLAUDE.mdcreate mode 100644 app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.phpdelete mode 100644 app/Component/ES/ElasticSearchWorkerManager.phpdelete mode 100644 app/Component/ES/Worker/ActivityWorker.phpdelete mode 100644 app/Component/ES/Worker/EntityWorker.phpdelete mode100644 app/Component/ES/Worker/WorkerAmount.phpdelete mode100644 app/Component/ES/Worker/WorkerInterface.phpcreate mode100644 app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.phtcreate mode100644 app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/Assembl:create mode100644 app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNot(create mode 100644 app/Console/Commands/Crm/Backfill0pportunityUserFromAccountCommand.phpdelete mode 100644 app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.phpcreate mode100644 front-end/src/components/shared/modals/EntityPickerModal/__tests__/us‹create mode 100644 tests/Feature/Component/Nudge/Process0rganisationImmediateNudgesJobTe:create mode 100644 tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheck‹delete mode 100644 tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/ActivityWorkerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/EntityWorkerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/WorkerAmountTest.phpcreate mode 100644 tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCr‹create mode 100644 tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.phpLukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ I|HomeDMsActivityFilesLaterMore(aol§ Support Daily - in 2h 16 m100% <78•Wed 13 May12:44:45ED-→Describe what you are looking forJiminny ...Nikolay Ivanov6 0curoaroylau# engineering# general# jiminny-bg# platform-tickets# product_launches#random# releases# sofia-office# support# thank-yous# the_people_of jimi...MessagesAdd canvas@ Files+Lukas Kovalik 11.Today ~мен все ме праща наhttps://app.vanta.com/c/jiminny.com/employee/onboardingNikolay Ivanov 11:01 AMХм, Джейс дали не може да ти помогне?Lukas Kovalik 11:01 AMще питам James, предполагам че нямам правада мерсиNikolay Ivanov 11:01 AMмда° Direct messages& Nikolay Ivanovdo James Graham. Stoyan Tanev. Galya Dimitrova. Steliyan Georgievo Petko Kashinski®. Aneliya Angelovaã. Stefka Stoyanova•. Vasil Vasilev •!Lukas Kovalik y...МОЛЯLukas Kovalik 12:13 PMНики сори, още един въпрос имамкогато ги правеше ти FE ли оправяима vulnerabilities no npmNikolay Ivanov 12:28 PMнетях ги оставямLukas Kovalik 12:29 PMаз погледнах твоя тикет и там друго нямашесамо FEкак стигна до Workerl:: AppsJira CloudMessage Nikolay IvanovToast...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
32895
|
1257
|
11
|
2026-05-13T09:44:45.972358+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665485972_m2.jpg...
|
PhpStorm
|
faVsco.js – TeamController.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhostormINavigarecodeLaravelKeractorFV faVsco.jsPr PhostormINavigarecodeLaravelKeractorFV faVsco.jsProiect vC CreateTeam.pnpYC) IntecrationContr(C) InvitationControYC) OraanizationSeto reamcoachingsnanespace Jiminny hetp concroulers settingsleansO leamconterene› use •C) leamDealinsigh 18(C) TeamDomaince, 10tinal class Teamcontroller extends controllen© TeamMemberCc 20© TeamPhotoCont 21C) leamkecording: 22© TeamSettingsCc 23c) leamsorphone• D Users124109C) DashboardControlle 25c) GroupController.ohi 26C) JobTitleController.r 279 MomentController.r 29c) Plavbookcatedorvd 20C) PlavbookController. za> M Telenhonv• N Webhook• M HubsootM intearationAonSubs 34(C) ActivitvDroviderCor zc© ActivityTranscriptio 36© BaseController.php 37€ CalendarController. 38(C) PenortController nh z09a) SoftnhoneWehhool 4dc.AbstractController.ong 41( CommentContextinter 42© Controller.php4) SynortController.php© FrontendController.pht 46( FrontendControllerTraGeocodinaController.p cn0g© HealthCheckController 48@ LiveCoachController.ol 4gc)Missing Teamcontrolle saC) MobileController.oho(C) NotificationController.: s8(C) NotificationProviderCo 5:@ PlavbackController.oh@ PlavlistController.ohp(c) PucherControlier ohnYc) SlackController nhn8) SunnortController nhn(C) TeamSetunController* Create a new team. subscription and invitation.posTaoivlsettinas/oraanizationslkiosk.oraanizations.storelnublic function storeCreateTeamRequest Srequest,CreateTeam Screateteam.InvitelserToTeamAction SinvitelsertoteamAction.): void 1/** @var User $teamCreator */SteamCreator = $request->userO:try{$data = $request->allO:Steam = $createTeam->handle($teamCreator, $data, Srequest->getDomainO):SinviteUserToTeamAction->execute(UserInvitationDTO:: for0wner(Srequest, $team)):} catch (\Exception Sexception) {Log::error( message: "An error occurred while creating team'. "'e message' => sexception->qetmessaqeoi= Sexception->qetCodeoPUTlaoi/v1/kiosk/oraanizations/team›lkiosk.oraanizations.editoublic function editdTeam Steam.EdrtTeamPenues+ Srequest.EditTeam SeditTeam!): JsonResponse {...}572— 573587588589596597— 594596— 60€60660%— 609612|aravel.l0gA SF (jiminny@localhost]4 HS_local [jiminny@localhost]« console (PROD] X 4 console [EU]A console [STAGING]Tx: AutovSo jiminnyCONCAT(u.id, CASE WHEN U.id = t.owner_id THEN ' (owner)' ELSE'' END) AS user_id,040 A1 A40 V 64 ^sa.*t.owner_id FROM social_accounts saNolN usens u on u.id e sa.sociablle i.diJOIN teams t .n<->l: on t.id = u.team_icWHERE u.team_id = 581 and sa.provider = 'salesforce';SELECT * FROM automated_report_results order by id desc;select * from features;select * from team_features where feature_id = 40;select * from teams where id = 556:select * from automated_reports:where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044,["pdf" "podcast"]SELECT * FROM automated report_ results WHERE uuid to bin( '822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;select * from automated_report_results order by za desc;sclzu * Frur automated revort resulrsWHERE id = 1919select * from automated report results WHERE renort 10 = 54:select * from opportunities where 1d = 75943494SELE * FROM teams WHERE name LIKE "%Les%': # 711, 692. 16067 - Timinnvintearationdlesmils.comselect * from playbooks where team id = 711; # event 226147SELEd * FROM Davbook catedonies WHERE Dlavbook 10 e 55151SELECT * SROM eom fields WHERE eom confiauration 1d = 692 and obnect tvne =SELECT * SROM com fields WHERE 1d = 226147-SELECT * EROM eom field values WHERE com field 1d = 226147.SELECT * FROM crm_configurations WHERE id = 692;SELSCTCONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '• END) AS user_id,nemailiSa.xt.owner id FROM social accounts saJOIN users u on u.id = sa.sociable idJOIN teams t 1..n<->1: on t.id = u.team idWHERE U.team id = 711 and sa.provider = 'salesforce':SELECT * FROM crm profiles co JOIN users u 1..n<->1: on u.id = co.user id WHERE u.team_id = 711:select * from leads:select * from calendars:SELECTS0 hlsuppont Dally • In Zn 10m100% L2• Wed 13 May 12:44:45AskJiminnyReportActivityServiceTest -CascadeTrial Owner Role Selec+0 ..kead kegistercontroller.php ana OnboardController.pnp ›Searched UserRegistered invitation. accept in ~/iminnyappThought for 3s ›Read UpdateProtile.phg0// tasks done ?• Review current role assianment when owner sians in7 Document findinas and provide imolementation olanInoughttor 4s7 7 tasks done)Ihought for 4SCurrent Flow Analvsis: Owner Role Assianment in Trial CreationBackend Flow1. Team Creation Entrv Point• TeamController::store() (lines 24-45)app Actions/InviteUsertoreamaction.php the team• Calls InviteUserToTeamAction with UserInvitationDTO: : for0wner(Srequest, Steam)2. Owner Role Assianment (HARDCODED)• UserInvitationDTO:: for0wner() (lines 52-72 in/app/DTO/Invitation/UserInvitationDT0.php)•Lines 54-57: This is where the owner's role is hardcodediohrUser:: ROLE RECORDER,→>oluck("id')→>toArravo:•Alwavs assians ROLE ADMIN + ROLE RECORDER to the ownenThic ic the koy ioention that noode modification3. Invitation Creatior•InviteUserToTeamAction::execute@ (lines 28-81)• Creates an Invitation with roles from the DTO (line 45: Sinvitation->roles()->sync(Sdto->roleIds))• Sends OwnerInvitedToTrial notificationl1 Owner Sian-in FlowOwner receives email invitation• Regrstercontroller:: showRegnstratonformo shows registration form with invitation dataOwner redisters and accents invitationRoles are already assigned via the invitation, so owner gets ROLE ADMIN + ROLE RECORDER automaticallvFrontend FlowAsk anvthina (84-D)« Code SWF-1.6O0 1WN Windsurf Teams26.52UTE.8io 4 spaces...
|
NULL
|
-5932179578530406328
|
NULL
|
click
|
ocr
|
NULL
|
PhostormINavigarecodeLaravelKeractorFV faVsco.jsPr PhostormINavigarecodeLaravelKeractorFV faVsco.jsProiect vC CreateTeam.pnpYC) IntecrationContr(C) InvitationControYC) OraanizationSeto reamcoachingsnanespace Jiminny hetp concroulers settingsleansO leamconterene› use •C) leamDealinsigh 18(C) TeamDomaince, 10tinal class Teamcontroller extends controllen© TeamMemberCc 20© TeamPhotoCont 21C) leamkecording: 22© TeamSettingsCc 23c) leamsorphone• D Users124109C) DashboardControlle 25c) GroupController.ohi 26C) JobTitleController.r 279 MomentController.r 29c) Plavbookcatedorvd 20C) PlavbookController. za> M Telenhonv• N Webhook• M HubsootM intearationAonSubs 34(C) ActivitvDroviderCor zc© ActivityTranscriptio 36© BaseController.php 37€ CalendarController. 38(C) PenortController nh z09a) SoftnhoneWehhool 4dc.AbstractController.ong 41( CommentContextinter 42© Controller.php4) SynortController.php© FrontendController.pht 46( FrontendControllerTraGeocodinaController.p cn0g© HealthCheckController 48@ LiveCoachController.ol 4gc)Missing Teamcontrolle saC) MobileController.oho(C) NotificationController.: s8(C) NotificationProviderCo 5:@ PlavbackController.oh@ PlavlistController.ohp(c) PucherControlier ohnYc) SlackController nhn8) SunnortController nhn(C) TeamSetunController* Create a new team. subscription and invitation.posTaoivlsettinas/oraanizationslkiosk.oraanizations.storelnublic function storeCreateTeamRequest Srequest,CreateTeam Screateteam.InvitelserToTeamAction SinvitelsertoteamAction.): void 1/** @var User $teamCreator */SteamCreator = $request->userO:try{$data = $request->allO:Steam = $createTeam->handle($teamCreator, $data, Srequest->getDomainO):SinviteUserToTeamAction->execute(UserInvitationDTO:: for0wner(Srequest, $team)):} catch (\Exception Sexception) {Log::error( message: "An error occurred while creating team'. "'e message' => sexception->qetmessaqeoi= Sexception->qetCodeoPUTlaoi/v1/kiosk/oraanizations/team›lkiosk.oraanizations.editoublic function editdTeam Steam.EdrtTeamPenues+ Srequest.EditTeam SeditTeam!): JsonResponse {...}572— 573587588589596597— 594596— 60€60660%— 609612|aravel.l0gA SF (jiminny@localhost]4 HS_local [jiminny@localhost]« console (PROD] X 4 console [EU]A console [STAGING]Tx: AutovSo jiminnyCONCAT(u.id, CASE WHEN U.id = t.owner_id THEN ' (owner)' ELSE'' END) AS user_id,040 A1 A40 V 64 ^sa.*t.owner_id FROM social_accounts saNolN usens u on u.id e sa.sociablle i.diJOIN teams t .n<->l: on t.id = u.team_icWHERE u.team_id = 581 and sa.provider = 'salesforce';SELECT * FROM automated_report_results order by id desc;select * from features;select * from team_features where feature_id = 40;select * from teams where id = 556:select * from automated_reports:where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044,["pdf" "podcast"]SELECT * FROM automated report_ results WHERE uuid to bin( '822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;select * from automated_report_results order by za desc;sclzu * Frur automated revort resulrsWHERE id = 1919select * from automated report results WHERE renort 10 = 54:select * from opportunities where 1d = 75943494SELE * FROM teams WHERE name LIKE "%Les%': # 711, 692. 16067 - Timinnvintearationdlesmils.comselect * from playbooks where team id = 711; # event 226147SELEd * FROM Davbook catedonies WHERE Dlavbook 10 e 55151SELECT * SROM eom fields WHERE eom confiauration 1d = 692 and obnect tvne =SELECT * SROM com fields WHERE 1d = 226147-SELECT * EROM eom field values WHERE com field 1d = 226147.SELECT * FROM crm_configurations WHERE id = 692;SELSCTCONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '• END) AS user_id,nemailiSa.xt.owner id FROM social accounts saJOIN users u on u.id = sa.sociable idJOIN teams t 1..n<->1: on t.id = u.team idWHERE U.team id = 711 and sa.provider = 'salesforce':SELECT * FROM crm profiles co JOIN users u 1..n<->1: on u.id = co.user id WHERE u.team_id = 711:select * from leads:select * from calendars:SELECTS0 hlsuppont Dally • In Zn 10m100% L2• Wed 13 May 12:44:45AskJiminnyReportActivityServiceTest -CascadeTrial Owner Role Selec+0 ..kead kegistercontroller.php ana OnboardController.pnp ›Searched UserRegistered invitation. accept in ~/iminnyappThought for 3s ›Read UpdateProtile.phg0// tasks done ?• Review current role assianment when owner sians in7 Document findinas and provide imolementation olanInoughttor 4s7 7 tasks done)Ihought for 4SCurrent Flow Analvsis: Owner Role Assianment in Trial CreationBackend Flow1. Team Creation Entrv Point• TeamController::store() (lines 24-45)app Actions/InviteUsertoreamaction.php the team• Calls InviteUserToTeamAction with UserInvitationDTO: : for0wner(Srequest, Steam)2. Owner Role Assianment (HARDCODED)• UserInvitationDTO:: for0wner() (lines 52-72 in/app/DTO/Invitation/UserInvitationDT0.php)•Lines 54-57: This is where the owner's role is hardcodediohrUser:: ROLE RECORDER,→>oluck("id')→>toArravo:•Alwavs assians ROLE ADMIN + ROLE RECORDER to the ownenThic ic the koy ioention that noode modification3. Invitation Creatior•InviteUserToTeamAction::execute@ (lines 28-81)• Creates an Invitation with roles from the DTO (line 45: Sinvitation->roles()->sync(Sdto->roleIds))• Sends OwnerInvitedToTrial notificationl1 Owner Sian-in FlowOwner receives email invitation• Regrstercontroller:: showRegnstratonformo shows registration form with invitation dataOwner redisters and accents invitationRoles are already assigned via the invitation, so owner gets ROLE ADMIN + ROLE RECORDER automaticallvFrontend FlowAsk anvthina (84-D)« Code SWF-1.6O0 1WN Windsurf Teams26.52UTE.8io 4 spaces...
|
32893
|
NULL
|
NULL
|
NULL
|
|
32896
|
1257
|
12
|
2026-05-13T09:44:49.664672+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665489664_m2.jpg...
|
PhpStorm
|
faVsco.js – CreateTeam.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
Analyzing…
<?php
declare(strict_types=1);
namespace Jiminny\Interactions\Settings\Teams;
use Illuminate\Contracts\Events\Dispatcher;
use Jiminny\Component\FeatureFlags\FeatureFlagsManager;
use Jiminny\Contracts\Crm\Providers;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Enums\TeamSetting;
use Jiminny\Events\Teams\TeamCreated;
use Jiminny\Contracts\Repositories\TeamRepository;
use Jiminny\Models\Activity;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Models\TeamSettings;
use Jiminny\Models\User;
use Jiminny\Repositories\ActivityProviderRepository;
use Jiminny\Repositories\TeamDomainsRepository;
use Jiminny\Services\Crm\BaseService;
use Jiminny\Services\Crm\ProviderRegistry;
final readonly class CreateTeam
{
public function __construct(
private ProviderRegistry $crmRegistry,
private FeatureFlagsManager $featureFlagsManager,
private TeamRepository $teamRepository,
private Dispatcher $eventDispatcher,
private ActivityProviderRepository $activityProviderRepository,
private TeamDomainsRepository $domainsRepository,
) {
}
public function handle(User $teamCreator, array $data, string $domain): Team
{
// Default to the creator's partner when not explicitly specified (e.g. non-default partner kiosk users).
$data['partner_id'] ??= $teamCreator->getTeam()->getPartner()->getUuid();
$team = $this->teamRepository->create($data);
// Update the billing address.
$this->teamRepository->updateBillingAddress($team, $data);
$this->domainsRepository->create($team, $domain);
$newFeatures = [];
foreach ($data['features'] as $feature) {
$newFeatures[] = FeatureEnum::fromName($feature);
}
foreach ($newFeatures as $feature) {
$this->featureFlagsManager->assignFeatureToTeam($feature, $team);
}
$this->teamRepository->createTeamSetting($team, [
'name' => TeamSetting::RETENTION_POLICY->name(),
'value_type' => 'integer',
'value' => TeamSettings::DEFAULT_RETENTION_POLICY,
]);
$this->enableLiveVideoCoachingIfNeeded($team);
$crmEdition = null;
$crmProviderKey = $data['crm'];
if (Providers::isIntegrationAppProvider($data['crm'])) {
$crmProviderKey = Providers::getTranslatedCrmProviderKey($data['crm']);
$crmEdition = $data['crm'];
}
/** @var ServiceInterface&BaseService $crmService */
$crmService = $this->crmRegistry->get($crmProviderKey);
$configurationData = [
'provider' => $crmProviderKey,
'edition' => $crmEdition,
'version' => $crmService->getMinimumApiVersion(),
];
if (isset($data['opportunity_sync_period'])) {
$configurationData['settings']['opportunity_sync_period'] = $data['opportunity_sync_period'];
}
$this->teamRepository->createTeamCrmConfiguration($team, $configurationData);
// Uploader provider is available for all teams. We create it when the team is created.
$this->activityProviderRepository->create($team, Activity::PROVIDER_UPLOADER);
$this->eventDispatcher->dispatch(new TeamCreated($team, $teamCreator));
return $team;
}
private function enableLiveVideoCoachingIfNeeded(Team $team): void
{
if ($team->hasFeature(FeatureEnum::VIDEOCOACH)) {
$team->toggleCoachingVideoLiveStream(true);
}
}
}
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
40...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.034242023,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"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":"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":"AXStaticText","text":"Analyzing…","depth":4,"bounds":{"left":0.3849734,"top":0.07581804,"width":0.019946808,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Interactions\\Settings\\Teams;\n\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Jiminny\\Component\\FeatureFlags\\FeatureFlagsManager;\nuse Jiminny\\Contracts\\Crm\\Providers;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Enums\\TeamSetting;\nuse Jiminny\\Events\\Teams\\TeamCreated;\nuse Jiminny\\Contracts\\Repositories\\TeamRepository;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\TeamSettings;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ActivityProviderRepository;\nuse Jiminny\\Repositories\\TeamDomainsRepository;\nuse Jiminny\\Services\\Crm\\BaseService;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\n\nfinal readonly class CreateTeam\n{\n public function __construct(\n private ProviderRegistry $crmRegistry,\n private FeatureFlagsManager $featureFlagsManager,\n private TeamRepository $teamRepository,\n private Dispatcher $eventDispatcher,\n private ActivityProviderRepository $activityProviderRepository,\n private TeamDomainsRepository $domainsRepository,\n ) {\n }\n\n public function handle(User $teamCreator, array $data, string $domain): Team\n {\n // Default to the creator's partner when not explicitly specified (e.g. non-default partner kiosk users).\n $data['partner_id'] ??= $teamCreator->getTeam()->getPartner()->getUuid();\n\n $team = $this->teamRepository->create($data);\n // Update the billing address.\n $this->teamRepository->updateBillingAddress($team, $data);\n\n $this->domainsRepository->create($team, $domain);\n\n $newFeatures = [];\n foreach ($data['features'] as $feature) {\n $newFeatures[] = FeatureEnum::fromName($feature);\n }\n\n foreach ($newFeatures as $feature) {\n $this->featureFlagsManager->assignFeatureToTeam($feature, $team);\n }\n\n $this->teamRepository->createTeamSetting($team, [\n 'name' => TeamSetting::RETENTION_POLICY->name(),\n 'value_type' => 'integer',\n 'value' => TeamSettings::DEFAULT_RETENTION_POLICY,\n ]);\n\n $this->enableLiveVideoCoachingIfNeeded($team);\n\n $crmEdition = null;\n $crmProviderKey = $data['crm'];\n if (Providers::isIntegrationAppProvider($data['crm'])) {\n $crmProviderKey = Providers::getTranslatedCrmProviderKey($data['crm']);\n $crmEdition = $data['crm'];\n }\n\n /** @var ServiceInterface&BaseService $crmService */\n $crmService = $this->crmRegistry->get($crmProviderKey);\n\n $configurationData = [\n 'provider' => $crmProviderKey,\n 'edition' => $crmEdition,\n 'version' => $crmService->getMinimumApiVersion(),\n ];\n\n if (isset($data['opportunity_sync_period'])) {\n $configurationData['settings']['opportunity_sync_period'] = $data['opportunity_sync_period'];\n }\n\n $this->teamRepository->createTeamCrmConfiguration($team, $configurationData);\n\n // Uploader provider is available for all teams. We create it when the team is created.\n $this->activityProviderRepository->create($team, Activity::PROVIDER_UPLOADER);\n\n $this->eventDispatcher->dispatch(new TeamCreated($team, $teamCreator));\n\n return $team;\n }\n\n private function enableLiveVideoCoachingIfNeeded(Team $team): void\n {\n if ($team->hasFeature(FeatureEnum::VIDEOCOACH)) {\n $team->toggleCoachingVideoLiveStream(true);\n }\n }\n}","depth":4,"bounds":{"left":0.122340426,"top":0.0726257,"width":0.2855718,"height":0.9066241},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Interactions\\Settings\\Teams;\n\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Jiminny\\Component\\FeatureFlags\\FeatureFlagsManager;\nuse Jiminny\\Contracts\\Crm\\Providers;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Enums\\TeamSetting;\nuse Jiminny\\Events\\Teams\\TeamCreated;\nuse Jiminny\\Contracts\\Repositories\\TeamRepository;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\TeamSettings;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ActivityProviderRepository;\nuse Jiminny\\Repositories\\TeamDomainsRepository;\nuse Jiminny\\Services\\Crm\\BaseService;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\n\nfinal readonly class CreateTeam\n{\n public function __construct(\n private ProviderRegistry $crmRegistry,\n private FeatureFlagsManager $featureFlagsManager,\n private TeamRepository $teamRepository,\n private Dispatcher $eventDispatcher,\n private ActivityProviderRepository $activityProviderRepository,\n private TeamDomainsRepository $domainsRepository,\n ) {\n }\n\n public function handle(User $teamCreator, array $data, string $domain): Team\n {\n // Default to the creator's partner when not explicitly specified (e.g. non-default partner kiosk users).\n $data['partner_id'] ??= $teamCreator->getTeam()->getPartner()->getUuid();\n\n $team = $this->teamRepository->create($data);\n // Update the billing address.\n $this->teamRepository->updateBillingAddress($team, $data);\n\n $this->domainsRepository->create($team, $domain);\n\n $newFeatures = [];\n foreach ($data['features'] as $feature) {\n $newFeatures[] = FeatureEnum::fromName($feature);\n }\n\n foreach ($newFeatures as $feature) {\n $this->featureFlagsManager->assignFeatureToTeam($feature, $team);\n }\n\n $this->teamRepository->createTeamSetting($team, [\n 'name' => TeamSetting::RETENTION_POLICY->name(),\n 'value_type' => 'integer',\n 'value' => TeamSettings::DEFAULT_RETENTION_POLICY,\n ]);\n\n $this->enableLiveVideoCoachingIfNeeded($team);\n\n $crmEdition = null;\n $crmProviderKey = $data['crm'];\n if (Providers::isIntegrationAppProvider($data['crm'])) {\n $crmProviderKey = Providers::getTranslatedCrmProviderKey($data['crm']);\n $crmEdition = $data['crm'];\n }\n\n /** @var ServiceInterface&BaseService $crmService */\n $crmService = $this->crmRegistry->get($crmProviderKey);\n\n $configurationData = [\n 'provider' => $crmProviderKey,\n 'edition' => $crmEdition,\n 'version' => $crmService->getMinimumApiVersion(),\n ];\n\n if (isset($data['opportunity_sync_period'])) {\n $configurationData['settings']['opportunity_sync_period'] = $data['opportunity_sync_period'];\n }\n\n $this->teamRepository->createTeamCrmConfiguration($team, $configurationData);\n\n // Uploader provider is available for all teams. We create it when the team is created.\n $this->activityProviderRepository->create($team, Activity::PROVIDER_UPLOADER);\n\n $this->eventDispatcher->dispatch(new TeamCreated($team, $teamCreator));\n\n return $team;\n }\n\n private function enableLiveVideoCoachingIfNeeded(Team $team): void\n {\n if ($team->hasFeature(FeatureEnum::VIDEOCOACH)) {\n $team->toggleCoachingVideoLiveStream(true);\n }\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.40957448,"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.41821808,"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.42918882,"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.43783244,"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.44647607,"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.4574468,"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.46841756,"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.4950133,"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.50598407,"top":0.09896249,"width":0.029587766,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"bounds":{"left":0.7084442,"top":0.09896249,"width":0.02825798,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"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":"40","depth":4,"bounds":{"left":0.67785907,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"}]...
|
1777509215435930321
|
-7301770507382486012
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
Analyzing…
<?php
declare(strict_types=1);
namespace Jiminny\Interactions\Settings\Teams;
use Illuminate\Contracts\Events\Dispatcher;
use Jiminny\Component\FeatureFlags\FeatureFlagsManager;
use Jiminny\Contracts\Crm\Providers;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Enums\TeamSetting;
use Jiminny\Events\Teams\TeamCreated;
use Jiminny\Contracts\Repositories\TeamRepository;
use Jiminny\Models\Activity;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Models\TeamSettings;
use Jiminny\Models\User;
use Jiminny\Repositories\ActivityProviderRepository;
use Jiminny\Repositories\TeamDomainsRepository;
use Jiminny\Services\Crm\BaseService;
use Jiminny\Services\Crm\ProviderRegistry;
final readonly class CreateTeam
{
public function __construct(
private ProviderRegistry $crmRegistry,
private FeatureFlagsManager $featureFlagsManager,
private TeamRepository $teamRepository,
private Dispatcher $eventDispatcher,
private ActivityProviderRepository $activityProviderRepository,
private TeamDomainsRepository $domainsRepository,
) {
}
public function handle(User $teamCreator, array $data, string $domain): Team
{
// Default to the creator's partner when not explicitly specified (e.g. non-default partner kiosk users).
$data['partner_id'] ??= $teamCreator->getTeam()->getPartner()->getUuid();
$team = $this->teamRepository->create($data);
// Update the billing address.
$this->teamRepository->updateBillingAddress($team, $data);
$this->domainsRepository->create($team, $domain);
$newFeatures = [];
foreach ($data['features'] as $feature) {
$newFeatures[] = FeatureEnum::fromName($feature);
}
foreach ($newFeatures as $feature) {
$this->featureFlagsManager->assignFeatureToTeam($feature, $team);
}
$this->teamRepository->createTeamSetting($team, [
'name' => TeamSetting::RETENTION_POLICY->name(),
'value_type' => 'integer',
'value' => TeamSettings::DEFAULT_RETENTION_POLICY,
]);
$this->enableLiveVideoCoachingIfNeeded($team);
$crmEdition = null;
$crmProviderKey = $data['crm'];
if (Providers::isIntegrationAppProvider($data['crm'])) {
$crmProviderKey = Providers::getTranslatedCrmProviderKey($data['crm']);
$crmEdition = $data['crm'];
}
/** @var ServiceInterface&BaseService $crmService */
$crmService = $this->crmRegistry->get($crmProviderKey);
$configurationData = [
'provider' => $crmProviderKey,
'edition' => $crmEdition,
'version' => $crmService->getMinimumApiVersion(),
];
if (isset($data['opportunity_sync_period'])) {
$configurationData['settings']['opportunity_sync_period'] = $data['opportunity_sync_period'];
}
$this->teamRepository->createTeamCrmConfiguration($team, $configurationData);
// Uploader provider is available for all teams. We create it when the team is created.
$this->activityProviderRepository->create($team, Activity::PROVIDER_UPLOADER);
$this->eventDispatcher->dispatch(new TeamCreated($team, $teamCreator));
return $team;
}
private function enableLiveVideoCoachingIfNeeded(Team $team): void
{
if ($team->hasFeature(FeatureEnum::VIDEOCOACH)) {
$team->toggleCoachingVideoLiveStream(true);
}
}
}
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
40...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
32897
|
1256
|
15
|
2026-05-13T09:44:48.198363+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665488198_m1.jpg...
|
PhpStorm
|
faVsco.js – CreateTeam.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
SlackFile Edit ViewGoHistoryWindowHelpAPPDOCKER-dS SlackFile Edit ViewGoHistoryWindowHelpAPPDOCKER-dSTDEV (docker)₴82APP (-zshtests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleterTest.phptests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesProviderTest.phptests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesUploaderTest.phptests/Unit/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeeches?tests/Unit/Component/Transcription/Diarization/Source/MeetingBotSourceTest.phptests/Unit/Contracts/Services/Calendar/CalendarTraitTest.phptests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.phptests/Unit/Jobs/Activity/Import/ImportTwilioVideoSpeechesJobTest.phptests/Unit/Jobs/Activity/Import/IsActivityReadyForProcessingJobTest.phptests/Unit/Jobs/Calendar/SetupCalendarSyncTest.phptests/Unit/Services/Activity/ParticipantsServiceTest.phptests/Unit/Services/Calendar/Command/ImportParticipantsTest.phptests/Unit/Services/Calendar/GoogleCalendarServiceTest.phptests/Unit/Services/Crm/Close/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTest.phptests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTraitMatchActivitiesTest.phytests/Unit/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTraitOpportunitiesTe:tests/Unit/Services/Crm/Pipedrive/ImportOpportunityMatchActivitiesTest.phptests/Unit/Services/Crm/Salesforce/ServiceTest.phptests/Unit/Services/Mail/0ffice/EmailApiClientTest.phptests/Unit/Services/RecallAI/RecallAIServiceTest.php113 files changed, 4143 insertions(+), 1740 deletions(-)create mode 120000 CLAUDE.mdcreate mode 100644 app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.phpdelete mode 100644 app/Component/ES/ElasticSearchWorkerManager.phpdelete mode 100644 app/Component/ES/Worker/ActivityWorker.phpdelete mode 100644 app/Component/ES/Worker/EntityWorker.phpdelete mode100644 app/Component/ES/Worker/WorkerAmount.phpdelete mode100644 app/Component/ES/Worker/WorkerInterface.phpcreate mode100644 app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.phtcreate mode100644 app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/Assembl:create mode100644 app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNot(create mode 100644 app/Console/Commands/Crm/Backfill0pportunityUserFromAccountCommand.phpdelete mode 100644 app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.phpcreate mode100644 front-end/src/components/shared/modals/EntityPickerModal/__tests__/us‹create mode 100644 tests/Feature/Component/Nudge/Process0rganisationImmediateNudgesJobTe:create mode 100644 tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheck‹delete mode 100644 tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/ActivityWorkerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/EntityWorkerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/WorkerAmountTest.phpcreate mode 100644 tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCr‹create mode 100644 tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.phpLukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ I|HomeDMsActivityFilesLaterMore(aol§ Support Daily - in 2h 16 m100% <78•Wed 13 May12:44:48ED-→Describe what you are looking forJiminny ...Nikolay Ivanov6 0curoaroylau# engineering# general# jiminny-bg# platform-tickets# product_launches#random# releases# sofia-office# support# thank-yous# the_people_of jimi...MessagesAdd canvas@ Files+Lukas Kovalik 11.Today ~мен все ме праща наhttps://app.vanta.com/c/jiminny.com/employee/onboardingNikolay Ivanov 11:01 AMХм, Джейс дали не може да ти помогне?Lukas Kovalik 11:01 AMще питам James, предполагам че нямам правада мерсиNikolay Ivanov 11:01 AMмда° Direct messages& Nikolay Ivanovdo James Graham. Stoyan Tanev. Galya Dimitrova. Steliyan Georgievo Petko Kashinski®. Aneliya Angelovaã. Stefka Stoyanova•. Vasil Vasilev •!Lukas Kovalik y...МОЛЯLukas Kovalik 12:13 PMНики сори, още един въпрос имамкогато ги правеше ти FE ли оправяима vulnerabilities no npmNikolay Ivanov 12:28 PMнетях ги оставямLukas Kovalik 12:29 PMаз погледнах твоя тикет и там друго нямашесамо FEкак стигна до Workerl:: AppsJira CloudMessage Nikolay IvanovToast...
|
NULL
|
4489823893543965296
|
NULL
|
click
|
ocr
|
NULL
|
SlackFile Edit ViewGoHistoryWindowHelpAPPDOCKER-dS SlackFile Edit ViewGoHistoryWindowHelpAPPDOCKER-dSTDEV (docker)₴82APP (-zshtests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleterTest.phptests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesProviderTest.phptests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesUploaderTest.phptests/Unit/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeeches?tests/Unit/Component/Transcription/Diarization/Source/MeetingBotSourceTest.phptests/Unit/Contracts/Services/Calendar/CalendarTraitTest.phptests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.phptests/Unit/Jobs/Activity/Import/ImportTwilioVideoSpeechesJobTest.phptests/Unit/Jobs/Activity/Import/IsActivityReadyForProcessingJobTest.phptests/Unit/Jobs/Calendar/SetupCalendarSyncTest.phptests/Unit/Services/Activity/ParticipantsServiceTest.phptests/Unit/Services/Calendar/Command/ImportParticipantsTest.phptests/Unit/Services/Calendar/GoogleCalendarServiceTest.phptests/Unit/Services/Crm/Close/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTest.phptests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTraitMatchActivitiesTest.phytests/Unit/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTraitOpportunitiesTe:tests/Unit/Services/Crm/Pipedrive/ImportOpportunityMatchActivitiesTest.phptests/Unit/Services/Crm/Salesforce/ServiceTest.phptests/Unit/Services/Mail/0ffice/EmailApiClientTest.phptests/Unit/Services/RecallAI/RecallAIServiceTest.php113 files changed, 4143 insertions(+), 1740 deletions(-)create mode 120000 CLAUDE.mdcreate mode 100644 app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.phpdelete mode 100644 app/Component/ES/ElasticSearchWorkerManager.phpdelete mode 100644 app/Component/ES/Worker/ActivityWorker.phpdelete mode 100644 app/Component/ES/Worker/EntityWorker.phpdelete mode100644 app/Component/ES/Worker/WorkerAmount.phpdelete mode100644 app/Component/ES/Worker/WorkerInterface.phpcreate mode100644 app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.phtcreate mode100644 app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/Assembl:create mode100644 app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNot(create mode 100644 app/Console/Commands/Crm/Backfill0pportunityUserFromAccountCommand.phpdelete mode 100644 app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.phpcreate mode100644 front-end/src/components/shared/modals/EntityPickerModal/__tests__/us‹create mode 100644 tests/Feature/Component/Nudge/Process0rganisationImmediateNudgesJobTe:create mode 100644 tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheck‹delete mode 100644 tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/ActivityWorkerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/EntityWorkerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/WorkerAmountTest.phpcreate mode 100644 tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCr‹create mode 100644 tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.phpLukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ I|HomeDMsActivityFilesLaterMore(aol§ Support Daily - in 2h 16 m100% <78•Wed 13 May12:44:48ED-→Describe what you are looking forJiminny ...Nikolay Ivanov6 0curoaroylau# engineering# general# jiminny-bg# platform-tickets# product_launches#random# releases# sofia-office# support# thank-yous# the_people_of jimi...MessagesAdd canvas@ Files+Lukas Kovalik 11.Today ~мен все ме праща наhttps://app.vanta.com/c/jiminny.com/employee/onboardingNikolay Ivanov 11:01 AMХм, Джейс дали не може да ти помогне?Lukas Kovalik 11:01 AMще питам James, предполагам че нямам правада мерсиNikolay Ivanov 11:01 AMмда° Direct messages& Nikolay Ivanovdo James Graham. Stoyan Tanev. Galya Dimitrova. Steliyan Georgievo Petko Kashinski®. Aneliya Angelovaã. Stefka Stoyanova•. Vasil Vasilev •!Lukas Kovalik y...МОЛЯLukas Kovalik 12:13 PMНики сори, още един въпрос имамкогато ги правеше ти FE ли оправяима vulnerabilities no npmNikolay Ivanov 12:28 PMнетях ги оставямLukas Kovalik 12:29 PMаз погледнах твоя тикет и там друго нямашесамо FEкак стигна до Workerl:: AppsJira CloudMessage Nikolay IvanovToast...
|
32894
|
NULL
|
NULL
|
NULL
|
|
32898
|
1257
|
13
|
2026-05-13T09:44:51.088727+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665491088_m2.jpg...
|
PhpStorm
|
faVsco.js – CreateTeam.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
Analyzing…
<?php
declare(strict_types=1);
namespace Jiminny\Interactions\Settings\Teams;
use Illuminate\Contracts\Events\Dispatcher;
use Jiminny\Component\FeatureFlags\FeatureFlagsManager;
use Jiminny\Contracts\Crm\Providers;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Enums\TeamSetting;
use Jiminny\Events\Teams\TeamCreated;
use Jiminny\Contracts\Repositories\TeamRepository;
use Jiminny\Models\Activity;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Models\TeamSettings;
use Jiminny\Models\User;
use Jiminny\Repositories\ActivityProviderRepository;
use Jiminny\Repositories\TeamDomainsRepository;
use Jiminny\Services\Crm\BaseService;
use Jiminny\Services\Crm\ProviderRegistry;
final readonly class CreateTeam
{
public function __construct(
private ProviderRegistry $crmRegistry,
private FeatureFlagsManager $featureFlagsManager,
private TeamRepository $teamRepository,
private Dispatcher $eventDispatcher,
private ActivityProviderRepository $activityProviderRepository,
private TeamDomainsRepository $domainsRepository,
) {
}
public function handle(User $teamCreator, array $data, string $domain): Team
{
// Default to the creator's partner when not explicitly specified (e.g. non-default partner kiosk users).
$data['partner_id'] ??= $teamCreator->getTeam()->getPartner()->getUuid();
$team = $this->teamRepository->create($data);
// Update the billing address.
$this->teamRepository->updateBillingAddress($team, $data);
$this->domainsRepository->create($team, $domain);
$newFeatures = [];
foreach ($data['features'] as $feature) {
$newFeatures[] = FeatureEnum::fromName($feature);
}
foreach ($newFeatures as $feature) {
$this->featureFlagsManager->assignFeatureToTeam($feature, $team);
}
$this->teamRepository->createTeamSetting($team, [
'name' => TeamSetting::RETENTION_POLICY->name(),
'value_type' => 'integer',
'value' => TeamSettings::DEFAULT_RETENTION_POLICY,
]);
$this->enableLiveVideoCoachingIfNeeded($team);
$crmEdition = null;
$crmProviderKey = $data['crm'];
if (Providers::isIntegrationAppProvider($data['crm'])) {
$crmProviderKey = Providers::getTranslatedCrmProviderKey($data['crm']);
$crmEdition = $data['crm'];
}
/** @var ServiceInterface&BaseService $crmService */
$crmService = $this->crmRegistry->get($crmProviderKey);
$configurationData = [
'provider' => $crmProviderKey,
'edition' => $crmEdition,
'version' => $crmService->getMinimumApiVersion(),
];
if (isset($data['opportunity_sync_period'])) {
$configurationData['settings']['opportunity_sync_period'] = $data['opportunity_sync_period'];
}
$this->teamRepository->createTeamCrmConfiguration($team, $configurationData);
// Uploader provider is available for all teams. We create it when the team is created.
$this->activityProviderRepository->create($team, Activity::PROVIDER_UPLOADER);
$this->eventDispatcher->dispatch(new TeamCreated($team, $teamCreator));
return $team;
}
private function enableLiveVideoCoachingIfNeeded(Team $team): void
{
if ($team->hasFeature(FeatureEnum::VIDEOCOACH)) {
$team->toggleCoachingVideoLiveStream(true);
}
}
}
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
40
1
40
64
Previous Highlighted Error
Next Highlighted Error
SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993
SELECT * FROM users WHERE id = 25061;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 994;
SELECT * FROM crm_profiles WHERE user_id = 25061;
select * from crm_configurations where id = 834;
SELECT * FROM teams WHERE id = 882;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;
SELECT * FROM contacts where crm_configuration_id = 834;
SELECT * FROM opportunities WHERE team_id = 933
# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');
AND id IN (8482561,18352941,19042734,19232139,19445140,19472541);
SELECT * FROM opportunity_contacts
WHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 485; #
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
select crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id
where crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')
# and l.converted_at IS NOT NULL
;
# [PASSWORD_DOTS]
SELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')
and opportunity_id IS NULL
order by id desc;
SELECT * FROM teams WHERE id = 604; # 598
SELECT * FROM activities WHERE id = 74410828; # [EMAIL]
SELECT * FROM accounts WHERE id = 20068382;
SELECT * FROM accounts WHERE id = 35186038;
SELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 559 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;
select * from sidekick_settings where team_id = 781;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100
SELECT * FROM crm_layouts WHERE crm_configuration_id = 711;
SELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL
and is_internal = 0 and status = 'completed'
order by id desc;
SELECT * FROM crm_layout_entities
WHERE crm_layout_id IN (2352, 2353);
;
SELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 556 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;
SELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;
select * from contacts
where crm_configuration_id = 530
and crm_provider_id = 872252;
select * from activities where crm_configuration_id = 530
and user_id = 14343 and type like '%softphone%'
and created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);
SELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t
JOIN crm_configurations c ON t.id = c.team_id
WHERE t.status = 'active';
SELECT * FROM teams where id = 1091;
SELECT * FROM crm_configurations where team_id = 1091;
SELECT * FROM activity_providers where team_id = 1091;
SELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT * FROM teams WHERE name LIKE '%Leadventure%';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1091 and sa.provider = 'salesforce';
SELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812
SELECT * FROM teams where id = 862;
SELECT * FROM crm_configurations where team_id = 862;
SELECT * FROM activity_providers where team_id = 862;
SELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT t.id, crm.id, crm.provider, ap.* FROM teams t
join crm_configurations crm on t.id = crm.team_id
join activity_providers ap on t.id = ap.team_id
where t.status = 'active' and ap.is_enabled = 1
and crm.provider = 'hubspot'
and ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',
'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');
SELECT * FROM teams where id = 1068;
SELECT * FROM crm_configurations where team_id = 1068;
SELECT * FROM activity_providers where team_id = 1068;
SELECT * FROM activities a
where crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')
and a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'
)
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by a.id desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1068 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262
SELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
select * from crm_layouts where crm_configuration_id = 834;
select * from crm_layout_entities where crm_layout_id = 2780;
select * from crm_fields where id IN (321153,321192,321193,321194);
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1057 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8
SELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20
SELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10
SELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #
SELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;
select * from users where team_id = 51; # 7783
SELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130
select * from activity_searches where user_id = 7783;
select * from activity_search_filters where activity_search_id IN (32291, 32292);
SELECT asf.activity_search_id, asf.id, asf.value
FROM activity_search_filters asf
WHERE asf.filter = 'group_id'
AND asf.value IN (
SELECT CONCAT(
HEX(SUBSTR(uuid, 5, 4)), '-',
HEX(SUBSTR(uuid, 3, 2)), '-',
HEX(SUBSTR(uuid, 1, 2)), '-',
HEX(SUBSTR(uuid, 9, 2)), '-',
HEX(SUBSTR(uuid, 11))
)
FROM groups
WHERE deleted_at IS NOT NULL
);
SELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where provider = 'hubspot';
SELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133
SELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null
# [PASSWORD_DOTS]
select * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';
select
cp.*
# DISTINCT t.id
# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields
FROM crm_profiles cp
JOIN crm_configurations crm on crm.id = cp.crm_configuration_id
JOIN users u on u.id = cp.user_id
JOIN teams t ON t.id = crm.team_id
WHERE crm.provider = 'salesforce' and t.status = 'active'
and cp.archived_at IS NULL and u.deleted_at IS NULL
and t.id NOT IN (1093)
and t.id = 2
and cp.contact_fields IS NULL;
# and c.crm_provider_id = '003Uu00000ojD4NIAU';
SELECT * FROM users WHERE id = 26484;
SELECT * FROM crm_profiles WHERE user_id = 26484;
SELECT * FROM social_accounts WHERE sociable_id = 26484;
SELECT * FROM crm_configurations where provider = 'salesforce';
select * from users where id IN (10022, 10403);
select * from users where team_id IN (526);
select * from teams where id IN (526, 532);
select * from crm_configurations where id IN (500, 516);
select * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);
select * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 526 and sa.provider = 'salesforce';
select * from team_settings where team_id IN (526, 532);
select * from users where id IN (22824);
select * from crm_profiles where crm_configuration_id IN (1026);
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1093 and sa.provider = 'salesforce';
select * from teams where id = 1099;
select * from users where id = 29643
select * from activity_processing_states;
SELECT * FROM teams where name LIKE '%Fare%'; # 233
SELECT * FROM opportunities where crm_configuration_id = 215
# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'
;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1088 and sa.provider = 'hubspot';
SELECT * FROM teams order by updated_at DESC
SELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account
select * from crm_configurations where provider = 'pipedrive';
select * from teams where id = 957;
select * from crm_configurations where id = 957;
SELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743
SELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;
select * from users where team_id = 1; # 26726 - Gabriela Dureva
SELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific
select * from activities where user_id = 26726 order by id desc;
select * from contacts where crm_configuration_id = 1
and email IN ('[EMAIL]', '[EMAIL]'); # 2094416, 2093620
SELECT * FROM contacts WHERE id = 6284931;
SELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id
WHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;
select * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);
select * from crm_configurations where id = 1;
43801692-1aeb-32ce-acba-5b80a479701a
44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b
405975c0-b3d0-7aaa-821f-09d59cae6dd1
4caf848d-4bed-2299-b248-7788d41f9fca
49bedc3f-f196-eef3-89c3-dea6a3b4aa63
43420989-a09d-b8f8-9806-c8bbf7a02aac
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
SELECT * FROM activities WHERE id = 75461988;
SELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;
select * from contacts where id = 17900517;
select * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id
where crm.provider != 'salesforce';
select * from users where id = 21047;
SELECT * FROM crm_configurations WHERE id = 892;
SELECT * FROM teams WHERE id = 942;
select * from opportunities where team_id = 942 order by updated_at desc;
select * from contacts where team_id = 942 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 942 and sa.provider = 'hubspot';
SELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430
SELECT * FROM crm_configurations WHERE id = 1;
SELECT * FROM teams WHERE crm_id = 1;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
select id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1
SELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430
select * from teams where id = 852;
select * from groups where id = 2286;
select * from sidekick_settings where team_id = 852;
select * from default_activity_types where team_id = 852;
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1 AND u.deleted_at IS NULL
AND u.crm_required = 1
AND u.team_id = 1
ORDER BY u.team_id;
SELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (
18481
);
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1
AND u.deleted_at IS NULL
AND u.crm_required = 1
# AND u.team_id = 1
AND p.id IS NULL -- Move this condition to WHERE clause
ORDER BY u.team_id;
SELECT * FROM opportunities WHERE id = 20002609;
select * from teams where id = 1122; # Velatir, 29953 - [EMAIL]
select * from crm_configurations where id = 1060;
select * from crm_layouts where crm_configuration_id = 1060;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1122 and sa.provider = 'hubspot';
select * from opportunities where team_id = 1122 order by updated_at desc;
select * from crm_field_data where object_type = 'contact';
SELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 248 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS
SELECT * FROM users where id = 24115;
SELECT * FROM accounts where id = 4002896;
SELECT * FROM teams WHERE name LIKE '%adswerve%';
SELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN ("0069N000003GIQ9QAO","0061r000019yGP9AAM","0066900001S2KWlAAN","0066900001TDpj2AAD","0066900001b8uEwAAI","0069N000001rQi0QAE","006QF00000KD40mYAD","006QF00000LzpRJYAZ","0069N000002uomtQAA","0069N000002xlMLQAY","0066900001NV6ubAAD","0061r00001HJp45AAD","006QF00000uTlUoYAK","006QF00000v0bZqYAI");
SELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203
SELECT u.id, u.email, ac.name, a.* FROM activities a
JOIN users u ON a.user_id = u.id
JOIN accounts ac ON a.account_id = ac.id
WHERE
uuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or
uuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or
uuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;
select * from users where id = 5825;
SELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;
select * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;
19594, 862
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 862 and sa.provider = 'salesforce';
select * from automated_reports where id = 36;
select ar.frequency, r.*, ar.* from automated_report_results r
join automated_reports ar on r.report_id = ar.id
where ar.frequency != 'one_off';
select s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;
select * from nudges n where n.activity_search_id
select * from teams where created_at > '2026-03-09';
SELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;
select * from users where team_id = 1 and name like '%Lukas%'; # 7160
SELECT * FROM teams WHERE id = 575;
select * from opportunities where team_id = 575;
SELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,
select * from opportunities where team_id = 1126;
SELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,
select * from opportunities where team_id = 1125;
select * from contacts c
where c.team_id = 882;
SELECT * FROM activities WHERE id = 76822967;
SELECT * FROM crm_profiles WHERE user_id = 15440;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 555;
SELECT * FROM crm_configurations WHERE id = 555;
SELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 581 and sa.provider = 'salesforce';
SELECT * FROM automated_report_results order by id desc;
select * from features;
select * from team_features where feature_id = 40;
select * from teams where id = 556;
select * from automated_reports;
where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , ["pdf","podcast"]
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
select * from automated_report_results order by id desc;
SELECT * FROM automated_report_results WHERE id = 1919;
select * from automated_report_results WHERE report_id = 54;
select * from opportunities where id = 7594349;
SELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - [EMAIL]
select * from playbooks where team_id = 711; # event 226147
SELECT * FROM playbook_categories WHERE playbook_id = 5515;
SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';
SELECT * FROM crm_fields WHERE id = 226147;
SELECT * FROM crm_field_values WHERE crm_field_id = 226147;
SELECT * FROM crm_configurations WHERE id = 692;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 711 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;
select * from leads;
select * from calendars;
SELECT
t.id AS team_id,
t.name,
LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain
FROM teams t
JOIN users u ON u.team_id = t.id
JOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'
LEFT JOIN team_domains td
ON td.team_id = t.id
AND td.deleted_at IS NULL
AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))
GROUP BY t.id, t.name, calendar_domain
ORDER BY t.name, calendar_domain;
select * from users u join calendars c on c.user_id = u.id
where u.team_id = 882;
select * from activities where id = 74049485; # team 563 crm 537
select * from activities where id = 73272382; # team 563 crm 537
select * from activities where id = 64400389; # team 563 crm 537
select * from activities where id = 58081273; # team 563 crm 537
select * from activities where id = 54520297; # team 563 crm 537
select * from participants where activity_id = 58081273;
select * from activities where crm_configuration_id = 537 and provider = 'aircall'
and account_id = 19003658 order by updated_at desc;
select * from contacts where crm_configuration_id = 537 and id = 35957759;
select * from accounts where crm_configuration_id = 537 and id = 19003658;
select * from automated_report_results where id = 1976;
select * from automated_reports where id = 583;
select * from activity_searches where id = 87714;
select * from activity_search_filters where activity_search_id = 87714;
SELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid
or uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;
SELECT * FROM crm_configurations WHERE provider = 'hubspot';
select * from rate_limits;
select * from automated_report_results where media_type = 'pdf' and status = 2
and id IN (18, 1872);
select * from automated_reports where id = 54;
SELECT * FROM users WHERE id IN (24623,29443,29613);
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app, folder
.circleci, folder
.cursor, folder
.github
.sonarlint, folder
.vscode, folder
.windsurf, folder
app, sources root
Actions
InviteUserToTeamAction.php, class
MarkUserAsOnboardableAction.php, class
SyncRecordingFlagsAction.php, class
UpdateTeamMemberAction.php, class
UpdateUserRolesAction.php, class
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.034242023,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"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":"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":"AXStaticText","text":"Analyzing…","depth":4,"bounds":{"left":0.3849734,"top":0.07581804,"width":0.019946808,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Interactions\\Settings\\Teams;\n\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Jiminny\\Component\\FeatureFlags\\FeatureFlagsManager;\nuse Jiminny\\Contracts\\Crm\\Providers;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Enums\\TeamSetting;\nuse Jiminny\\Events\\Teams\\TeamCreated;\nuse Jiminny\\Contracts\\Repositories\\TeamRepository;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\TeamSettings;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ActivityProviderRepository;\nuse Jiminny\\Repositories\\TeamDomainsRepository;\nuse Jiminny\\Services\\Crm\\BaseService;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\n\nfinal readonly class CreateTeam\n{\n public function __construct(\n private ProviderRegistry $crmRegistry,\n private FeatureFlagsManager $featureFlagsManager,\n private TeamRepository $teamRepository,\n private Dispatcher $eventDispatcher,\n private ActivityProviderRepository $activityProviderRepository,\n private TeamDomainsRepository $domainsRepository,\n ) {\n }\n\n public function handle(User $teamCreator, array $data, string $domain): Team\n {\n // Default to the creator's partner when not explicitly specified (e.g. non-default partner kiosk users).\n $data['partner_id'] ??= $teamCreator->getTeam()->getPartner()->getUuid();\n\n $team = $this->teamRepository->create($data);\n // Update the billing address.\n $this->teamRepository->updateBillingAddress($team, $data);\n\n $this->domainsRepository->create($team, $domain);\n\n $newFeatures = [];\n foreach ($data['features'] as $feature) {\n $newFeatures[] = FeatureEnum::fromName($feature);\n }\n\n foreach ($newFeatures as $feature) {\n $this->featureFlagsManager->assignFeatureToTeam($feature, $team);\n }\n\n $this->teamRepository->createTeamSetting($team, [\n 'name' => TeamSetting::RETENTION_POLICY->name(),\n 'value_type' => 'integer',\n 'value' => TeamSettings::DEFAULT_RETENTION_POLICY,\n ]);\n\n $this->enableLiveVideoCoachingIfNeeded($team);\n\n $crmEdition = null;\n $crmProviderKey = $data['crm'];\n if (Providers::isIntegrationAppProvider($data['crm'])) {\n $crmProviderKey = Providers::getTranslatedCrmProviderKey($data['crm']);\n $crmEdition = $data['crm'];\n }\n\n /** @var ServiceInterface&BaseService $crmService */\n $crmService = $this->crmRegistry->get($crmProviderKey);\n\n $configurationData = [\n 'provider' => $crmProviderKey,\n 'edition' => $crmEdition,\n 'version' => $crmService->getMinimumApiVersion(),\n ];\n\n if (isset($data['opportunity_sync_period'])) {\n $configurationData['settings']['opportunity_sync_period'] = $data['opportunity_sync_period'];\n }\n\n $this->teamRepository->createTeamCrmConfiguration($team, $configurationData);\n\n // Uploader provider is available for all teams. We create it when the team is created.\n $this->activityProviderRepository->create($team, Activity::PROVIDER_UPLOADER);\n\n $this->eventDispatcher->dispatch(new TeamCreated($team, $teamCreator));\n\n return $team;\n }\n\n private function enableLiveVideoCoachingIfNeeded(Team $team): void\n {\n if ($team->hasFeature(FeatureEnum::VIDEOCOACH)) {\n $team->toggleCoachingVideoLiveStream(true);\n }\n }\n}","depth":4,"bounds":{"left":0.122340426,"top":0.0726257,"width":0.2855718,"height":0.9066241},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Interactions\\Settings\\Teams;\n\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Jiminny\\Component\\FeatureFlags\\FeatureFlagsManager;\nuse Jiminny\\Contracts\\Crm\\Providers;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Enums\\TeamSetting;\nuse Jiminny\\Events\\Teams\\TeamCreated;\nuse Jiminny\\Contracts\\Repositories\\TeamRepository;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\TeamSettings;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ActivityProviderRepository;\nuse Jiminny\\Repositories\\TeamDomainsRepository;\nuse Jiminny\\Services\\Crm\\BaseService;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\n\nfinal readonly class CreateTeam\n{\n public function __construct(\n private ProviderRegistry $crmRegistry,\n private FeatureFlagsManager $featureFlagsManager,\n private TeamRepository $teamRepository,\n private Dispatcher $eventDispatcher,\n private ActivityProviderRepository $activityProviderRepository,\n private TeamDomainsRepository $domainsRepository,\n ) {\n }\n\n public function handle(User $teamCreator, array $data, string $domain): Team\n {\n // Default to the creator's partner when not explicitly specified (e.g. non-default partner kiosk users).\n $data['partner_id'] ??= $teamCreator->getTeam()->getPartner()->getUuid();\n\n $team = $this->teamRepository->create($data);\n // Update the billing address.\n $this->teamRepository->updateBillingAddress($team, $data);\n\n $this->domainsRepository->create($team, $domain);\n\n $newFeatures = [];\n foreach ($data['features'] as $feature) {\n $newFeatures[] = FeatureEnum::fromName($feature);\n }\n\n foreach ($newFeatures as $feature) {\n $this->featureFlagsManager->assignFeatureToTeam($feature, $team);\n }\n\n $this->teamRepository->createTeamSetting($team, [\n 'name' => TeamSetting::RETENTION_POLICY->name(),\n 'value_type' => 'integer',\n 'value' => TeamSettings::DEFAULT_RETENTION_POLICY,\n ]);\n\n $this->enableLiveVideoCoachingIfNeeded($team);\n\n $crmEdition = null;\n $crmProviderKey = $data['crm'];\n if (Providers::isIntegrationAppProvider($data['crm'])) {\n $crmProviderKey = Providers::getTranslatedCrmProviderKey($data['crm']);\n $crmEdition = $data['crm'];\n }\n\n /** @var ServiceInterface&BaseService $crmService */\n $crmService = $this->crmRegistry->get($crmProviderKey);\n\n $configurationData = [\n 'provider' => $crmProviderKey,\n 'edition' => $crmEdition,\n 'version' => $crmService->getMinimumApiVersion(),\n ];\n\n if (isset($data['opportunity_sync_period'])) {\n $configurationData['settings']['opportunity_sync_period'] = $data['opportunity_sync_period'];\n }\n\n $this->teamRepository->createTeamCrmConfiguration($team, $configurationData);\n\n // Uploader provider is available for all teams. We create it when the team is created.\n $this->activityProviderRepository->create($team, Activity::PROVIDER_UPLOADER);\n\n $this->eventDispatcher->dispatch(new TeamCreated($team, $teamCreator));\n\n return $team;\n }\n\n private function enableLiveVideoCoachingIfNeeded(Team $team): void\n {\n if ($team->hasFeature(FeatureEnum::VIDEOCOACH)) {\n $team->toggleCoachingVideoLiveStream(true);\n }\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.40957448,"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.41821808,"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.42918882,"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.43783244,"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.44647607,"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.4574468,"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.46841756,"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.4950133,"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.50598407,"top":0.09896249,"width":0.029587766,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"bounds":{"left":0.7084442,"top":0.09896249,"width":0.02825798,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"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":"40","depth":4,"bounds":{"left":0.67785907,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.69015956,"top":0.123703115,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"40","depth":4,"bounds":{"left":0.6994681,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"64","depth":4,"bounds":{"left":0.7117686,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.7237367,"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.73105055,"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 * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","depth":4,"on_screen":true,"value":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","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,"bounds":{"left":0.020944148,"top":0.0,"width":0.045877658,"height":0.017557861},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".circleci, folder","depth":7,"bounds":{"left":0.027260639,"top":0.0,"width":0.023936171,"height":0.017557861},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".cursor, folder","depth":7,"bounds":{"left":0.027260639,"top":0.0,"width":0.022273935,"height":0.017557861},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"bounds":{"left":0.027260639,"top":0.0023942539,"width":0.022273935,"height":0.017557861},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint, folder","depth":7,"bounds":{"left":0.027260639,"top":0.019952115,"width":0.026928192,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".vscode, folder","depth":7,"bounds":{"left":0.027260639,"top":0.037509978,"width":0.024268618,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".windsurf, folder","depth":7,"bounds":{"left":0.027260639,"top":0.055067837,"width":0.026928192,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"bounds":{"left":0.027260639,"top":0.0726257,"width":0.015957447,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"bounds":{"left":0.03357713,"top":0.090183556,"width":0.023603724,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"InviteUserToTeamAction.php, class","depth":9,"bounds":{"left":0.039893616,"top":0.10774142,"width":0.06781915,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"MarkUserAsOnboardableAction.php, class","depth":9,"bounds":{"left":0.039893616,"top":0.12529927,"width":0.08178192,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SyncRecordingFlagsAction.php, class","depth":9,"bounds":{"left":0.039893616,"top":0.14285715,"width":0.07180851,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"UpdateTeamMemberAction.php, class","depth":9,"bounds":{"left":0.039893616,"top":0.16041501,"width":0.073803194,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"UpdateUserRolesAction.php, class","depth":9,"bounds":{"left":0.039893616,"top":0.17797287,"width":0.06582447,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"bounds":{"left":0.03357713,"top":0.19553073,"width":0.031914894,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"bounds":{"left":0.039893616,"top":0.21308859,"width":0.01462766,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems","depth":9,"bounds":{"left":0.039893616,"top":0.23064645,"width":0.032579787,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":9,"bounds":{"left":0.039893616,"top":0.2482043,"width":0.023603724,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"bounds":{"left":0.039893616,"top":0.26576218,"width":0.042220745,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch","depth":9,"bounds":{"left":0.039893616,"top":0.28332004,"width":0.037898935,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"bounds":{"left":0.039893616,"top":0.3008779,"width":0.037898935,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"bounds":{"left":0.039893616,"top":0.31843576,"width":0.03557181,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"bounds":{"left":0.039893616,"top":0.33599362,"width":0.03523936,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"bounds":{"left":0.039893616,"top":0.35355148,"width":0.033909574,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Dtos","depth":10,"bounds":{"left":0.046210106,"top":0.37110934,"width":0.01761968,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Events","depth":10,"bounds":{"left":0.046210106,"top":0.3886672,"width":0.021941489,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"bounds":{"left":0.046210106,"top":0.40622506,"width":0.0731383,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"bounds":{"left":0.046210106,"top":0.4237829,"width":0.04720745,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"bounds":{"left":0.039893616,"top":0.44134077,"width":0.03523936,"height":0.017557861},"on_screen":true,"role_description":"text"}]...
|
7051438119237299949
|
2218652951799805517
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
Analyzing…
<?php
declare(strict_types=1);
namespace Jiminny\Interactions\Settings\Teams;
use Illuminate\Contracts\Events\Dispatcher;
use Jiminny\Component\FeatureFlags\FeatureFlagsManager;
use Jiminny\Contracts\Crm\Providers;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Enums\TeamSetting;
use Jiminny\Events\Teams\TeamCreated;
use Jiminny\Contracts\Repositories\TeamRepository;
use Jiminny\Models\Activity;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Models\TeamSettings;
use Jiminny\Models\User;
use Jiminny\Repositories\ActivityProviderRepository;
use Jiminny\Repositories\TeamDomainsRepository;
use Jiminny\Services\Crm\BaseService;
use Jiminny\Services\Crm\ProviderRegistry;
final readonly class CreateTeam
{
public function __construct(
private ProviderRegistry $crmRegistry,
private FeatureFlagsManager $featureFlagsManager,
private TeamRepository $teamRepository,
private Dispatcher $eventDispatcher,
private ActivityProviderRepository $activityProviderRepository,
private TeamDomainsRepository $domainsRepository,
) {
}
public function handle(User $teamCreator, array $data, string $domain): Team
{
// Default to the creator's partner when not explicitly specified (e.g. non-default partner kiosk users).
$data['partner_id'] ??= $teamCreator->getTeam()->getPartner()->getUuid();
$team = $this->teamRepository->create($data);
// Update the billing address.
$this->teamRepository->updateBillingAddress($team, $data);
$this->domainsRepository->create($team, $domain);
$newFeatures = [];
foreach ($data['features'] as $feature) {
$newFeatures[] = FeatureEnum::fromName($feature);
}
foreach ($newFeatures as $feature) {
$this->featureFlagsManager->assignFeatureToTeam($feature, $team);
}
$this->teamRepository->createTeamSetting($team, [
'name' => TeamSetting::RETENTION_POLICY->name(),
'value_type' => 'integer',
'value' => TeamSettings::DEFAULT_RETENTION_POLICY,
]);
$this->enableLiveVideoCoachingIfNeeded($team);
$crmEdition = null;
$crmProviderKey = $data['crm'];
if (Providers::isIntegrationAppProvider($data['crm'])) {
$crmProviderKey = Providers::getTranslatedCrmProviderKey($data['crm']);
$crmEdition = $data['crm'];
}
/** @var ServiceInterface&BaseService $crmService */
$crmService = $this->crmRegistry->get($crmProviderKey);
$configurationData = [
'provider' => $crmProviderKey,
'edition' => $crmEdition,
'version' => $crmService->getMinimumApiVersion(),
];
if (isset($data['opportunity_sync_period'])) {
$configurationData['settings']['opportunity_sync_period'] = $data['opportunity_sync_period'];
}
$this->teamRepository->createTeamCrmConfiguration($team, $configurationData);
// Uploader provider is available for all teams. We create it when the team is created.
$this->activityProviderRepository->create($team, Activity::PROVIDER_UPLOADER);
$this->eventDispatcher->dispatch(new TeamCreated($team, $teamCreator));
return $team;
}
private function enableLiveVideoCoachingIfNeeded(Team $team): void
{
if ($team->hasFeature(FeatureEnum::VIDEOCOACH)) {
$team->toggleCoachingVideoLiveStream(true);
}
}
}
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
40
1
40
64
Previous Highlighted Error
Next Highlighted Error
SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993
SELECT * FROM users WHERE id = 25061;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 994;
SELECT * FROM crm_profiles WHERE user_id = 25061;
select * from crm_configurations where id = 834;
SELECT * FROM teams WHERE id = 882;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;
SELECT * FROM contacts where crm_configuration_id = 834;
SELECT * FROM opportunities WHERE team_id = 933
# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');
AND id IN (8482561,18352941,19042734,19232139,19445140,19472541);
SELECT * FROM opportunity_contacts
WHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 485; #
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
select crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id
where crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')
# and l.converted_at IS NOT NULL
;
# [PASSWORD_DOTS]
SELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')
and opportunity_id IS NULL
order by id desc;
SELECT * FROM teams WHERE id = 604; # 598
SELECT * FROM activities WHERE id = 74410828; # [EMAIL]
SELECT * FROM accounts WHERE id = 20068382;
SELECT * FROM accounts WHERE id = 35186038;
SELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 559 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;
select * from sidekick_settings where team_id = 781;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100
SELECT * FROM crm_layouts WHERE crm_configuration_id = 711;
SELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL
and is_internal = 0 and status = 'completed'
order by id desc;
SELECT * FROM crm_layout_entities
WHERE crm_layout_id IN (2352, 2353);
;
SELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 556 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;
SELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;
select * from contacts
where crm_configuration_id = 530
and crm_provider_id = 872252;
select * from activities where crm_configuration_id = 530
and user_id = 14343 and type like '%softphone%'
and created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);
SELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t
JOIN crm_configurations c ON t.id = c.team_id
WHERE t.status = 'active';
SELECT * FROM teams where id = 1091;
SELECT * FROM crm_configurations where team_id = 1091;
SELECT * FROM activity_providers where team_id = 1091;
SELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT * FROM teams WHERE name LIKE '%Leadventure%';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1091 and sa.provider = 'salesforce';
SELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812
SELECT * FROM teams where id = 862;
SELECT * FROM crm_configurations where team_id = 862;
SELECT * FROM activity_providers where team_id = 862;
SELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT t.id, crm.id, crm.provider, ap.* FROM teams t
join crm_configurations crm on t.id = crm.team_id
join activity_providers ap on t.id = ap.team_id
where t.status = 'active' and ap.is_enabled = 1
and crm.provider = 'hubspot'
and ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',
'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');
SELECT * FROM teams where id = 1068;
SELECT * FROM crm_configurations where team_id = 1068;
SELECT * FROM activity_providers where team_id = 1068;
SELECT * FROM activities a
where crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')
and a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'
)
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by a.id desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1068 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262
SELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
select * from crm_layouts where crm_configuration_id = 834;
select * from crm_layout_entities where crm_layout_id = 2780;
select * from crm_fields where id IN (321153,321192,321193,321194);
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1057 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8
SELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20
SELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10
SELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #
SELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;
select * from users where team_id = 51; # 7783
SELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130
select * from activity_searches where user_id = 7783;
select * from activity_search_filters where activity_search_id IN (32291, 32292);
SELECT asf.activity_search_id, asf.id, asf.value
FROM activity_search_filters asf
WHERE asf.filter = 'group_id'
AND asf.value IN (
SELECT CONCAT(
HEX(SUBSTR(uuid, 5, 4)), '-',
HEX(SUBSTR(uuid, 3, 2)), '-',
HEX(SUBSTR(uuid, 1, 2)), '-',
HEX(SUBSTR(uuid, 9, 2)), '-',
HEX(SUBSTR(uuid, 11))
)
FROM groups
WHERE deleted_at IS NOT NULL
);
SELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where provider = 'hubspot';
SELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133
SELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null
# [PASSWORD_DOTS]
select * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';
select
cp.*
# DISTINCT t.id
# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields
FROM crm_profiles cp
JOIN crm_configurations crm on crm.id = cp.crm_configuration_id
JOIN users u on u.id = cp.user_id
JOIN teams t ON t.id = crm.team_id
WHERE crm.provider = 'salesforce' and t.status = 'active'
and cp.archived_at IS NULL and u.deleted_at IS NULL
and t.id NOT IN (1093)
and t.id = 2
and cp.contact_fields IS NULL;
# and c.crm_provider_id = '003Uu00000ojD4NIAU';
SELECT * FROM users WHERE id = 26484;
SELECT * FROM crm_profiles WHERE user_id = 26484;
SELECT * FROM social_accounts WHERE sociable_id = 26484;
SELECT * FROM crm_configurations where provider = 'salesforce';
select * from users where id IN (10022, 10403);
select * from users where team_id IN (526);
select * from teams where id IN (526, 532);
select * from crm_configurations where id IN (500, 516);
select * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);
select * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 526 and sa.provider = 'salesforce';
select * from team_settings where team_id IN (526, 532);
select * from users where id IN (22824);
select * from crm_profiles where crm_configuration_id IN (1026);
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1093 and sa.provider = 'salesforce';
select * from teams where id = 1099;
select * from users where id = 29643
select * from activity_processing_states;
SELECT * FROM teams where name LIKE '%Fare%'; # 233
SELECT * FROM opportunities where crm_configuration_id = 215
# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'
;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1088 and sa.provider = 'hubspot';
SELECT * FROM teams order by updated_at DESC
SELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account
select * from crm_configurations where provider = 'pipedrive';
select * from teams where id = 957;
select * from crm_configurations where id = 957;
SELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743
SELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;
select * from users where team_id = 1; # 26726 - Gabriela Dureva
SELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific
select * from activities where user_id = 26726 order by id desc;
select * from contacts where crm_configuration_id = 1
and email IN ('[EMAIL]', '[EMAIL]'); # 2094416, 2093620
SELECT * FROM contacts WHERE id = 6284931;
SELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id
WHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;
select * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);
select * from crm_configurations where id = 1;
43801692-1aeb-32ce-acba-5b80a479701a
44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b
405975c0-b3d0-7aaa-821f-09d59cae6dd1
4caf848d-4bed-2299-b248-7788d41f9fca
49bedc3f-f196-eef3-89c3-dea6a3b4aa63
43420989-a09d-b8f8-9806-c8bbf7a02aac
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
SELECT * FROM activities WHERE id = 75461988;
SELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;
select * from contacts where id = 17900517;
select * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id
where crm.provider != 'salesforce';
select * from users where id = 21047;
SELECT * FROM crm_configurations WHERE id = 892;
SELECT * FROM teams WHERE id = 942;
select * from opportunities where team_id = 942 order by updated_at desc;
select * from contacts where team_id = 942 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 942 and sa.provider = 'hubspot';
SELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430
SELECT * FROM crm_configurations WHERE id = 1;
SELECT * FROM teams WHERE crm_id = 1;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
select id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1
SELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430
select * from teams where id = 852;
select * from groups where id = 2286;
select * from sidekick_settings where team_id = 852;
select * from default_activity_types where team_id = 852;
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1 AND u.deleted_at IS NULL
AND u.crm_required = 1
AND u.team_id = 1
ORDER BY u.team_id;
SELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (
18481
);
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1
AND u.deleted_at IS NULL
AND u.crm_required = 1
# AND u.team_id = 1
AND p.id IS NULL -- Move this condition to WHERE clause
ORDER BY u.team_id;
SELECT * FROM opportunities WHERE id = 20002609;
select * from teams where id = 1122; # Velatir, 29953 - [EMAIL]
select * from crm_configurations where id = 1060;
select * from crm_layouts where crm_configuration_id = 1060;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1122 and sa.provider = 'hubspot';
select * from opportunities where team_id = 1122 order by updated_at desc;
select * from crm_field_data where object_type = 'contact';
SELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 248 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS
SELECT * FROM users where id = 24115;
SELECT * FROM accounts where id = 4002896;
SELECT * FROM teams WHERE name LIKE '%adswerve%';
SELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN ("0069N000003GIQ9QAO","0061r000019yGP9AAM","0066900001S2KWlAAN","0066900001TDpj2AAD","0066900001b8uEwAAI","0069N000001rQi0QAE","006QF00000KD40mYAD","006QF00000LzpRJYAZ","0069N000002uomtQAA","0069N000002xlMLQAY","0066900001NV6ubAAD","0061r00001HJp45AAD","006QF00000uTlUoYAK","006QF00000v0bZqYAI");
SELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203
SELECT u.id, u.email, ac.name, a.* FROM activities a
JOIN users u ON a.user_id = u.id
JOIN accounts ac ON a.account_id = ac.id
WHERE
uuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or
uuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or
uuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;
select * from users where id = 5825;
SELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;
select * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;
19594, 862
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 862 and sa.provider = 'salesforce';
select * from automated_reports where id = 36;
select ar.frequency, r.*, ar.* from automated_report_results r
join automated_reports ar on r.report_id = ar.id
where ar.frequency != 'one_off';
select s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;
select * from nudges n where n.activity_search_id
select * from teams where created_at > '2026-03-09';
SELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;
select * from users where team_id = 1 and name like '%Lukas%'; # 7160
SELECT * FROM teams WHERE id = 575;
select * from opportunities where team_id = 575;
SELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,
select * from opportunities where team_id = 1126;
SELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,
select * from opportunities where team_id = 1125;
select * from contacts c
where c.team_id = 882;
SELECT * FROM activities WHERE id = 76822967;
SELECT * FROM crm_profiles WHERE user_id = 15440;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 555;
SELECT * FROM crm_configurations WHERE id = 555;
SELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 581 and sa.provider = 'salesforce';
SELECT * FROM automated_report_results order by id desc;
select * from features;
select * from team_features where feature_id = 40;
select * from teams where id = 556;
select * from automated_reports;
where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , ["pdf","podcast"]
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
select * from automated_report_results order by id desc;
SELECT * FROM automated_report_results WHERE id = 1919;
select * from automated_report_results WHERE report_id = 54;
select * from opportunities where id = 7594349;
SELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - [EMAIL]
select * from playbooks where team_id = 711; # event 226147
SELECT * FROM playbook_categories WHERE playbook_id = 5515;
SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';
SELECT * FROM crm_fields WHERE id = 226147;
SELECT * FROM crm_field_values WHERE crm_field_id = 226147;
SELECT * FROM crm_configurations WHERE id = 692;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 711 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;
select * from leads;
select * from calendars;
SELECT
t.id AS team_id,
t.name,
LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain
FROM teams t
JOIN users u ON u.team_id = t.id
JOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'
LEFT JOIN team_domains td
ON td.team_id = t.id
AND td.deleted_at IS NULL
AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))
GROUP BY t.id, t.name, calendar_domain
ORDER BY t.name, calendar_domain;
select * from users u join calendars c on c.user_id = u.id
where u.team_id = 882;
select * from activities where id = 74049485; # team 563 crm 537
select * from activities where id = 73272382; # team 563 crm 537
select * from activities where id = 64400389; # team 563 crm 537
select * from activities where id = 58081273; # team 563 crm 537
select * from activities where id = 54520297; # team 563 crm 537
select * from participants where activity_id = 58081273;
select * from activities where crm_configuration_id = 537 and provider = 'aircall'
and account_id = 19003658 order by updated_at desc;
select * from contacts where crm_configuration_id = 537 and id = 35957759;
select * from accounts where crm_configuration_id = 537 and id = 19003658;
select * from automated_report_results where id = 1976;
select * from automated_reports where id = 583;
select * from activity_searches where id = 87714;
select * from activity_search_filters where activity_search_id = 87714;
SELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid
or uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;
SELECT * FROM crm_configurations WHERE provider = 'hubspot';
select * from rate_limits;
select * from automated_report_results where media_type = 'pdf' and status = 2
and id IN (18, 1872);
select * from automated_reports where id = 54;
SELECT * FROM users WHERE id IN (24623,29443,29613);
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app, folder
.circleci, folder
.cursor, folder
.github
.sonarlint, folder
.vscode, folder
.windsurf, folder
app, sources root
Actions
InviteUserToTeamAction.php, class
MarkUserAsOnboardableAction.php, class
SyncRecordingFlagsAction.php, class
UpdateTeamMemberAction.php, class
UpdateUserRolesAction.php, class
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi...
|
32896
|
NULL
|
NULL
|
NULL
|
|
32899
|
1256
|
16
|
2026-05-13T09:44:51.681808+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665491681_m1.jpg...
|
PhpStorm
|
faVsco.js – CreateTeam.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
<?php
namespace Jiminny\Actions;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Jiminny\Component\Acl\RoleChangeContext;
use Jiminny\Component\Acl\RoleChangeLogger;
use Jiminny\Component\Acl\RoleChangeType;
use Jiminny\Contracts\Acl\RoleRepositoryInterface;
use Jiminny\DTO\Invitation\UserInvitationDTO;
use Jiminny\Models\Invitation;
use Jiminny\Models\Role;
use Jiminny\Models\User;
use Jiminny\Notifications\Channels\EmailNotifiable;
use Jiminny\Notifications\OwnerInvitedToTrial;
use Jiminny\Notifications\UserInvitedToTeam;
use Jiminny\Notifications\UserInvitedToTeamWithEmailOnly;
class InviteUserToTeamAction
{
public function __construct(
private RoleRepositoryInterface $roleRepository,
private RoleChangeLogger $roleChangeLogger,
) {
}
public function execute(UserInvitationDTO $dto): void
{
/** @var Invitation $invitation */
$invitation = Invitation::updateOrCreate(
[
'team_id' => $dto->teamId,
'email' => $dto->email,
],
[
'group_id' => $dto->groupId,
'secondary_email' => $dto->secondaryEmail,
'crm_required' => $dto->crmRequired,
'token' => Str::random(40),
'is_owner' => $dto->isOwner,
]
)->loadMissing(['team']);
$invitation->roles()->sync($dto->roleIds);
$notifiable = new EmailNotifiable($invitation->email, $invitation->getTeam());
$logMessage = 'User invited to trial';
if ($invitation->getTeam()->owner_id === null) {
$notifiable->notifyNow(new OwnerInvitedToTrial($invitation));
$logMessage = 'Owner invited to trial';
} else {
$notifiable->notifyNow(new UserInvitedToTeam($invitation));
}
collect($dto->roleIds)
->map(fn (int $roleId): Role => $this->roleRepository->get($roleId))
->each(function (Role $role) use ($dto, $invitation): void {
$this->roleChangeLogger->log(
$dto->currentUser,
$invitation,
$role,
$invitation->wasRecentlyCreated
? RoleChangeType::INVITE_USER
: RoleChangeType::RESEND_INVITATION,
RoleChangeContext::APP,
);
});
Log::info($logMessage, [
'teamId' => $invitation->team_id,
'teamName' => $invitation->getTeam()->name,
'email' => $invitation->email,
'crmRequired' => $invitation->crm_required ? 'yes' : 'no',
]);
$invitation->touch();
}
public function executeWithEmailOnly(User $user): void
{
$notifiable = new EmailNotifiable($user->getEmailAddress(), $user->getTeam());
$notifiable->notifyNow(new UserInvitedToTeamWithEmailOnly($user));
}
}
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
40
1
40
64
Previous Highlighted Error
Next Highlighted Error
SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993
SELECT * FROM users WHERE id = 25061;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 994;
SELECT * FROM crm_profiles WHERE user_id = 25061;
select * from crm_configurations where id = 834;
SELECT * FROM teams WHERE id = 882;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;
SELECT * FROM contacts where crm_configuration_id = 834;
SELECT * FROM opportunities WHERE team_id = 933
# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');
AND id IN (8482561,18352941,19042734,19232139,19445140,19472541);
SELECT * FROM opportunity_contacts
WHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 485; #
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
select crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id
where crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')
# and l.converted_at IS NOT NULL
;
# [PASSWORD_DOTS]
SELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')
and opportunity_id IS NULL
order by id desc;
SELECT * FROM teams WHERE id = 604; # 598
SELECT * FROM activities WHERE id = 74410828; # [EMAIL]
SELECT * FROM accounts WHERE id = 20068382;
SELECT * FROM accounts WHERE id = 35186038;
SELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 559 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;
select * from sidekick_settings where team_id = 781;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100
SELECT * FROM crm_layouts WHERE crm_configuration_id = 711;
SELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL
and is_internal = 0 and status = 'completed'
order by id desc;
SELECT * FROM crm_layout_entities
WHERE crm_layout_id IN (2352, 2353);
;
SELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 556 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;
SELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;
select * from contacts
where crm_configuration_id = 530
and crm_provider_id = 872252;
select * from activities where crm_configuration_id = 530
and user_id = 14343 and type like '%softphone%'
and created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);
SELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t
JOIN crm_configurations c ON t.id = c.team_id
WHERE t.status = 'active';
SELECT * FROM teams where id = 1091;
SELECT * FROM crm_configurations where team_id = 1091;
SELECT * FROM activity_providers where team_id = 1091;
SELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT * FROM teams WHERE name LIKE '%Leadventure%';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1091 and sa.provider = 'salesforce';
SELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812
SELECT * FROM teams where id = 862;
SELECT * FROM crm_configurations where team_id = 862;
SELECT * FROM activity_providers where team_id = 862;
SELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT t.id, crm.id, crm.provider, ap.* FROM teams t
join crm_configurations crm on t.id = crm.team_id
join activity_providers ap on t.id = ap.team_id
where t.status = 'active' and ap.is_enabled = 1
and crm.provider = 'hubspot'
and ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',
'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');
SELECT * FROM teams where id = 1068;
SELECT * FROM crm_configurations where team_id = 1068;
SELECT * FROM activity_providers where team_id = 1068;
SELECT * FROM activities a
where crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')
and a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'
)
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by a.id desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1068 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262
SELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
select * from crm_layouts where crm_configuration_id = 834;
select * from crm_layout_entities where crm_layout_id = 2780;
select * from crm_fields where id IN (321153,321192,321193,321194);
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1057 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8
SELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20
SELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10
SELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #
SELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;
select * from users where team_id = 51; # 7783
SELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130
select * from activity_searches where user_id = 7783;
select * from activity_search_filters where activity_search_id IN (32291, 32292);
SELECT asf.activity_search_id, asf.id, asf.value
FROM activity_search_filters asf
WHERE asf.filter = 'group_id'
AND asf.value IN (
SELECT CONCAT(
HEX(SUBSTR(uuid, 5, 4)), '-',
HEX(SUBSTR(uuid, 3, 2)), '-',
HEX(SUBSTR(uuid, 1, 2)), '-',
HEX(SUBSTR(uuid, 9, 2)), '-',
HEX(SUBSTR(uuid, 11))
)
FROM groups
WHERE deleted_at IS NOT NULL
);
SELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where provider = 'hubspot';
SELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133
SELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null
# [PASSWORD_DOTS]
select * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';
select
cp.*
# DISTINCT t.id
# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields
FROM crm_profiles cp
JOIN crm_configurations crm on crm.id = cp.crm_configuration_id
JOIN users u on u.id = cp.user_id
JOIN teams t ON t.id = crm.team_id
WHERE crm.provider = 'salesforce' and t.status = 'active'
and cp.archived_at IS NULL and u.deleted_at IS NULL
and t.id NOT IN (1093)
and t.id = 2
and cp.contact_fields IS NULL;
# and c.crm_provider_id = '003Uu00000ojD4NIAU';
SELECT * FROM users WHERE id = 26484;
SELECT * FROM crm_profiles WHERE user_id = 26484;
SELECT * FROM social_accounts WHERE sociable_id = 26484;
SELECT * FROM crm_configurations where provider = 'salesforce';
select * from users where id IN (10022, 10403);
select * from users where team_id IN (526);
select * from teams where id IN (526, 532);
select * from crm_configurations where id IN (500, 516);
select * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);
select * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 526 and sa.provider = 'salesforce';
select * from team_settings where team_id IN (526, 532);
select * from users where id IN (22824);
select * from crm_profiles where crm_configuration_id IN (1026);
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1093 and sa.provider = 'salesforce';
select * from teams where id = 1099;
select * from users where id = 29643
select * from activity_processing_states;
SELECT * FROM teams where name LIKE '%Fare%'; # 233
SELECT * FROM opportunities where crm_configuration_id = 215
# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'
;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1088 and sa.provider = 'hubspot';
SELECT * FROM teams order by updated_at DESC
SELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account
select * from crm_configurations where provider = 'pipedrive';
select * from teams where id = 957;
select * from crm_configurations where id = 957;
SELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743
SELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;
select * from users where team_id = 1; # 26726 - Gabriela Dureva
SELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific
select * from activities where user_id = 26726 order by id desc;
select * from contacts where crm_configuration_id = 1
and email IN ('[EMAIL]', '[EMAIL]'); # 2094416, 2093620
SELECT * FROM contacts WHERE id = 6284931;
SELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id
WHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;
select * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);
select * from crm_configurations where id = 1;
43801692-1aeb-32ce-acba-5b80a479701a
44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b
405975c0-b3d0-7aaa-821f-09d59cae6dd1
4caf848d-4bed-2299-b248-7788d41f9fca
49bedc3f-f196-eef3-89c3-dea6a3b4aa63
43420989-a09d-b8f8-9806-c8bbf7a02aac
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
SELECT * FROM activities WHERE id = 75461988;
SELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;
select * from contacts where id = 17900517;
select * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id
where crm.provider != 'salesforce';
select * from users where id = 21047;
SELECT * FROM crm_configurations WHERE id = 892;
SELECT * FROM teams WHERE id = 942;
select * from opportunities where team_id = 942 order by updated_at desc;
select * from contacts where team_id = 942 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 942 and sa.provider = 'hubspot';
SELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430
SELECT * FROM crm_configurations WHERE id = 1;
SELECT * FROM teams WHERE crm_id = 1;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
select id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1
SELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430
select * from teams where id = 852;
select * from groups where id = 2286;
select * from sidekick_settings where team_id = 852;
select * from default_activity_types where team_id = 852;
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1 AND u.deleted_at IS NULL
AND u.crm_required = 1
AND u.team_id = 1
ORDER BY u.team_id;
SELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (
18481
);
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1
AND u.deleted_at IS NULL
AND u.crm_required = 1
# AND u.team_id = 1
AND p.id IS NULL -- Move this condition to WHERE clause
ORDER BY u.team_id;
SELECT * FROM opportunities WHERE id = 20002609;
select * from teams where id = 1122; # Velatir, 29953 - [EMAIL]
select * from crm_configurations where id = 1060;
select * from crm_layouts where crm_configuration_id = 1060;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1122 and sa.provider = 'hubspot';
select * from opportunities where team_id = 1122 order by updated_at desc;
select * from crm_field_data where object_type = 'contact';
SELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 248 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS
SELECT * FROM users where id = 24115;
SELECT * FROM accounts where id = 4002896;
SELECT * FROM teams WHERE name LIKE '%adswerve%';
SELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN ("0069N000003GIQ9QAO","0061r000019yGP9AAM","0066900001S2KWlAAN","0066900001TDpj2AAD","0066900001b8uEwAAI","0069N000001rQi0QAE","006QF00000KD40mYAD","006QF00000LzpRJYAZ","0069N000002uomtQAA","0069N000002xlMLQAY","0066900001NV6ubAAD","0061r00001HJp45AAD","006QF00000uTlUoYAK","006QF00000v0bZqYAI");
SELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203
SELECT u.id, u.email, ac.name, a.* FROM activities a
JOIN users u ON a.user_id = u.id
JOIN accounts ac ON a.account_id = ac.id
WHERE
uuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or
uuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or
uuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;
select * from users where id = 5825;
SELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;
select * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;
19594, 862
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 862 and sa.provider = 'salesforce';
select * from automated_reports where id = 36;
select ar.frequency, r.*, ar.* from automated_report_results r
join automated_reports ar on r.report_id = ar.id
where ar.frequency != 'one_off';
select s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;
select * from nudges n where n.activity_search_id
select * from teams where created_at > '2026-03-09';
SELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;
select * from users where team_id = 1 and name like '%Lukas%'; # 7160
SELECT * FROM teams WHERE id = 575;
select * from opportunities where team_id = 575;
SELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,
select * from opportunities where team_id = 1126;
SELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,
select * from opportunities where team_id = 1125;
select * from contacts c
where c.team_id = 882;
SELECT * FROM activities WHERE id = 76822967;
SELECT * FROM crm_profiles WHERE user_id = 15440;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 555;
SELECT * FROM crm_configurations WHERE id = 555;
SELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 581 and sa.provider = 'salesforce';
SELECT * FROM automated_report_results order by id desc;
select * from features;
select * from team_features where feature_id = 40;
select * from teams where id = 556;
select * from automated_reports;
where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , ["pdf","podcast"]
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
select * from automated_report_results order by id desc;
SELECT * FROM automated_report_results WHERE id = 1919;
select * from automated_report_results WHERE report_id = 54;
select * from opportunities where id = 7594349;
SELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - [EMAIL]
select * from playbooks where team_id = 711; # event 226147
SELECT * FROM playbook_categories WHERE playbook_id = 5515;
SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';
SELECT * FROM crm_fields WHERE id = 226147;
SELECT * FROM crm_field_values WHERE crm_field_id = 226147;
SELECT * FROM crm_configurations WHERE id = 692;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 711 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;
select * from leads;
select * from calendars;
SELECT
t.id AS team_id,
t.name,
LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain
FROM teams t
JOIN users u ON u.team_id = t.id
JOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'
LEFT JOIN team_domains td
ON td.team_id = t.id
AND td.deleted_at IS NULL
AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))
GROUP BY t.id, t.name, calendar_domain
ORDER BY t.name, calendar_domain;
select * from users u join calendars c on c.user_id = u.id
where u.team_id = 882;
select * from activities where id = 74049485; # team 563 crm 537
select * from activities where id = 73272382; # team 563 crm 537
select * from activities where id = 64400389; # team 563 crm 537
select * from activities where id = 58081273; # team 563 crm 537
select * from activities where id = 54520297; # team 563 crm 537
select * from participants where activity_id = 58081273;
select * from activities where crm_configuration_id = 537 and provider = 'aircall'
and account_id = 19003658 order by updated_at desc;
select * from contacts where crm_configuration_id = 537 and id = 35957759;
select * from accounts where crm_configuration_id = 537 and id = 19003658;
select * from automated_report_results where id = 1976;
select * from automated_reports where id = 583;
select * from activity_searches where id = 87714;
select * from activity_search_filters where activity_search_id = 87714;
SELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid
or uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;
SELECT * FROM crm_configurations WHERE provider = 'hubspot';
select * from rate_limits;
select * from automated_report_results where media_type = 'pdf' and status = 2
and id IN (18, 1872);
select * from automated_reports where id = 54;
SELECT * FROM users WHERE id IN (24623,29443,29613);
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app, folder
.circleci, folder
.cursor, folder
.github
.sonarlint, folder...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"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":"Analyzing…","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Actions;\n\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Support\\Str;\nuse Jiminny\\Component\\Acl\\RoleChangeContext;\nuse Jiminny\\Component\\Acl\\RoleChangeLogger;\nuse Jiminny\\Component\\Acl\\RoleChangeType;\nuse Jiminny\\Contracts\\Acl\\RoleRepositoryInterface;\nuse Jiminny\\DTO\\Invitation\\UserInvitationDTO;\nuse Jiminny\\Models\\Invitation;\nuse Jiminny\\Models\\Role;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Notifications\\Channels\\EmailNotifiable;\nuse Jiminny\\Notifications\\OwnerInvitedToTrial;\nuse Jiminny\\Notifications\\UserInvitedToTeam;\nuse Jiminny\\Notifications\\UserInvitedToTeamWithEmailOnly;\n\nclass InviteUserToTeamAction\n{\n public function __construct(\n private RoleRepositoryInterface $roleRepository,\n private RoleChangeLogger $roleChangeLogger,\n ) {\n }\n\n public function execute(UserInvitationDTO $dto): void\n {\n /** @var Invitation $invitation */\n $invitation = Invitation::updateOrCreate(\n [\n 'team_id' => $dto->teamId,\n 'email' => $dto->email,\n ],\n [\n 'group_id' => $dto->groupId,\n 'secondary_email' => $dto->secondaryEmail,\n 'crm_required' => $dto->crmRequired,\n 'token' => Str::random(40),\n 'is_owner' => $dto->isOwner,\n ]\n )->loadMissing(['team']);\n\n $invitation->roles()->sync($dto->roleIds);\n\n $notifiable = new EmailNotifiable($invitation->email, $invitation->getTeam());\n\n $logMessage = 'User invited to trial';\n\n if ($invitation->getTeam()->owner_id === null) {\n $notifiable->notifyNow(new OwnerInvitedToTrial($invitation));\n\n $logMessage = 'Owner invited to trial';\n } else {\n $notifiable->notifyNow(new UserInvitedToTeam($invitation));\n }\n\n collect($dto->roleIds)\n ->map(fn (int $roleId): Role => $this->roleRepository->get($roleId))\n ->each(function (Role $role) use ($dto, $invitation): void {\n $this->roleChangeLogger->log(\n $dto->currentUser,\n $invitation,\n $role,\n $invitation->wasRecentlyCreated\n ? RoleChangeType::INVITE_USER\n : RoleChangeType::RESEND_INVITATION,\n RoleChangeContext::APP,\n );\n });\n\n Log::info($logMessage, [\n 'teamId' => $invitation->team_id,\n 'teamName' => $invitation->getTeam()->name,\n 'email' => $invitation->email,\n 'crmRequired' => $invitation->crm_required ? 'yes' : 'no',\n ]);\n\n $invitation->touch();\n }\n\n public function executeWithEmailOnly(User $user): void\n {\n $notifiable = new EmailNotifiable($user->getEmailAddress(), $user->getTeam());\n\n $notifiable->notifyNow(new UserInvitedToTeamWithEmailOnly($user));\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Actions;\n\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Support\\Str;\nuse Jiminny\\Component\\Acl\\RoleChangeContext;\nuse Jiminny\\Component\\Acl\\RoleChangeLogger;\nuse Jiminny\\Component\\Acl\\RoleChangeType;\nuse Jiminny\\Contracts\\Acl\\RoleRepositoryInterface;\nuse Jiminny\\DTO\\Invitation\\UserInvitationDTO;\nuse Jiminny\\Models\\Invitation;\nuse Jiminny\\Models\\Role;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Notifications\\Channels\\EmailNotifiable;\nuse Jiminny\\Notifications\\OwnerInvitedToTrial;\nuse Jiminny\\Notifications\\UserInvitedToTeam;\nuse Jiminny\\Notifications\\UserInvitedToTeamWithEmailOnly;\n\nclass InviteUserToTeamAction\n{\n public function __construct(\n private RoleRepositoryInterface $roleRepository,\n private RoleChangeLogger $roleChangeLogger,\n ) {\n }\n\n public function execute(UserInvitationDTO $dto): void\n {\n /** @var Invitation $invitation */\n $invitation = Invitation::updateOrCreate(\n [\n 'team_id' => $dto->teamId,\n 'email' => $dto->email,\n ],\n [\n 'group_id' => $dto->groupId,\n 'secondary_email' => $dto->secondaryEmail,\n 'crm_required' => $dto->crmRequired,\n 'token' => Str::random(40),\n 'is_owner' => $dto->isOwner,\n ]\n )->loadMissing(['team']);\n\n $invitation->roles()->sync($dto->roleIds);\n\n $notifiable = new EmailNotifiable($invitation->email, $invitation->getTeam());\n\n $logMessage = 'User invited to trial';\n\n if ($invitation->getTeam()->owner_id === null) {\n $notifiable->notifyNow(new OwnerInvitedToTrial($invitation));\n\n $logMessage = 'Owner invited to trial';\n } else {\n $notifiable->notifyNow(new UserInvitedToTeam($invitation));\n }\n\n collect($dto->roleIds)\n ->map(fn (int $roleId): Role => $this->roleRepository->get($roleId))\n ->each(function (Role $role) use ($dto, $invitation): void {\n $this->roleChangeLogger->log(\n $dto->currentUser,\n $invitation,\n $role,\n $invitation->wasRecentlyCreated\n ? RoleChangeType::INVITE_USER\n : RoleChangeType::RESEND_INVITATION,\n RoleChangeContext::APP,\n );\n });\n\n Log::info($logMessage, [\n 'teamId' => $invitation->team_id,\n 'teamName' => $invitation->getTeam()->name,\n 'email' => $invitation->email,\n 'crmRequired' => $invitation->crm_required ? 'yes' : 'no',\n ]);\n\n $invitation->touch();\n }\n\n public function executeWithEmailOnly(User $user): void\n {\n $notifiable = new EmailNotifiable($user->getEmailAddress(), $user->getTeam());\n\n $notifiable->notifyNow(new UserInvitedToTeamWithEmailOnly($user));\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":"40","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"40","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"64","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","depth":4,"on_screen":true,"value":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app, 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":".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"}]...
|
3759295006096232366
|
1065678636275086917
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
<?php
namespace Jiminny\Actions;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Jiminny\Component\Acl\RoleChangeContext;
use Jiminny\Component\Acl\RoleChangeLogger;
use Jiminny\Component\Acl\RoleChangeType;
use Jiminny\Contracts\Acl\RoleRepositoryInterface;
use Jiminny\DTO\Invitation\UserInvitationDTO;
use Jiminny\Models\Invitation;
use Jiminny\Models\Role;
use Jiminny\Models\User;
use Jiminny\Notifications\Channels\EmailNotifiable;
use Jiminny\Notifications\OwnerInvitedToTrial;
use Jiminny\Notifications\UserInvitedToTeam;
use Jiminny\Notifications\UserInvitedToTeamWithEmailOnly;
class InviteUserToTeamAction
{
public function __construct(
private RoleRepositoryInterface $roleRepository,
private RoleChangeLogger $roleChangeLogger,
) {
}
public function execute(UserInvitationDTO $dto): void
{
/** @var Invitation $invitation */
$invitation = Invitation::updateOrCreate(
[
'team_id' => $dto->teamId,
'email' => $dto->email,
],
[
'group_id' => $dto->groupId,
'secondary_email' => $dto->secondaryEmail,
'crm_required' => $dto->crmRequired,
'token' => Str::random(40),
'is_owner' => $dto->isOwner,
]
)->loadMissing(['team']);
$invitation->roles()->sync($dto->roleIds);
$notifiable = new EmailNotifiable($invitation->email, $invitation->getTeam());
$logMessage = 'User invited to trial';
if ($invitation->getTeam()->owner_id === null) {
$notifiable->notifyNow(new OwnerInvitedToTrial($invitation));
$logMessage = 'Owner invited to trial';
} else {
$notifiable->notifyNow(new UserInvitedToTeam($invitation));
}
collect($dto->roleIds)
->map(fn (int $roleId): Role => $this->roleRepository->get($roleId))
->each(function (Role $role) use ($dto, $invitation): void {
$this->roleChangeLogger->log(
$dto->currentUser,
$invitation,
$role,
$invitation->wasRecentlyCreated
? RoleChangeType::INVITE_USER
: RoleChangeType::RESEND_INVITATION,
RoleChangeContext::APP,
);
});
Log::info($logMessage, [
'teamId' => $invitation->team_id,
'teamName' => $invitation->getTeam()->name,
'email' => $invitation->email,
'crmRequired' => $invitation->crm_required ? 'yes' : 'no',
]);
$invitation->touch();
}
public function executeWithEmailOnly(User $user): void
{
$notifiable = new EmailNotifiable($user->getEmailAddress(), $user->getTeam());
$notifiable->notifyNow(new UserInvitedToTeamWithEmailOnly($user));
}
}
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
40
1
40
64
Previous Highlighted Error
Next Highlighted Error
SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993
SELECT * FROM users WHERE id = 25061;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 994;
SELECT * FROM crm_profiles WHERE user_id = 25061;
select * from crm_configurations where id = 834;
SELECT * FROM teams WHERE id = 882;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;
SELECT * FROM contacts where crm_configuration_id = 834;
SELECT * FROM opportunities WHERE team_id = 933
# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');
AND id IN (8482561,18352941,19042734,19232139,19445140,19472541);
SELECT * FROM opportunity_contacts
WHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 485; #
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
select crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id
where crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')
# and l.converted_at IS NOT NULL
;
# [PASSWORD_DOTS]
SELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')
and opportunity_id IS NULL
order by id desc;
SELECT * FROM teams WHERE id = 604; # 598
SELECT * FROM activities WHERE id = 74410828; # [EMAIL]
SELECT * FROM accounts WHERE id = 20068382;
SELECT * FROM accounts WHERE id = 35186038;
SELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 559 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;
select * from sidekick_settings where team_id = 781;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100
SELECT * FROM crm_layouts WHERE crm_configuration_id = 711;
SELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL
and is_internal = 0 and status = 'completed'
order by id desc;
SELECT * FROM crm_layout_entities
WHERE crm_layout_id IN (2352, 2353);
;
SELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 556 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;
SELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;
select * from contacts
where crm_configuration_id = 530
and crm_provider_id = 872252;
select * from activities where crm_configuration_id = 530
and user_id = 14343 and type like '%softphone%'
and created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);
SELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t
JOIN crm_configurations c ON t.id = c.team_id
WHERE t.status = 'active';
SELECT * FROM teams where id = 1091;
SELECT * FROM crm_configurations where team_id = 1091;
SELECT * FROM activity_providers where team_id = 1091;
SELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT * FROM teams WHERE name LIKE '%Leadventure%';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1091 and sa.provider = 'salesforce';
SELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812
SELECT * FROM teams where id = 862;
SELECT * FROM crm_configurations where team_id = 862;
SELECT * FROM activity_providers where team_id = 862;
SELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT t.id, crm.id, crm.provider, ap.* FROM teams t
join crm_configurations crm on t.id = crm.team_id
join activity_providers ap on t.id = ap.team_id
where t.status = 'active' and ap.is_enabled = 1
and crm.provider = 'hubspot'
and ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',
'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');
SELECT * FROM teams where id = 1068;
SELECT * FROM crm_configurations where team_id = 1068;
SELECT * FROM activity_providers where team_id = 1068;
SELECT * FROM activities a
where crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')
and a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'
)
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by a.id desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1068 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262
SELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
select * from crm_layouts where crm_configuration_id = 834;
select * from crm_layout_entities where crm_layout_id = 2780;
select * from crm_fields where id IN (321153,321192,321193,321194);
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1057 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8
SELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20
SELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10
SELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #
SELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;
select * from users where team_id = 51; # 7783
SELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130
select * from activity_searches where user_id = 7783;
select * from activity_search_filters where activity_search_id IN (32291, 32292);
SELECT asf.activity_search_id, asf.id, asf.value
FROM activity_search_filters asf
WHERE asf.filter = 'group_id'
AND asf.value IN (
SELECT CONCAT(
HEX(SUBSTR(uuid, 5, 4)), '-',
HEX(SUBSTR(uuid, 3, 2)), '-',
HEX(SUBSTR(uuid, 1, 2)), '-',
HEX(SUBSTR(uuid, 9, 2)), '-',
HEX(SUBSTR(uuid, 11))
)
FROM groups
WHERE deleted_at IS NOT NULL
);
SELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where provider = 'hubspot';
SELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133
SELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null
# [PASSWORD_DOTS]
select * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';
select
cp.*
# DISTINCT t.id
# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields
FROM crm_profiles cp
JOIN crm_configurations crm on crm.id = cp.crm_configuration_id
JOIN users u on u.id = cp.user_id
JOIN teams t ON t.id = crm.team_id
WHERE crm.provider = 'salesforce' and t.status = 'active'
and cp.archived_at IS NULL and u.deleted_at IS NULL
and t.id NOT IN (1093)
and t.id = 2
and cp.contact_fields IS NULL;
# and c.crm_provider_id = '003Uu00000ojD4NIAU';
SELECT * FROM users WHERE id = 26484;
SELECT * FROM crm_profiles WHERE user_id = 26484;
SELECT * FROM social_accounts WHERE sociable_id = 26484;
SELECT * FROM crm_configurations where provider = 'salesforce';
select * from users where id IN (10022, 10403);
select * from users where team_id IN (526);
select * from teams where id IN (526, 532);
select * from crm_configurations where id IN (500, 516);
select * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);
select * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 526 and sa.provider = 'salesforce';
select * from team_settings where team_id IN (526, 532);
select * from users where id IN (22824);
select * from crm_profiles where crm_configuration_id IN (1026);
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1093 and sa.provider = 'salesforce';
select * from teams where id = 1099;
select * from users where id = 29643
select * from activity_processing_states;
SELECT * FROM teams where name LIKE '%Fare%'; # 233
SELECT * FROM opportunities where crm_configuration_id = 215
# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'
;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1088 and sa.provider = 'hubspot';
SELECT * FROM teams order by updated_at DESC
SELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account
select * from crm_configurations where provider = 'pipedrive';
select * from teams where id = 957;
select * from crm_configurations where id = 957;
SELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743
SELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;
select * from users where team_id = 1; # 26726 - Gabriela Dureva
SELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific
select * from activities where user_id = 26726 order by id desc;
select * from contacts where crm_configuration_id = 1
and email IN ('[EMAIL]', '[EMAIL]'); # 2094416, 2093620
SELECT * FROM contacts WHERE id = 6284931;
SELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id
WHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;
select * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);
select * from crm_configurations where id = 1;
43801692-1aeb-32ce-acba-5b80a479701a
44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b
405975c0-b3d0-7aaa-821f-09d59cae6dd1
4caf848d-4bed-2299-b248-7788d41f9fca
49bedc3f-f196-eef3-89c3-dea6a3b4aa63
43420989-a09d-b8f8-9806-c8bbf7a02aac
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
SELECT * FROM activities WHERE id = 75461988;
SELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;
select * from contacts where id = 17900517;
select * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id
where crm.provider != 'salesforce';
select * from users where id = 21047;
SELECT * FROM crm_configurations WHERE id = 892;
SELECT * FROM teams WHERE id = 942;
select * from opportunities where team_id = 942 order by updated_at desc;
select * from contacts where team_id = 942 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 942 and sa.provider = 'hubspot';
SELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430
SELECT * FROM crm_configurations WHERE id = 1;
SELECT * FROM teams WHERE crm_id = 1;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
select id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1
SELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430
select * from teams where id = 852;
select * from groups where id = 2286;
select * from sidekick_settings where team_id = 852;
select * from default_activity_types where team_id = 852;
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1 AND u.deleted_at IS NULL
AND u.crm_required = 1
AND u.team_id = 1
ORDER BY u.team_id;
SELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (
18481
);
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1
AND u.deleted_at IS NULL
AND u.crm_required = 1
# AND u.team_id = 1
AND p.id IS NULL -- Move this condition to WHERE clause
ORDER BY u.team_id;
SELECT * FROM opportunities WHERE id = 20002609;
select * from teams where id = 1122; # Velatir, 29953 - [EMAIL]
select * from crm_configurations where id = 1060;
select * from crm_layouts where crm_configuration_id = 1060;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1122 and sa.provider = 'hubspot';
select * from opportunities where team_id = 1122 order by updated_at desc;
select * from crm_field_data where object_type = 'contact';
SELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 248 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS
SELECT * FROM users where id = 24115;
SELECT * FROM accounts where id = 4002896;
SELECT * FROM teams WHERE name LIKE '%adswerve%';
SELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN ("0069N000003GIQ9QAO","0061r000019yGP9AAM","0066900001S2KWlAAN","0066900001TDpj2AAD","0066900001b8uEwAAI","0069N000001rQi0QAE","006QF00000KD40mYAD","006QF00000LzpRJYAZ","0069N000002uomtQAA","0069N000002xlMLQAY","0066900001NV6ubAAD","0061r00001HJp45AAD","006QF00000uTlUoYAK","006QF00000v0bZqYAI");
SELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203
SELECT u.id, u.email, ac.name, a.* FROM activities a
JOIN users u ON a.user_id = u.id
JOIN accounts ac ON a.account_id = ac.id
WHERE
uuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or
uuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or
uuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;
select * from users where id = 5825;
SELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;
select * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;
19594, 862
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 862 and sa.provider = 'salesforce';
select * from automated_reports where id = 36;
select ar.frequency, r.*, ar.* from automated_report_results r
join automated_reports ar on r.report_id = ar.id
where ar.frequency != 'one_off';
select s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;
select * from nudges n where n.activity_search_id
select * from teams where created_at > '2026-03-09';
SELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;
select * from users where team_id = 1 and name like '%Lukas%'; # 7160
SELECT * FROM teams WHERE id = 575;
select * from opportunities where team_id = 575;
SELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,
select * from opportunities where team_id = 1126;
SELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,
select * from opportunities where team_id = 1125;
select * from contacts c
where c.team_id = 882;
SELECT * FROM activities WHERE id = 76822967;
SELECT * FROM crm_profiles WHERE user_id = 15440;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 555;
SELECT * FROM crm_configurations WHERE id = 555;
SELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 581 and sa.provider = 'salesforce';
SELECT * FROM automated_report_results order by id desc;
select * from features;
select * from team_features where feature_id = 40;
select * from teams where id = 556;
select * from automated_reports;
where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , ["pdf","podcast"]
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
select * from automated_report_results order by id desc;
SELECT * FROM automated_report_results WHERE id = 1919;
select * from automated_report_results WHERE report_id = 54;
select * from opportunities where id = 7594349;
SELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - [EMAIL]
select * from playbooks where team_id = 711; # event 226147
SELECT * FROM playbook_categories WHERE playbook_id = 5515;
SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';
SELECT * FROM crm_fields WHERE id = 226147;
SELECT * FROM crm_field_values WHERE crm_field_id = 226147;
SELECT * FROM crm_configurations WHERE id = 692;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 711 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;
select * from leads;
select * from calendars;
SELECT
t.id AS team_id,
t.name,
LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain
FROM teams t
JOIN users u ON u.team_id = t.id
JOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'
LEFT JOIN team_domains td
ON td.team_id = t.id
AND td.deleted_at IS NULL
AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))
GROUP BY t.id, t.name, calendar_domain
ORDER BY t.name, calendar_domain;
select * from users u join calendars c on c.user_id = u.id
where u.team_id = 882;
select * from activities where id = 74049485; # team 563 crm 537
select * from activities where id = 73272382; # team 563 crm 537
select * from activities where id = 64400389; # team 563 crm 537
select * from activities where id = 58081273; # team 563 crm 537
select * from activities where id = 54520297; # team 563 crm 537
select * from participants where activity_id = 58081273;
select * from activities where crm_configuration_id = 537 and provider = 'aircall'
and account_id = 19003658 order by updated_at desc;
select * from contacts where crm_configuration_id = 537 and id = 35957759;
select * from accounts where crm_configuration_id = 537 and id = 19003658;
select * from automated_report_results where id = 1976;
select * from automated_reports where id = 583;
select * from activity_searches where id = 87714;
select * from activity_search_filters where activity_search_id = 87714;
SELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid
or uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;
SELECT * FROM crm_configurations WHERE provider = 'hubspot';
select * from rate_limits;
select * from automated_report_results where media_type = 'pdf' and status = 2
and id IN (18, 1872);
select * from automated_reports where id = 54;
SELECT * FROM users WHERE id IN (24623,29443,29613);
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app, folder
.circleci, folder
.cursor, folder
.github
.sonarlint, folder...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
32900
|
1256
|
17
|
2026-05-13T09:44:53.057549+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665493057_m1.jpg...
|
PhpStorm
|
faVsco.js – InviteUserToTeamAction.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
3
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Actions;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Jiminny\Component\Acl\RoleChangeContext;
use Jiminny\Component\Acl\RoleChangeLogger;
use Jiminny\Component\Acl\RoleChangeType;
use Jiminny\Contracts\Acl\RoleRepositoryInterface;
use Jiminny\DTO\Invitation\UserInvitationDTO;
use Jiminny\Models\Invitation;
use Jiminny\Models\Role;
use Jiminny\Models\User;
use Jiminny\Notifications\Channels\EmailNotifiable;
use Jiminny\Notifications\OwnerInvitedToTrial;
use Jiminny\Notifications\UserInvitedToTeam;
use Jiminny\Notifications\UserInvitedToTeamWithEmailOnly;
class InviteUserToTeamAction
{
public function __construct(
private RoleRepositoryInterface $roleRepository,
private RoleChangeLogger $roleChangeLogger,
) {
}
public function execute(UserInvitationDTO $dto): void
{
/** @var Invitation $invitation */
$invitation = Invitation::updateOrCreate(
[
'team_id' => $dto->teamId,
'email' => $dto->email,
],
[
'group_id' => $dto->groupId,
'secondary_email' => $dto->secondaryEmail,
'crm_required' => $dto->crmRequired,
'token' => Str::random(40),
'is_owner' => $dto->isOwner,
]
)->loadMissing(['team']);
$invitation->roles()->sync($dto->roleIds);
$notifiable = new EmailNotifiable($invitation->email, $invitation->getTeam());
$logMessage = 'User invited to trial';
if ($invitation->getTeam()->owner_id === null) {
$notifiable->notifyNow(new OwnerInvitedToTrial($invitation));
$logMessage = 'Owner invited to trial';
} else {
$notifiable->notifyNow(new UserInvitedToTeam($invitation));
}
collect($dto->roleIds)
->map(fn (int $roleId): Role => $this->roleRepository->get($roleId))
->each(function (Role $role) use ($dto, $invitation): void {
$this->roleChangeLogger->log(
$dto->currentUser,
$invitation,
$role,
$invitation->wasRecentlyCreated
? RoleChangeType::INVITE_USER
: RoleChangeType::RESEND_INVITATION,
RoleChangeContext::APP,
);
});
Log::info($logMessage, [
'teamId' => $invitation->team_id,
'teamName' => $invitation->getTeam()->name,
'email' => $invitation->email,
'crmRequired' => $invitation->crm_required ? 'yes' : 'no',
]);
$invitation->touch();
}
public function executeWithEmailOnly(User $user): void
{
$notifiable = new EmailNotifiable($user->getEmailAddress(), $user->getTeam());
$notifiable->notifyNow(new UserInvitedToTeamWithEmailOnly($user));
}
}
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
40
1
40
64
Previous Highlighted Error
Next Highlighted Error
SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993
SELECT * FROM users WHERE id = 25061;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 994;
SELECT * FROM crm_profiles WHERE user_id = 25061;
select * from crm_configurations where id = 834;
SELECT * FROM teams WHERE id = 882;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;
SELECT * FROM contacts where crm_configuration_id = 834;
SELECT * FROM opportunities WHERE team_id = 933
# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');
AND id IN (8482561,18352941,19042734,19232139,19445140,19472541);
SELECT * FROM opportunity_contacts
WHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 485; #
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
select crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id
where crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')
# and l.converted_at IS NOT NULL
;
# [PASSWORD_DOTS]
SELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')
and opportunity_id IS NULL
order by id desc;
SELECT * FROM teams WHERE id = 604; # 598
SELECT * FROM activities WHERE id = 74410828; # [EMAIL]
SELECT * FROM accounts WHERE id = 20068382;
SELECT * FROM accounts WHERE id = 35186038;
SELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 559 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;
select * from sidekick_settings where team_id = 781;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100
SELECT * FROM crm_layouts WHERE crm_configuration_id = 711;
SELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL
and is_internal = 0 and status = 'completed'
order by id desc;
SELECT * FROM crm_layout_entities
WHERE crm_layout_id IN (2352, 2353);
;
SELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 556 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;
SELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;
select * from contacts
where crm_configuration_id = 530
and crm_provider_id = 872252;
select * from activities where crm_configuration_id = 530
and user_id = 14343 and type like '%softphone%'
and created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);
SELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t
JOIN crm_configurations c ON t.id = c.team_id
WHERE t.status = 'active';
SELECT * FROM teams where id = 1091;
SELECT * FROM crm_configurations where team_id = 1091;
SELECT * FROM activity_providers where team_id = 1091;
SELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT * FROM teams WHERE name LIKE '%Leadventure%';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1091 and sa.provider = 'salesforce';
SELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812
SELECT * FROM teams where id = 862;
SELECT * FROM crm_configurations where team_id = 862;
SELECT * FROM activity_providers where team_id = 862;
SELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT t.id, crm.id, crm.provider, ap.* FROM teams t
join crm_configurations crm on t.id = crm.team_id
join activity_providers ap on t.id = ap.team_id
where t.status = 'active' and ap.is_enabled = 1
and crm.provider = 'hubspot'
and ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',
'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');
SELECT * FROM teams where id = 1068;
SELECT * FROM crm_configurations where team_id = 1068;
SELECT * FROM activity_providers where team_id = 1068;
SELECT * FROM activities a
where crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')
and a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'
)
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by a.id desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1068 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262
SELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
select * from crm_layouts where crm_configuration_id = 834;
select * from crm_layout_entities where crm_layout_id = 2780;
select * from crm_fields where id IN (321153,321192,321193,321194);
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1057 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8
SELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20
SELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10
SELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #
SELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;
select * from users where team_id = 51; # 7783
SELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130
select * from activity_searches where user_id = 7783;
select * from activity_search_filters where activity_search_id IN (32291, 32292);
SELECT asf.activity_search_id, asf.id, asf.value
FROM activity_search_filters asf
WHERE asf.filter = 'group_id'
AND asf.value IN (
SELECT CONCAT(
HEX(SUBSTR(uuid, 5, 4)), '-',
HEX(SUBSTR(uuid, 3, 2)), '-',
HEX(SUBSTR(uuid, 1, 2)), '-',
HEX(SUBSTR(uuid, 9, 2)), '-',
HEX(SUBSTR(uuid, 11))
)
FROM groups
WHERE deleted_at IS NOT NULL
);
SELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where provider = 'hubspot';
SELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133
SELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null
# [PASSWORD_DOTS]
select * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';
select
cp.*
# DISTINCT t.id
# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields
FROM crm_profiles cp
JOIN crm_configurations crm on crm.id = cp.crm_configuration_id
JOIN users u on u.id = cp.user_id
JOIN teams t ON t.id = crm.team_id
WHERE crm.provider = 'salesforce' and t.status = 'active'
and cp.archived_at IS NULL and u.deleted_at IS NULL
and t.id NOT IN (1093)
and t.id = 2
and cp.contact_fields IS NULL;
# and c.crm_provider_id = '003Uu00000ojD4NIAU';
SELECT * FROM users WHERE id = 26484;
SELECT * FROM crm_profiles WHERE user_id = 26484;
SELECT * FROM social_accounts WHERE sociable_id = 26484;
SELECT * FROM crm_configurations where provider = 'salesforce';
select * from users where id IN (10022, 10403);
select * from users where team_id IN (526);
select * from teams where id IN (526, 532);
select * from crm_configurations where id IN (500, 516);
select * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);
select * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 526 and sa.provider = 'salesforce';
select * from team_settings where team_id IN (526, 532);
select * from users where id IN (22824);
select * from crm_profiles where crm_configuration_id IN (1026);
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1093 and sa.provider = 'salesforce';
select * from teams where id = 1099;
select * from users where id = 29643
select * from activity_processing_states;
SELECT * FROM teams where name LIKE '%Fare%'; # 233
SELECT * FROM opportunities where crm_configuration_id = 215
# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'
;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1088 and sa.provider = 'hubspot';
SELECT * FROM teams order by updated_at DESC
SELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account
select * from crm_configurations where provider = 'pipedrive';
select * from teams where id = 957;
select * from crm_configurations where id = 957;
SELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743
SELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;
select * from users where team_id = 1; # 26726 - Gabriela Dureva
SELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific
select * from activities where user_id = 26726 order by id desc;
select * from contacts where crm_configuration_id = 1
and email IN ('[EMAIL]', '[EMAIL]'); # 2094416, 2093620
SELECT * FROM contacts WHERE id = 6284931;
SELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id
WHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;
select * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);
select * from crm_configurations where id = 1;
43801692-1aeb-32ce-acba-5b80a479701a
44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b
405975c0-b3d0-7aaa-821f-09d59cae6dd1
4caf848d-4bed-2299-b248-7788d41f9fca
49bedc3f-f196-eef3-89c3-dea6a3b4aa63
43420989-a09d-b8f8-9806-c8bbf7a02aac
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
SELECT * FROM activities WHERE id = 75461988;
SELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;
select * from contacts where id = 17900517;
select * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id
where crm.provider != 'salesforce';
select * from users where id = 21047;
SELECT * FROM crm_configurations WHERE id = 892;
SELECT * FROM teams WHERE id = 942;
select * from opportunities where team_id = 942 order by updated_at desc;
select * from contacts where team_id = 942 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 942 and sa.provider = 'hubspot';
SELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430
SELECT * FROM crm_configurations WHERE id = 1;
SELECT * FROM teams WHERE crm_id = 1;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
select id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1
SELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430
select * from teams where id = 852;
select * from groups where id = 2286;
select * from sidekick_settings where team_id = 852;
select * from default_activity_types where team_id = 852;
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1 AND u.deleted_at IS NULL
AND u.crm_required = 1
AND u.team_id = 1
ORDER BY u.team_id;
SELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (
18481
);
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1
AND u.deleted_at IS NULL
AND u.crm_required = 1
# AND u.team_id = 1
AND p.id IS NULL -- Move this condition to WHERE clause
ORDER BY u.team_id;
SELECT * FROM opportunities WHERE id = 20002609;
select * from teams where id = 1122; # Velatir, 29953 - [EMAIL]
select * from crm_configurations where id = 1060;
select * from crm_layouts where crm_configuration_id = 1060;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1122 and sa.provider = 'hubspot';
select * from opportunities where team_id = 1122 order by updated_at desc;
select * from crm_field_data where object_type = 'contact';
SELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 248 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS
SELECT * FROM users where id = 24115;
SELECT * FROM accounts where id = 4002896;
SELECT * FROM teams WHERE name LIKE '%adswerve%';
SELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN ("0069N000003GIQ9QAO","0061r000019yGP9AAM","0066900001S2KWlAAN","0066900001TDpj2AAD","0066900001b8uEwAAI","0069N000001rQi0QAE","006QF00000KD40mYAD","006QF00000LzpRJYAZ","0069N000002uomtQAA","0069N000002xlMLQAY","0066900001NV6ubAAD","0061r00001HJp45AAD","006QF00000uTlUoYAK","006QF00000v0bZqYAI");
SELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203
SELECT u.id, u.email, ac.name, a.* FROM activities a
JOIN users u ON a.user_id = u.id
JOIN accounts ac ON a.account_id = ac.id
WHERE
uuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or
uuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or
uuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;
select * from users where id = 5825;
SELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;
select * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;
19594, 862
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 862 and sa.provider = 'salesforce';
select * from automated_reports where id = 36;
select ar.frequency, r.*, ar.* from automated_report_results r
join automated_reports ar on r.report_id = ar.id
where ar.frequency != 'one_off';
select s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;
select * from nudges n where n.activity_search_id
select * from teams where created_at > '2026-03-09';
SELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;
select * from users where team_id = 1 and name like '%Lukas%'; # 7160
SELECT * FROM teams WHERE id = 575;
select * from opportunities where team_id = 575;
SELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,
select * from opportunities where team_id = 1126;
SELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,
select * from opportunities where team_id = 1125;
select * from contacts c
where c.team_id = 882;
SELECT * FROM activities WHERE id = 76822967;
SELECT * FROM crm_profiles WHERE user_id = 15440;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 555;
SELECT * FROM crm_configurations WHERE id = 555;
SELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 581 and sa.provider = 'salesforce';
SELECT * FROM automated_report_results order by id desc;
select * from features;
select * from team_features where feature_id = 40;
select * from teams where id = 556;
select * from automated_reports;
where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , ["pdf","podcast"]
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
select * from automated_report_results order by id desc;
SELECT * FROM automated_report_results WHERE id = 1919;
select * from automated_report_results WHERE report_id = 54;
select * from opportunities where id = 7594349;
SELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - [EMAIL]
select * from playbooks where team_id = 711; # event 226147
SELECT * FROM playbook_categories WHERE playbook_id = 5515;
SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';
SELECT * FROM crm_fields WHERE id = 226147;
SELECT * FROM crm_field_values WHERE crm_field_id = 226147;
SELECT * FROM crm_configurations WHERE id = 692;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 711 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;
select * from leads;
select * from calendars;
SELECT
t.id AS team_id,
t.name,
LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain
FROM teams t
JOIN users u ON u.team_id = t.id
JOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'
LEFT JOIN team_domains td
ON td.team_id = t.id
AND td.deleted_at IS NULL
AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))
GROUP BY t.id, t.name, calendar_domain
ORDER BY t.name, calendar_domain;
select * from users u join calendars c on c.user_id = u.id
where u.team_id = 882;
select * from activities where id = 74049485; # team 563 crm 537
select * from activities where id = 73272382; # team 563 crm 537
select * from activities where id = 64400389; # team 563 crm 537
select * from activities where id = 58081273; # team 563 crm 537
select * from activities where id = 54520297; # team 563 crm 537
select * from participants where activity_id = 58081273;
select * from activities where crm_configuration_id = 537 and provider = 'aircall'
and account_id = 19003658 order by updated_at desc;
select * from contacts where crm_configuration_id = 537 and id = 35957759;
select * from accounts where crm_configuration_id = 537 and id = 19003658;
select * from automated_report_results where id = 1976;
select * from automated_reports where id = 583;
select * from activity_searches where id = 87714;
select * from activity_search_filters where activity_search_id = 87714;
SELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid
or uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;
SELECT * FROM crm_configurations WHERE provider = 'hubspot';
select * from rate_limits;
select * from automated_report_results where media_type = 'pdf' and status = 2
and id IN (18, 1872);
select * from automated_reports where id = 54;
SELECT * FROM users WHERE id IN (24623,29443,29613);
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app, folder
.circleci, folder
.cursor, folder
.github
.sonarlint, folder
.vscode, folder
.windsurf, folder
app, sources root
Actions
InviteUserToTeamAction.php, class
MarkUserAsOnboardableAction.php, class
SyncRecordingFlagsAction.php, class
UpdateTeamMemberAction.php, class
UpdateUserRolesAction.php, class
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags
FFMpeg
FileSystem
Gecko
Gong
GuzzleHttp
KeyPoints
Kiosk
LanguageDetection
LiveFeed
Locks
Math
MediaPipeline
MeetingBot, folder
MobileSettings, folder
Model, folder...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"3","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"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\\Actions;\n\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Support\\Str;\nuse Jiminny\\Component\\Acl\\RoleChangeContext;\nuse Jiminny\\Component\\Acl\\RoleChangeLogger;\nuse Jiminny\\Component\\Acl\\RoleChangeType;\nuse Jiminny\\Contracts\\Acl\\RoleRepositoryInterface;\nuse Jiminny\\DTO\\Invitation\\UserInvitationDTO;\nuse Jiminny\\Models\\Invitation;\nuse Jiminny\\Models\\Role;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Notifications\\Channels\\EmailNotifiable;\nuse Jiminny\\Notifications\\OwnerInvitedToTrial;\nuse Jiminny\\Notifications\\UserInvitedToTeam;\nuse Jiminny\\Notifications\\UserInvitedToTeamWithEmailOnly;\n\nclass InviteUserToTeamAction\n{\n public function __construct(\n private RoleRepositoryInterface $roleRepository,\n private RoleChangeLogger $roleChangeLogger,\n ) {\n }\n\n public function execute(UserInvitationDTO $dto): void\n {\n /** @var Invitation $invitation */\n $invitation = Invitation::updateOrCreate(\n [\n 'team_id' => $dto->teamId,\n 'email' => $dto->email,\n ],\n [\n 'group_id' => $dto->groupId,\n 'secondary_email' => $dto->secondaryEmail,\n 'crm_required' => $dto->crmRequired,\n 'token' => Str::random(40),\n 'is_owner' => $dto->isOwner,\n ]\n )->loadMissing(['team']);\n\n $invitation->roles()->sync($dto->roleIds);\n\n $notifiable = new EmailNotifiable($invitation->email, $invitation->getTeam());\n\n $logMessage = 'User invited to trial';\n\n if ($invitation->getTeam()->owner_id === null) {\n $notifiable->notifyNow(new OwnerInvitedToTrial($invitation));\n\n $logMessage = 'Owner invited to trial';\n } else {\n $notifiable->notifyNow(new UserInvitedToTeam($invitation));\n }\n\n collect($dto->roleIds)\n ->map(fn (int $roleId): Role => $this->roleRepository->get($roleId))\n ->each(function (Role $role) use ($dto, $invitation): void {\n $this->roleChangeLogger->log(\n $dto->currentUser,\n $invitation,\n $role,\n $invitation->wasRecentlyCreated\n ? RoleChangeType::INVITE_USER\n : RoleChangeType::RESEND_INVITATION,\n RoleChangeContext::APP,\n );\n });\n\n Log::info($logMessage, [\n 'teamId' => $invitation->team_id,\n 'teamName' => $invitation->getTeam()->name,\n 'email' => $invitation->email,\n 'crmRequired' => $invitation->crm_required ? 'yes' : 'no',\n ]);\n\n $invitation->touch();\n }\n\n public function executeWithEmailOnly(User $user): void\n {\n $notifiable = new EmailNotifiable($user->getEmailAddress(), $user->getTeam());\n\n $notifiable->notifyNow(new UserInvitedToTeamWithEmailOnly($user));\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Actions;\n\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Support\\Str;\nuse Jiminny\\Component\\Acl\\RoleChangeContext;\nuse Jiminny\\Component\\Acl\\RoleChangeLogger;\nuse Jiminny\\Component\\Acl\\RoleChangeType;\nuse Jiminny\\Contracts\\Acl\\RoleRepositoryInterface;\nuse Jiminny\\DTO\\Invitation\\UserInvitationDTO;\nuse Jiminny\\Models\\Invitation;\nuse Jiminny\\Models\\Role;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Notifications\\Channels\\EmailNotifiable;\nuse Jiminny\\Notifications\\OwnerInvitedToTrial;\nuse Jiminny\\Notifications\\UserInvitedToTeam;\nuse Jiminny\\Notifications\\UserInvitedToTeamWithEmailOnly;\n\nclass InviteUserToTeamAction\n{\n public function __construct(\n private RoleRepositoryInterface $roleRepository,\n private RoleChangeLogger $roleChangeLogger,\n ) {\n }\n\n public function execute(UserInvitationDTO $dto): void\n {\n /** @var Invitation $invitation */\n $invitation = Invitation::updateOrCreate(\n [\n 'team_id' => $dto->teamId,\n 'email' => $dto->email,\n ],\n [\n 'group_id' => $dto->groupId,\n 'secondary_email' => $dto->secondaryEmail,\n 'crm_required' => $dto->crmRequired,\n 'token' => Str::random(40),\n 'is_owner' => $dto->isOwner,\n ]\n )->loadMissing(['team']);\n\n $invitation->roles()->sync($dto->roleIds);\n\n $notifiable = new EmailNotifiable($invitation->email, $invitation->getTeam());\n\n $logMessage = 'User invited to trial';\n\n if ($invitation->getTeam()->owner_id === null) {\n $notifiable->notifyNow(new OwnerInvitedToTrial($invitation));\n\n $logMessage = 'Owner invited to trial';\n } else {\n $notifiable->notifyNow(new UserInvitedToTeam($invitation));\n }\n\n collect($dto->roleIds)\n ->map(fn (int $roleId): Role => $this->roleRepository->get($roleId))\n ->each(function (Role $role) use ($dto, $invitation): void {\n $this->roleChangeLogger->log(\n $dto->currentUser,\n $invitation,\n $role,\n $invitation->wasRecentlyCreated\n ? RoleChangeType::INVITE_USER\n : RoleChangeType::RESEND_INVITATION,\n RoleChangeContext::APP,\n );\n });\n\n Log::info($logMessage, [\n 'teamId' => $invitation->team_id,\n 'teamName' => $invitation->getTeam()->name,\n 'email' => $invitation->email,\n 'crmRequired' => $invitation->crm_required ? 'yes' : 'no',\n ]);\n\n $invitation->touch();\n }\n\n public function executeWithEmailOnly(User $user): void\n {\n $notifiable = new EmailNotifiable($user->getEmailAddress(), $user->getTeam());\n\n $notifiable->notifyNow(new UserInvitedToTeamWithEmailOnly($user));\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":"40","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"40","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"64","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","depth":4,"on_screen":true,"value":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app, 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":".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":true,"role_description":"text"},{"role":"AXStaticText","text":".vscode, folder","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".windsurf, folder","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"InviteUserToTeamAction.php, class","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"MarkUserAsOnboardableAction.php, class","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SyncRecordingFlagsAction.php, class","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"UpdateTeamMemberAction.php, class","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"UpdateUserRolesAction.php, class","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Dtos","depth":10,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Events","depth":10,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Country","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Database","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Datadog","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"DateTime","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Encoding","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Encryption","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ES","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Faker","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlags","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"FFMpeg","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"FileSystem","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Gecko","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Gong","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"GuzzleHttp","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"KeyPoints","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Kiosk","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"LanguageDetection","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"LiveFeed","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Locks","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Math","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"MediaPipeline","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"MeetingBot, folder","depth":9,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"MobileSettings, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Model, folder","depth":9,"on_screen":false,"role_description":"text"}]...
|
2213224875418358514
|
1065696228461131589
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
3
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Actions;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Jiminny\Component\Acl\RoleChangeContext;
use Jiminny\Component\Acl\RoleChangeLogger;
use Jiminny\Component\Acl\RoleChangeType;
use Jiminny\Contracts\Acl\RoleRepositoryInterface;
use Jiminny\DTO\Invitation\UserInvitationDTO;
use Jiminny\Models\Invitation;
use Jiminny\Models\Role;
use Jiminny\Models\User;
use Jiminny\Notifications\Channels\EmailNotifiable;
use Jiminny\Notifications\OwnerInvitedToTrial;
use Jiminny\Notifications\UserInvitedToTeam;
use Jiminny\Notifications\UserInvitedToTeamWithEmailOnly;
class InviteUserToTeamAction
{
public function __construct(
private RoleRepositoryInterface $roleRepository,
private RoleChangeLogger $roleChangeLogger,
) {
}
public function execute(UserInvitationDTO $dto): void
{
/** @var Invitation $invitation */
$invitation = Invitation::updateOrCreate(
[
'team_id' => $dto->teamId,
'email' => $dto->email,
],
[
'group_id' => $dto->groupId,
'secondary_email' => $dto->secondaryEmail,
'crm_required' => $dto->crmRequired,
'token' => Str::random(40),
'is_owner' => $dto->isOwner,
]
)->loadMissing(['team']);
$invitation->roles()->sync($dto->roleIds);
$notifiable = new EmailNotifiable($invitation->email, $invitation->getTeam());
$logMessage = 'User invited to trial';
if ($invitation->getTeam()->owner_id === null) {
$notifiable->notifyNow(new OwnerInvitedToTrial($invitation));
$logMessage = 'Owner invited to trial';
} else {
$notifiable->notifyNow(new UserInvitedToTeam($invitation));
}
collect($dto->roleIds)
->map(fn (int $roleId): Role => $this->roleRepository->get($roleId))
->each(function (Role $role) use ($dto, $invitation): void {
$this->roleChangeLogger->log(
$dto->currentUser,
$invitation,
$role,
$invitation->wasRecentlyCreated
? RoleChangeType::INVITE_USER
: RoleChangeType::RESEND_INVITATION,
RoleChangeContext::APP,
);
});
Log::info($logMessage, [
'teamId' => $invitation->team_id,
'teamName' => $invitation->getTeam()->name,
'email' => $invitation->email,
'crmRequired' => $invitation->crm_required ? 'yes' : 'no',
]);
$invitation->touch();
}
public function executeWithEmailOnly(User $user): void
{
$notifiable = new EmailNotifiable($user->getEmailAddress(), $user->getTeam());
$notifiable->notifyNow(new UserInvitedToTeamWithEmailOnly($user));
}
}
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
40
1
40
64
Previous Highlighted Error
Next Highlighted Error
SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993
SELECT * FROM users WHERE id = 25061;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 994;
SELECT * FROM crm_profiles WHERE user_id = 25061;
select * from crm_configurations where id = 834;
SELECT * FROM teams WHERE id = 882;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;
SELECT * FROM contacts where crm_configuration_id = 834;
SELECT * FROM opportunities WHERE team_id = 933
# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');
AND id IN (8482561,18352941,19042734,19232139,19445140,19472541);
SELECT * FROM opportunity_contacts
WHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 485; #
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
select crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id
where crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')
# and l.converted_at IS NOT NULL
;
# [PASSWORD_DOTS]
SELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')
and opportunity_id IS NULL
order by id desc;
SELECT * FROM teams WHERE id = 604; # 598
SELECT * FROM activities WHERE id = 74410828; # [EMAIL]
SELECT * FROM accounts WHERE id = 20068382;
SELECT * FROM accounts WHERE id = 35186038;
SELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 559 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;
select * from sidekick_settings where team_id = 781;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100
SELECT * FROM crm_layouts WHERE crm_configuration_id = 711;
SELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL
and is_internal = 0 and status = 'completed'
order by id desc;
SELECT * FROM crm_layout_entities
WHERE crm_layout_id IN (2352, 2353);
;
SELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 556 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;
SELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;
select * from contacts
where crm_configuration_id = 530
and crm_provider_id = 872252;
select * from activities where crm_configuration_id = 530
and user_id = 14343 and type like '%softphone%'
and created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);
SELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t
JOIN crm_configurations c ON t.id = c.team_id
WHERE t.status = 'active';
SELECT * FROM teams where id = 1091;
SELECT * FROM crm_configurations where team_id = 1091;
SELECT * FROM activity_providers where team_id = 1091;
SELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT * FROM teams WHERE name LIKE '%Leadventure%';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1091 and sa.provider = 'salesforce';
SELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812
SELECT * FROM teams where id = 862;
SELECT * FROM crm_configurations where team_id = 862;
SELECT * FROM activity_providers where team_id = 862;
SELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT t.id, crm.id, crm.provider, ap.* FROM teams t
join crm_configurations crm on t.id = crm.team_id
join activity_providers ap on t.id = ap.team_id
where t.status = 'active' and ap.is_enabled = 1
and crm.provider = 'hubspot'
and ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',
'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');
SELECT * FROM teams where id = 1068;
SELECT * FROM crm_configurations where team_id = 1068;
SELECT * FROM activity_providers where team_id = 1068;
SELECT * FROM activities a
where crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')
and a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'
)
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by a.id desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1068 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262
SELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
select * from crm_layouts where crm_configuration_id = 834;
select * from crm_layout_entities where crm_layout_id = 2780;
select * from crm_fields where id IN (321153,321192,321193,321194);
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1057 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8
SELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20
SELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10
SELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #
SELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;
select * from users where team_id = 51; # 7783
SELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130
select * from activity_searches where user_id = 7783;
select * from activity_search_filters where activity_search_id IN (32291, 32292);
SELECT asf.activity_search_id, asf.id, asf.value
FROM activity_search_filters asf
WHERE asf.filter = 'group_id'
AND asf.value IN (
SELECT CONCAT(
HEX(SUBSTR(uuid, 5, 4)), '-',
HEX(SUBSTR(uuid, 3, 2)), '-',
HEX(SUBSTR(uuid, 1, 2)), '-',
HEX(SUBSTR(uuid, 9, 2)), '-',
HEX(SUBSTR(uuid, 11))
)
FROM groups
WHERE deleted_at IS NOT NULL
);
SELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where provider = 'hubspot';
SELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133
SELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null
# [PASSWORD_DOTS]
select * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';
select
cp.*
# DISTINCT t.id
# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields
FROM crm_profiles cp
JOIN crm_configurations crm on crm.id = cp.crm_configuration_id
JOIN users u on u.id = cp.user_id
JOIN teams t ON t.id = crm.team_id
WHERE crm.provider = 'salesforce' and t.status = 'active'
and cp.archived_at IS NULL and u.deleted_at IS NULL
and t.id NOT IN (1093)
and t.id = 2
and cp.contact_fields IS NULL;
# and c.crm_provider_id = '003Uu00000ojD4NIAU';
SELECT * FROM users WHERE id = 26484;
SELECT * FROM crm_profiles WHERE user_id = 26484;
SELECT * FROM social_accounts WHERE sociable_id = 26484;
SELECT * FROM crm_configurations where provider = 'salesforce';
select * from users where id IN (10022, 10403);
select * from users where team_id IN (526);
select * from teams where id IN (526, 532);
select * from crm_configurations where id IN (500, 516);
select * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);
select * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 526 and sa.provider = 'salesforce';
select * from team_settings where team_id IN (526, 532);
select * from users where id IN (22824);
select * from crm_profiles where crm_configuration_id IN (1026);
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1093 and sa.provider = 'salesforce';
select * from teams where id = 1099;
select * from users where id = 29643
select * from activity_processing_states;
SELECT * FROM teams where name LIKE '%Fare%'; # 233
SELECT * FROM opportunities where crm_configuration_id = 215
# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'
;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1088 and sa.provider = 'hubspot';
SELECT * FROM teams order by updated_at DESC
SELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account
select * from crm_configurations where provider = 'pipedrive';
select * from teams where id = 957;
select * from crm_configurations where id = 957;
SELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743
SELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;
select * from users where team_id = 1; # 26726 - Gabriela Dureva
SELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific
select * from activities where user_id = 26726 order by id desc;
select * from contacts where crm_configuration_id = 1
and email IN ('[EMAIL]', '[EMAIL]'); # 2094416, 2093620
SELECT * FROM contacts WHERE id = 6284931;
SELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id
WHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;
select * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);
select * from crm_configurations where id = 1;
43801692-1aeb-32ce-acba-5b80a479701a
44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b
405975c0-b3d0-7aaa-821f-09d59cae6dd1
4caf848d-4bed-2299-b248-7788d41f9fca
49bedc3f-f196-eef3-89c3-dea6a3b4aa63
43420989-a09d-b8f8-9806-c8bbf7a02aac
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
SELECT * FROM activities WHERE id = 75461988;
SELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;
select * from contacts where id = 17900517;
select * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id
where crm.provider != 'salesforce';
select * from users where id = 21047;
SELECT * FROM crm_configurations WHERE id = 892;
SELECT * FROM teams WHERE id = 942;
select * from opportunities where team_id = 942 order by updated_at desc;
select * from contacts where team_id = 942 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 942 and sa.provider = 'hubspot';
SELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430
SELECT * FROM crm_configurations WHERE id = 1;
SELECT * FROM teams WHERE crm_id = 1;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
select id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1
SELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430
select * from teams where id = 852;
select * from groups where id = 2286;
select * from sidekick_settings where team_id = 852;
select * from default_activity_types where team_id = 852;
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1 AND u.deleted_at IS NULL
AND u.crm_required = 1
AND u.team_id = 1
ORDER BY u.team_id;
SELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (
18481
);
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1
AND u.deleted_at IS NULL
AND u.crm_required = 1
# AND u.team_id = 1
AND p.id IS NULL -- Move this condition to WHERE clause
ORDER BY u.team_id;
SELECT * FROM opportunities WHERE id = 20002609;
select * from teams where id = 1122; # Velatir, 29953 - [EMAIL]
select * from crm_configurations where id = 1060;
select * from crm_layouts where crm_configuration_id = 1060;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1122 and sa.provider = 'hubspot';
select * from opportunities where team_id = 1122 order by updated_at desc;
select * from crm_field_data where object_type = 'contact';
SELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 248 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS
SELECT * FROM users where id = 24115;
SELECT * FROM accounts where id = 4002896;
SELECT * FROM teams WHERE name LIKE '%adswerve%';
SELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN ("0069N000003GIQ9QAO","0061r000019yGP9AAM","0066900001S2KWlAAN","0066900001TDpj2AAD","0066900001b8uEwAAI","0069N000001rQi0QAE","006QF00000KD40mYAD","006QF00000LzpRJYAZ","0069N000002uomtQAA","0069N000002xlMLQAY","0066900001NV6ubAAD","0061r00001HJp45AAD","006QF00000uTlUoYAK","006QF00000v0bZqYAI");
SELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203
SELECT u.id, u.email, ac.name, a.* FROM activities a
JOIN users u ON a.user_id = u.id
JOIN accounts ac ON a.account_id = ac.id
WHERE
uuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or
uuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or
uuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;
select * from users where id = 5825;
SELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;
select * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;
19594, 862
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 862 and sa.provider = 'salesforce';
select * from automated_reports where id = 36;
select ar.frequency, r.*, ar.* from automated_report_results r
join automated_reports ar on r.report_id = ar.id
where ar.frequency != 'one_off';
select s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;
select * from nudges n where n.activity_search_id
select * from teams where created_at > '2026-03-09';
SELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;
select * from users where team_id = 1 and name like '%Lukas%'; # 7160
SELECT * FROM teams WHERE id = 575;
select * from opportunities where team_id = 575;
SELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,
select * from opportunities where team_id = 1126;
SELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,
select * from opportunities where team_id = 1125;
select * from contacts c
where c.team_id = 882;
SELECT * FROM activities WHERE id = 76822967;
SELECT * FROM crm_profiles WHERE user_id = 15440;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 555;
SELECT * FROM crm_configurations WHERE id = 555;
SELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 581 and sa.provider = 'salesforce';
SELECT * FROM automated_report_results order by id desc;
select * from features;
select * from team_features where feature_id = 40;
select * from teams where id = 556;
select * from automated_reports;
where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , ["pdf","podcast"]
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
select * from automated_report_results order by id desc;
SELECT * FROM automated_report_results WHERE id = 1919;
select * from automated_report_results WHERE report_id = 54;
select * from opportunities where id = 7594349;
SELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - [EMAIL]
select * from playbooks where team_id = 711; # event 226147
SELECT * FROM playbook_categories WHERE playbook_id = 5515;
SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';
SELECT * FROM crm_fields WHERE id = 226147;
SELECT * FROM crm_field_values WHERE crm_field_id = 226147;
SELECT * FROM crm_configurations WHERE id = 692;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 711 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;
select * from leads;
select * from calendars;
SELECT
t.id AS team_id,
t.name,
LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain
FROM teams t
JOIN users u ON u.team_id = t.id
JOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'
LEFT JOIN team_domains td
ON td.team_id = t.id
AND td.deleted_at IS NULL
AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))
GROUP BY t.id, t.name, calendar_domain
ORDER BY t.name, calendar_domain;
select * from users u join calendars c on c.user_id = u.id
where u.team_id = 882;
select * from activities where id = 74049485; # team 563 crm 537
select * from activities where id = 73272382; # team 563 crm 537
select * from activities where id = 64400389; # team 563 crm 537
select * from activities where id = 58081273; # team 563 crm 537
select * from activities where id = 54520297; # team 563 crm 537
select * from participants where activity_id = 58081273;
select * from activities where crm_configuration_id = 537 and provider = 'aircall'
and account_id = 19003658 order by updated_at desc;
select * from contacts where crm_configuration_id = 537 and id = 35957759;
select * from accounts where crm_configuration_id = 537 and id = 19003658;
select * from automated_report_results where id = 1976;
select * from automated_reports where id = 583;
select * from activity_searches where id = 87714;
select * from activity_search_filters where activity_search_id = 87714;
SELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid
or uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;
SELECT * FROM crm_configurations WHERE provider = 'hubspot';
select * from rate_limits;
select * from automated_report_results where media_type = 'pdf' and status = 2
and id IN (18, 1872);
select * from automated_reports where id = 54;
SELECT * FROM users WHERE id IN (24623,29443,29613);
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app, folder
.circleci, folder
.cursor, folder
.github
.sonarlint, folder
.vscode, folder
.windsurf, folder
app, sources root
Actions
InviteUserToTeamAction.php, class
MarkUserAsOnboardableAction.php, class
SyncRecordingFlagsAction.php, class
UpdateTeamMemberAction.php, class
UpdateUserRolesAction.php, class
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags
FFMpeg
FileSystem
Gecko
Gong
GuzzleHttp
KeyPoints
Kiosk
LanguageDetection
LiveFeed
Locks
Math
MediaPipeline
MeetingBot, folder
MobileSettings, folder
Model, folder...
|
32899
|
NULL
|
NULL
|
NULL
|
|
32901
|
1257
|
14
|
2026-05-13T09:44:53.090869+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665493090_m2.jpg...
|
PhpStorm
|
faVsco.js – InviteUserToTeamAction.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
3
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Actions;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Jiminny\Component\Acl\RoleChangeContext;
use Jiminny\Component\Acl\RoleChangeLogger;
use Jiminny\Component\Acl\RoleChangeType;
use Jiminny\Contracts\Acl\RoleRepositoryInterface;
use Jiminny\DTO\Invitation\UserInvitationDTO;
use Jiminny\Models\Invitation;
use Jiminny\Models\Role;
use Jiminny\Models\User;
use Jiminny\Notifications\Channels\EmailNotifiable;
use Jiminny\Notifications\OwnerInvitedToTrial;
use Jiminny\Notifications\UserInvitedToTeam;
use Jiminny\Notifications\UserInvitedToTeamWithEmailOnly;
class InviteUserToTeamAction
{
public function __construct(
private RoleRepositoryInterface $roleRepository,
private RoleChangeLogger $roleChangeLogger,
) {
}
public function execute(UserInvitationDTO $dto): void
{
/** @var Invitation $invitation */
$invitation = Invitation::updateOrCreate(
[
'team_id' => $dto->teamId,
'email' => $dto->email,
],
[
'group_id' => $dto->groupId,
'secondary_email' => $dto->secondaryEmail,
'crm_required' => $dto->crmRequired,
'token' => Str::random(40),
'is_owner' => $dto->isOwner,
]
)->loadMissing(['team']);
$invitation->roles()->sync($dto->roleIds);
$notifiable = new EmailNotifiable($invitation->email, $invitation->getTeam());
$logMessage = 'User invited to trial';
if ($invitation->getTeam()->owner_id === null) {
$notifiable->notifyNow(new OwnerInvitedToTrial($invitation));
$logMessage = 'Owner invited to trial';
} else {
$notifiable->notifyNow(new UserInvitedToTeam($invitation));
}
collect($dto->roleIds)
->map(fn (int $roleId): Role => $this->roleRepository->get($roleId))
->each(function (Role $role) use ($dto, $invitation): void {
$this->roleChangeLogger->log(
$dto->currentUser,
$invitation,
$role,
$invitation->wasRecentlyCreated
? RoleChangeType::INVITE_USER
: RoleChangeType::RESEND_INVITATION,
RoleChangeContext::APP,
);
});
Log::info($logMessage, [
'teamId' => $invitation->team_id,
'teamName' => $invitation->getTeam()->name,
'email' => $invitation->email,
'crmRequired' => $invitation->crm_required ? 'yes' : 'no',
]);
$invitation->touch();
}
public function executeWithEmailOnly(User $user): void
{
$notifiable = new EmailNotifiable($user->getEmailAddress(), $user->getTeam());
$notifiable->notifyNow(new UserInvitedToTeamWithEmailOnly($user));
}
}
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
40
1
40
64
Previous Highlighted Error
Next Highlighted Error
SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993
SELECT * FROM users WHERE id = 25061;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 994;
SELECT * FROM crm_profiles WHERE user_id = 25061;
select * from crm_configurations where id = 834;
SELECT * FROM teams WHERE id = 882;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;
SELECT * FROM contacts where crm_configuration_id = 834;
SELECT * FROM opportunities WHERE team_id = 933
# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');
AND id IN (8482561,18352941,19042734,19232139,19445140,19472541);
SELECT * FROM opportunity_contacts
WHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 485; #
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
select crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id
where crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')
# and l.converted_at IS NOT NULL
;
# [PASSWORD_DOTS]
SELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')
and opportunity_id IS NULL
order by id desc;
SELECT * FROM teams WHERE id = 604; # 598
SELECT * FROM activities WHERE id = 74410828; # [EMAIL]
SELECT * FROM accounts WHERE id = 20068382;
SELECT * FROM accounts WHERE id = 35186038;
SELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 559 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;
select * from sidekick_settings where team_id = 781;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100
SELECT * FROM crm_layouts WHERE crm_configuration_id = 711;
SELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL
and is_internal = 0 and status = 'completed'
order by id desc;
SELECT * FROM crm_layout_entities
WHERE crm_layout_id IN (2352, 2353);
;
SELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 556 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;
SELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;
select * from contacts
where crm_configuration_id = 530
and crm_provider_id = 872252;
select * from activities where crm_configuration_id = 530
and user_id = 14343 and type like '%softphone%'
and created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);
SELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t
JOIN crm_configurations c ON t.id = c.team_id
WHERE t.status = 'active';
SELECT * FROM teams where id = 1091;
SELECT * FROM crm_configurations where team_id = 1091;
SELECT * FROM activity_providers where team_id = 1091;
SELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT * FROM teams WHERE name LIKE '%Leadventure%';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1091 and sa.provider = 'salesforce';
SELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812
SELECT * FROM teams where id = 862;
SELECT * FROM crm_configurations where team_id = 862;
SELECT * FROM activity_providers where team_id = 862;
SELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT t.id, crm.id, crm.provider, ap.* FROM teams t
join crm_configurations crm on t.id = crm.team_id
join activity_providers ap on t.id = ap.team_id
where t.status = 'active' and ap.is_enabled = 1
and crm.provider = 'hubspot'
and ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',
'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');
SELECT * FROM teams where id = 1068;
SELECT * FROM crm_configurations where team_id = 1068;
SELECT * FROM activity_providers where team_id = 1068;
SELECT * FROM activities a
where crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')
and a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'
)
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by a.id desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1068 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262
SELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
select * from crm_layouts where crm_configuration_id = 834;
select * from crm_layout_entities where crm_layout_id = 2780;
select * from crm_fields where id IN (321153,321192,321193,321194);
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1057 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8
SELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20
SELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10
SELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #
SELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;
select * from users where team_id = 51; # 7783
SELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130
select * from activity_searches where user_id = 7783;
select * from activity_search_filters where activity_search_id IN (32291, 32292);
SELECT asf.activity_search_id, asf.id, asf.value
FROM activity_search_filters asf
WHERE asf.filter = 'group_id'
AND asf.value IN (
SELECT CONCAT(
HEX(SUBSTR(uuid, 5, 4)), '-',
HEX(SUBSTR(uuid, 3, 2)), '-',
HEX(SUBSTR(uuid, 1, 2)), '-',
HEX(SUBSTR(uuid, 9, 2)), '-',
HEX(SUBSTR(uuid, 11))
)
FROM groups
WHERE deleted_at IS NOT NULL
);
SELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where provider = 'hubspot';
SELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133
SELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null
# [PASSWORD_DOTS]
select * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';
select
cp.*
# DISTINCT t.id
# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields
FROM crm_profiles cp
JOIN crm_configurations crm on crm.id = cp.crm_configuration_id
JOIN users u on u.id = cp.user_id
JOIN teams t ON t.id = crm.team_id
WHERE crm.provider = 'salesforce' and t.status = 'active'
and cp.archived_at IS NULL and u.deleted_at IS NULL
and t.id NOT IN (1093)
and t.id = 2
and cp.contact_fields IS NULL;
# and c.crm_provider_id = '003Uu00000ojD4NIAU';
SELECT * FROM users WHERE id = 26484;
SELECT * FROM crm_profiles WHERE user_id = 26484;
SELECT * FROM social_accounts WHERE sociable_id = 26484;
SELECT * FROM crm_configurations where provider = 'salesforce';
select * from users where id IN (10022, 10403);
select * from users where team_id IN (526);
select * from teams where id IN (526, 532);
select * from crm_configurations where id IN (500, 516);
select * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);
select * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 526 and sa.provider = 'salesforce';
select * from team_settings where team_id IN (526, 532);
select * from users where id IN (22824);
select * from crm_profiles where crm_configuration_id IN (1026);
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1093 and sa.provider = 'salesforce';
select * from teams where id = 1099;
select * from users where id = 29643
select * from activity_processing_states;
SELECT * FROM teams where name LIKE '%Fare%'; # 233
SELECT * FROM opportunities where crm_configuration_id = 215
# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'
;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1088 and sa.provider = 'hubspot';
SELECT * FROM teams order by updated_at DESC
SELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account
select * from crm_configurations where provider = 'pipedrive';
select * from teams where id = 957;
select * from crm_configurations where id = 957;
SELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743
SELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;
select * from users where team_id = 1; # 26726 - Gabriela Dureva
SELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific
select * from activities where user_id = 26726 order by id desc;
select * from contacts where crm_configuration_id = 1
and email IN ('[EMAIL]', '[EMAIL]'); # 2094416, 2093620
SELECT * FROM contacts WHERE id = 6284931;
SELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id
WHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;
select * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);
select * from crm_configurations where id = 1;
43801692-1aeb-32ce-acba-5b80a479701a
44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b
405975c0-b3d0-7aaa-821f-09d59cae6dd1
4caf848d-4bed-2299-b248-7788d41f9fca
49bedc3f-f196-eef3-89c3-dea6a3b4aa63
43420989-a09d-b8f8-9806-c8bbf7a02aac
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
SELECT * FROM activities WHERE id = 75461988;
SELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;
select * from contacts where id = 17900517;
select * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id
where crm.provider != 'salesforce';
select * from users where id = 21047;
SELECT * FROM crm_configurations WHERE id = 892;
SELECT * FROM teams WHERE id = 942;
select * from opportunities where team_id = 942 order by updated_at desc;
select * from contacts where team_id = 942 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 942 and sa.provider = 'hubspot';
SELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430
SELECT * FROM crm_configurations WHERE id = 1;
SELECT * FROM teams WHERE crm_id = 1;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
select id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1
SELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430
select * from teams where id = 852;
select * from groups where id = 2286;
select * from sidekick_settings where team_id = 852;
select * from default_activity_types where team_id = 852;
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1 AND u.deleted_at IS NULL
AND u.crm_required = 1
AND u.team_id = 1
ORDER BY u.team_id;
SELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (
18481
);
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1
AND u.deleted_at IS NULL
AND u.crm_required = 1
# AND u.team_id = 1
AND p.id IS NULL -- Move this condition to WHERE clause
ORDER BY u.team_id;
SELECT * FROM opportunities WHERE id = 20002609;
select * from teams where id = 1122; # Velatir, 29953 - [EMAIL]
select * from crm_configurations where id = 1060;
select * from crm_layouts where crm_configuration_id = 1060;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1122 and sa.provider = 'hubspot';
select * from opportunities where team_id = 1122 order by updated_at desc;
select * from crm_field_data where object_type = 'contact';
SELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 248 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS
SELECT * FROM users where id = 24115;
SELECT * FROM accounts where id = 4002896;
SELECT * FROM teams WHERE name LIKE '%adswerve%';
SELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN ("0069N000003GIQ9QAO","0061r000019yGP9AAM","0066900001S2KWlAAN","0066900001TDpj2AAD","0066900001b8uEwAAI","0069N000001rQi0QAE","006QF00000KD40mYAD","006QF00000LzpRJYAZ","0069N000002uomtQAA","0069N000002xlMLQAY","0066900001NV6ubAAD","0061r00001HJp45AAD","006QF00000uTlUoYAK","006QF00000v0bZqYAI");
SELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203
SELECT u.id, u.email, ac.name, a.* FROM activities a
JOIN users u ON a.user_id = u.id
JOIN accounts ac ON a.account_id = ac.id
WHERE
uuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or
uuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or
uuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;
select * from users where id = 5825;
SELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;
select * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;
19594, 862
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 862 and sa.provider = 'salesforce';
select * from automated_reports where id = 36;
select ar.frequency, r.*, ar.* from automated_report_results r
join automated_reports ar on r.report_id = ar.id
where ar.frequency != 'one_off';
select s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;
select * from nudges n where n.activity_search_id
select * from teams where created_at > '2026-03-09';
SELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;
select * from users where team_id = 1 and name like '%Lukas%'; # 7160
SELECT * FROM teams WHERE id = 575;
select * from opportunities where team_id = 575;
SELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,
select * from opportunities where team_id = 1126;
SELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,
select * from opportunities where team_id = 1125;
select * from contacts c
where c.team_id = 882;
SELECT * FROM activities WHERE id = 76822967;
SELECT * FROM crm_profiles WHERE user_id = 15440;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 555;
SELECT * FROM crm_configurations WHERE id = 555;
SELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 581 and sa.provider = 'salesforce';
SELECT * FROM automated_report_results order by id desc;
select * from features;
select * from team_features where feature_id = 40;
select * from teams where id = 556;
select * from automated_reports;
where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , ["pdf","podcast"]
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
select * from automated_report_results order by id desc;
SELECT * FROM automated_report_results WHERE id = 1919;
select * from automated_report_results WHERE report_id = 54;
select * from opportunities where id = 7594349;
SELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - [EMAIL]
select * from playbooks where team_id = 711; # event 226147
SELECT * FROM playbook_categories WHERE playbook_id = 5515;
SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';
SELECT * FROM crm_fields WHERE id = 226147;
SELECT * FROM crm_field_values WHERE crm_field_id = 226147;
SELECT * FROM crm_configurations WHERE id = 692;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 711 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;
select * from leads;
select * from calendars;
SELECT
t.id AS team_id,
t.name,
LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain
FROM teams t
JOIN users u ON u.team_id = t.id
JOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'
LEFT JOIN team_domains td
ON td.team_id = t.id
AND td.deleted_at IS NULL
AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))
GROUP BY t.id, t.name, calendar_domain
ORDER BY t.name, calendar_domain;
select * from users u join calendars c on c.user_id = u.id
where u.team_id = 882;
select * from activities where id = 74049485; # team 563 crm 537
select * from activities where id = 73272382; # team 563 crm 537
select * from activities where id = 64400389; # team 563 crm 537
select * from activities where id = 58081273; # team 563 crm 537
select * from activities where id = 54520297; # team 563 crm 537
select * from participants where activity_id = 58081273;
select * from activities where crm_configuration_id = 537 and provider = 'aircall'
and account_id = 19003658 order by updated_at desc;
select * from contacts where crm_configuration_id = 537 and id = 35957759;
select * from accounts where crm_configuration_id = 537 and id = 19003658;
select * from automated_report_results where id = 1976;
select * from automated_reports where id = 583;
select * from activity_searches where id = 87714;
select * from activity_search_filters where activity_search_id = 87714;
SELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid
or uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;
SELECT * FROM crm_configurations WHERE provider = 'hubspot';
select * from rate_limits;
select * from automated_report_results where media_type = 'pdf' and status = 2
and id IN (18, 1872);
select * from automated_reports where id = 54;
SELECT * FROM users WHERE id IN (24623,29443,29613);
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app, folder
.circleci, folder
.cursor, folder
.github
.sonarlint, folder
.vscode, folder
.windsurf, folder
app, sources root
Actions
InviteUserToTeamAction.php, class
MarkUserAsOnboardableAction.php, class
SyncRecordingFlagsAction.php, class
UpdateTeamMemberAction.php, class
UpdateUserRolesAction.php, class
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.034242023,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"3","depth":4,"bounds":{"left":0.37466756,"top":0.07581804,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.38464096,"top":0.07581804,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.39361703,"top":0.074221864,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.40093085,"top":0.074221864,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Actions;\n\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Support\\Str;\nuse Jiminny\\Component\\Acl\\RoleChangeContext;\nuse Jiminny\\Component\\Acl\\RoleChangeLogger;\nuse Jiminny\\Component\\Acl\\RoleChangeType;\nuse Jiminny\\Contracts\\Acl\\RoleRepositoryInterface;\nuse Jiminny\\DTO\\Invitation\\UserInvitationDTO;\nuse Jiminny\\Models\\Invitation;\nuse Jiminny\\Models\\Role;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Notifications\\Channels\\EmailNotifiable;\nuse Jiminny\\Notifications\\OwnerInvitedToTrial;\nuse Jiminny\\Notifications\\UserInvitedToTeam;\nuse Jiminny\\Notifications\\UserInvitedToTeamWithEmailOnly;\n\nclass InviteUserToTeamAction\n{\n public function __construct(\n private RoleRepositoryInterface $roleRepository,\n private RoleChangeLogger $roleChangeLogger,\n ) {\n }\n\n public function execute(UserInvitationDTO $dto): void\n {\n /** @var Invitation $invitation */\n $invitation = Invitation::updateOrCreate(\n [\n 'team_id' => $dto->teamId,\n 'email' => $dto->email,\n ],\n [\n 'group_id' => $dto->groupId,\n 'secondary_email' => $dto->secondaryEmail,\n 'crm_required' => $dto->crmRequired,\n 'token' => Str::random(40),\n 'is_owner' => $dto->isOwner,\n ]\n )->loadMissing(['team']);\n\n $invitation->roles()->sync($dto->roleIds);\n\n $notifiable = new EmailNotifiable($invitation->email, $invitation->getTeam());\n\n $logMessage = 'User invited to trial';\n\n if ($invitation->getTeam()->owner_id === null) {\n $notifiable->notifyNow(new OwnerInvitedToTrial($invitation));\n\n $logMessage = 'Owner invited to trial';\n } else {\n $notifiable->notifyNow(new UserInvitedToTeam($invitation));\n }\n\n collect($dto->roleIds)\n ->map(fn (int $roleId): Role => $this->roleRepository->get($roleId))\n ->each(function (Role $role) use ($dto, $invitation): void {\n $this->roleChangeLogger->log(\n $dto->currentUser,\n $invitation,\n $role,\n $invitation->wasRecentlyCreated\n ? RoleChangeType::INVITE_USER\n : RoleChangeType::RESEND_INVITATION,\n RoleChangeContext::APP,\n );\n });\n\n Log::info($logMessage, [\n 'teamId' => $invitation->team_id,\n 'teamName' => $invitation->getTeam()->name,\n 'email' => $invitation->email,\n 'crmRequired' => $invitation->crm_required ? 'yes' : 'no',\n ]);\n\n $invitation->touch();\n }\n\n public function executeWithEmailOnly(User $user): void\n {\n $notifiable = new EmailNotifiable($user->getEmailAddress(), $user->getTeam());\n\n $notifiable->notifyNow(new UserInvitedToTeamWithEmailOnly($user));\n }\n}","depth":4,"bounds":{"left":0.11968085,"top":0.0726257,"width":0.28823137,"height":0.9273743},"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Actions;\n\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Support\\Str;\nuse Jiminny\\Component\\Acl\\RoleChangeContext;\nuse Jiminny\\Component\\Acl\\RoleChangeLogger;\nuse Jiminny\\Component\\Acl\\RoleChangeType;\nuse Jiminny\\Contracts\\Acl\\RoleRepositoryInterface;\nuse Jiminny\\DTO\\Invitation\\UserInvitationDTO;\nuse Jiminny\\Models\\Invitation;\nuse Jiminny\\Models\\Role;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Notifications\\Channels\\EmailNotifiable;\nuse Jiminny\\Notifications\\OwnerInvitedToTrial;\nuse Jiminny\\Notifications\\UserInvitedToTeam;\nuse Jiminny\\Notifications\\UserInvitedToTeamWithEmailOnly;\n\nclass InviteUserToTeamAction\n{\n public function __construct(\n private RoleRepositoryInterface $roleRepository,\n private RoleChangeLogger $roleChangeLogger,\n ) {\n }\n\n public function execute(UserInvitationDTO $dto): void\n {\n /** @var Invitation $invitation */\n $invitation = Invitation::updateOrCreate(\n [\n 'team_id' => $dto->teamId,\n 'email' => $dto->email,\n ],\n [\n 'group_id' => $dto->groupId,\n 'secondary_email' => $dto->secondaryEmail,\n 'crm_required' => $dto->crmRequired,\n 'token' => Str::random(40),\n 'is_owner' => $dto->isOwner,\n ]\n )->loadMissing(['team']);\n\n $invitation->roles()->sync($dto->roleIds);\n\n $notifiable = new EmailNotifiable($invitation->email, $invitation->getTeam());\n\n $logMessage = 'User invited to trial';\n\n if ($invitation->getTeam()->owner_id === null) {\n $notifiable->notifyNow(new OwnerInvitedToTrial($invitation));\n\n $logMessage = 'Owner invited to trial';\n } else {\n $notifiable->notifyNow(new UserInvitedToTeam($invitation));\n }\n\n collect($dto->roleIds)\n ->map(fn (int $roleId): Role => $this->roleRepository->get($roleId))\n ->each(function (Role $role) use ($dto, $invitation): void {\n $this->roleChangeLogger->log(\n $dto->currentUser,\n $invitation,\n $role,\n $invitation->wasRecentlyCreated\n ? RoleChangeType::INVITE_USER\n : RoleChangeType::RESEND_INVITATION,\n RoleChangeContext::APP,\n );\n });\n\n Log::info($logMessage, [\n 'teamId' => $invitation->team_id,\n 'teamName' => $invitation->getTeam()->name,\n 'email' => $invitation->email,\n 'crmRequired' => $invitation->crm_required ? 'yes' : 'no',\n ]);\n\n $invitation->touch();\n }\n\n public function executeWithEmailOnly(User $user): void\n {\n $notifiable = new EmailNotifiable($user->getEmailAddress(), $user->getTeam());\n\n $notifiable->notifyNow(new UserInvitedToTeamWithEmailOnly($user));\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.40957448,"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.41821808,"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.42918882,"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.43783244,"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.44647607,"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.4574468,"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.46841756,"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.4950133,"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.50598407,"top":0.09896249,"width":0.029587766,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"bounds":{"left":0.7084442,"top":0.09896249,"width":0.02825798,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"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":"40","depth":4,"bounds":{"left":0.67785907,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.69015956,"top":0.123703115,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"40","depth":4,"bounds":{"left":0.6994681,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"64","depth":4,"bounds":{"left":0.7117686,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.7237367,"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.73105055,"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 * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","depth":4,"on_screen":true,"value":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","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,"bounds":{"left":0.020944148,"top":0.0,"width":0.045877658,"height":0.017557861},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".circleci, folder","depth":7,"bounds":{"left":0.027260639,"top":0.0,"width":0.023936171,"height":0.017557861},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".cursor, folder","depth":7,"bounds":{"left":0.027260639,"top":0.0,"width":0.022273935,"height":0.017557861},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"bounds":{"left":0.027260639,"top":0.0023942539,"width":0.022273935,"height":0.017557861},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint, folder","depth":7,"bounds":{"left":0.027260639,"top":0.019952115,"width":0.026928192,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".vscode, folder","depth":7,"bounds":{"left":0.027260639,"top":0.037509978,"width":0.024268618,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":".windsurf, folder","depth":7,"bounds":{"left":0.027260639,"top":0.055067837,"width":0.026928192,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"bounds":{"left":0.027260639,"top":0.0726257,"width":0.015957447,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"bounds":{"left":0.03357713,"top":0.090183556,"width":0.023603724,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"InviteUserToTeamAction.php, class","depth":9,"bounds":{"left":0.039893616,"top":0.10774142,"width":0.06781915,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"MarkUserAsOnboardableAction.php, class","depth":9,"bounds":{"left":0.039893616,"top":0.12529927,"width":0.08178192,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"SyncRecordingFlagsAction.php, class","depth":9,"bounds":{"left":0.039893616,"top":0.14285715,"width":0.07180851,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"UpdateTeamMemberAction.php, class","depth":9,"bounds":{"left":0.039893616,"top":0.16041501,"width":0.073803194,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"UpdateUserRolesAction.php, class","depth":9,"bounds":{"left":0.039893616,"top":0.17797287,"width":0.06582447,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"bounds":{"left":0.03357713,"top":0.19553073,"width":0.031914894,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"bounds":{"left":0.039893616,"top":0.21308859,"width":0.01462766,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems","depth":9,"bounds":{"left":0.039893616,"top":0.23064645,"width":0.032579787,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":9,"bounds":{"left":0.039893616,"top":0.2482043,"width":0.023603724,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"bounds":{"left":0.039893616,"top":0.26576218,"width":0.042220745,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch","depth":9,"bounds":{"left":0.039893616,"top":0.28332004,"width":0.037898935,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"bounds":{"left":0.039893616,"top":0.3008779,"width":0.037898935,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"bounds":{"left":0.039893616,"top":0.31843576,"width":0.03557181,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"bounds":{"left":0.039893616,"top":0.33599362,"width":0.03523936,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"bounds":{"left":0.039893616,"top":0.35355148,"width":0.033909574,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Dtos","depth":10,"bounds":{"left":0.046210106,"top":0.37110934,"width":0.01761968,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Events","depth":10,"bounds":{"left":0.046210106,"top":0.3886672,"width":0.021941489,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"bounds":{"left":0.046210106,"top":0.40622506,"width":0.0731383,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"bounds":{"left":0.046210106,"top":0.4237829,"width":0.04720745,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"bounds":{"left":0.039893616,"top":0.44134077,"width":0.03523936,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"bounds":{"left":0.039893616,"top":0.45889863,"width":0.017952127,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"bounds":{"left":0.039893616,"top":0.4764565,"width":0.046875,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"bounds":{"left":0.039893616,"top":0.49401435,"width":0.021276595,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"bounds":{"left":0.039893616,"top":0.51157224,"width":0.047539894,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Country","depth":9,"bounds":{"left":0.039893616,"top":0.5291301,"width":0.024601065,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi","depth":9,"bounds":{"left":0.039893616,"top":0.54668796,"width":0.034574468,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Database","depth":9,"bounds":{"left":0.039893616,"top":0.5642458,"width":0.027593086,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Datadog","depth":9,"bounds":{"left":0.039893616,"top":0.5818037,"width":0.025598405,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"DateTime","depth":9,"bounds":{"left":0.039893616,"top":0.59936154,"width":0.027925532,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":9,"bounds":{"left":0.039893616,"top":0.6169194,"width":0.03324468,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"bounds":{"left":0.039893616,"top":0.63447726,"width":0.027925532,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch","depth":9,"bounds":{"left":0.039893616,"top":0.6520351,"width":0.035904255,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent","depth":9,"bounds":{"left":0.039893616,"top":0.669593,"width":0.025930852,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Encoding","depth":9,"bounds":{"left":0.039893616,"top":0.68715084,"width":0.027260639,"height":0.017557861},"on_screen":true,"role_description":"text"}]...
|
2576053587826717010
|
1065678636275087173
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
3
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Actions;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Jiminny\Component\Acl\RoleChangeContext;
use Jiminny\Component\Acl\RoleChangeLogger;
use Jiminny\Component\Acl\RoleChangeType;
use Jiminny\Contracts\Acl\RoleRepositoryInterface;
use Jiminny\DTO\Invitation\UserInvitationDTO;
use Jiminny\Models\Invitation;
use Jiminny\Models\Role;
use Jiminny\Models\User;
use Jiminny\Notifications\Channels\EmailNotifiable;
use Jiminny\Notifications\OwnerInvitedToTrial;
use Jiminny\Notifications\UserInvitedToTeam;
use Jiminny\Notifications\UserInvitedToTeamWithEmailOnly;
class InviteUserToTeamAction
{
public function __construct(
private RoleRepositoryInterface $roleRepository,
private RoleChangeLogger $roleChangeLogger,
) {
}
public function execute(UserInvitationDTO $dto): void
{
/** @var Invitation $invitation */
$invitation = Invitation::updateOrCreate(
[
'team_id' => $dto->teamId,
'email' => $dto->email,
],
[
'group_id' => $dto->groupId,
'secondary_email' => $dto->secondaryEmail,
'crm_required' => $dto->crmRequired,
'token' => Str::random(40),
'is_owner' => $dto->isOwner,
]
)->loadMissing(['team']);
$invitation->roles()->sync($dto->roleIds);
$notifiable = new EmailNotifiable($invitation->email, $invitation->getTeam());
$logMessage = 'User invited to trial';
if ($invitation->getTeam()->owner_id === null) {
$notifiable->notifyNow(new OwnerInvitedToTrial($invitation));
$logMessage = 'Owner invited to trial';
} else {
$notifiable->notifyNow(new UserInvitedToTeam($invitation));
}
collect($dto->roleIds)
->map(fn (int $roleId): Role => $this->roleRepository->get($roleId))
->each(function (Role $role) use ($dto, $invitation): void {
$this->roleChangeLogger->log(
$dto->currentUser,
$invitation,
$role,
$invitation->wasRecentlyCreated
? RoleChangeType::INVITE_USER
: RoleChangeType::RESEND_INVITATION,
RoleChangeContext::APP,
);
});
Log::info($logMessage, [
'teamId' => $invitation->team_id,
'teamName' => $invitation->getTeam()->name,
'email' => $invitation->email,
'crmRequired' => $invitation->crm_required ? 'yes' : 'no',
]);
$invitation->touch();
}
public function executeWithEmailOnly(User $user): void
{
$notifiable = new EmailNotifiable($user->getEmailAddress(), $user->getTeam());
$notifiable->notifyNow(new UserInvitedToTeamWithEmailOnly($user));
}
}
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
40
1
40
64
Previous Highlighted Error
Next Highlighted Error
SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993
SELECT * FROM users WHERE id = 25061;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 994;
SELECT * FROM crm_profiles WHERE user_id = 25061;
select * from crm_configurations where id = 834;
SELECT * FROM teams WHERE id = 882;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;
SELECT * FROM contacts where crm_configuration_id = 834;
SELECT * FROM opportunities WHERE team_id = 933
# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');
AND id IN (8482561,18352941,19042734,19232139,19445140,19472541);
SELECT * FROM opportunity_contacts
WHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 485; #
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
select crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id
where crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')
# and l.converted_at IS NOT NULL
;
# [PASSWORD_DOTS]
SELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')
and opportunity_id IS NULL
order by id desc;
SELECT * FROM teams WHERE id = 604; # 598
SELECT * FROM activities WHERE id = 74410828; # [EMAIL]
SELECT * FROM accounts WHERE id = 20068382;
SELECT * FROM accounts WHERE id = 35186038;
SELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 559 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;
select * from sidekick_settings where team_id = 781;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100
SELECT * FROM crm_layouts WHERE crm_configuration_id = 711;
SELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL
and is_internal = 0 and status = 'completed'
order by id desc;
SELECT * FROM crm_layout_entities
WHERE crm_layout_id IN (2352, 2353);
;
SELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 556 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;
SELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;
select * from contacts
where crm_configuration_id = 530
and crm_provider_id = 872252;
select * from activities where crm_configuration_id = 530
and user_id = 14343 and type like '%softphone%'
and created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);
SELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t
JOIN crm_configurations c ON t.id = c.team_id
WHERE t.status = 'active';
SELECT * FROM teams where id = 1091;
SELECT * FROM crm_configurations where team_id = 1091;
SELECT * FROM activity_providers where team_id = 1091;
SELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT * FROM teams WHERE name LIKE '%Leadventure%';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1091 and sa.provider = 'salesforce';
SELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812
SELECT * FROM teams where id = 862;
SELECT * FROM crm_configurations where team_id = 862;
SELECT * FROM activity_providers where team_id = 862;
SELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT t.id, crm.id, crm.provider, ap.* FROM teams t
join crm_configurations crm on t.id = crm.team_id
join activity_providers ap on t.id = ap.team_id
where t.status = 'active' and ap.is_enabled = 1
and crm.provider = 'hubspot'
and ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',
'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');
SELECT * FROM teams where id = 1068;
SELECT * FROM crm_configurations where team_id = 1068;
SELECT * FROM activity_providers where team_id = 1068;
SELECT * FROM activities a
where crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')
and a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'
)
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by a.id desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1068 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262
SELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
select * from crm_layouts where crm_configuration_id = 834;
select * from crm_layout_entities where crm_layout_id = 2780;
select * from crm_fields where id IN (321153,321192,321193,321194);
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1057 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8
SELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20
SELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10
SELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #
SELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;
select * from users where team_id = 51; # 7783
SELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130
select * from activity_searches where user_id = 7783;
select * from activity_search_filters where activity_search_id IN (32291, 32292);
SELECT asf.activity_search_id, asf.id, asf.value
FROM activity_search_filters asf
WHERE asf.filter = 'group_id'
AND asf.value IN (
SELECT CONCAT(
HEX(SUBSTR(uuid, 5, 4)), '-',
HEX(SUBSTR(uuid, 3, 2)), '-',
HEX(SUBSTR(uuid, 1, 2)), '-',
HEX(SUBSTR(uuid, 9, 2)), '-',
HEX(SUBSTR(uuid, 11))
)
FROM groups
WHERE deleted_at IS NOT NULL
);
SELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where provider = 'hubspot';
SELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133
SELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null
# [PASSWORD_DOTS]
select * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';
select
cp.*
# DISTINCT t.id
# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields
FROM crm_profiles cp
JOIN crm_configurations crm on crm.id = cp.crm_configuration_id
JOIN users u on u.id = cp.user_id
JOIN teams t ON t.id = crm.team_id
WHERE crm.provider = 'salesforce' and t.status = 'active'
and cp.archived_at IS NULL and u.deleted_at IS NULL
and t.id NOT IN (1093)
and t.id = 2
and cp.contact_fields IS NULL;
# and c.crm_provider_id = '003Uu00000ojD4NIAU';
SELECT * FROM users WHERE id = 26484;
SELECT * FROM crm_profiles WHERE user_id = 26484;
SELECT * FROM social_accounts WHERE sociable_id = 26484;
SELECT * FROM crm_configurations where provider = 'salesforce';
select * from users where id IN (10022, 10403);
select * from users where team_id IN (526);
select * from teams where id IN (526, 532);
select * from crm_configurations where id IN (500, 516);
select * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);
select * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 526 and sa.provider = 'salesforce';
select * from team_settings where team_id IN (526, 532);
select * from users where id IN (22824);
select * from crm_profiles where crm_configuration_id IN (1026);
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1093 and sa.provider = 'salesforce';
select * from teams where id = 1099;
select * from users where id = 29643
select * from activity_processing_states;
SELECT * FROM teams where name LIKE '%Fare%'; # 233
SELECT * FROM opportunities where crm_configuration_id = 215
# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'
;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1088 and sa.provider = 'hubspot';
SELECT * FROM teams order by updated_at DESC
SELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account
select * from crm_configurations where provider = 'pipedrive';
select * from teams where id = 957;
select * from crm_configurations where id = 957;
SELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743
SELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;
select * from users where team_id = 1; # 26726 - Gabriela Dureva
SELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific
select * from activities where user_id = 26726 order by id desc;
select * from contacts where crm_configuration_id = 1
and email IN ('[EMAIL]', '[EMAIL]'); # 2094416, 2093620
SELECT * FROM contacts WHERE id = 6284931;
SELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id
WHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;
select * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);
select * from crm_configurations where id = 1;
43801692-1aeb-32ce-acba-5b80a479701a
44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b
405975c0-b3d0-7aaa-821f-09d59cae6dd1
4caf848d-4bed-2299-b248-7788d41f9fca
49bedc3f-f196-eef3-89c3-dea6a3b4aa63
43420989-a09d-b8f8-9806-c8bbf7a02aac
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
SELECT * FROM activities WHERE id = 75461988;
SELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;
select * from contacts where id = 17900517;
select * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id
where crm.provider != 'salesforce';
select * from users where id = 21047;
SELECT * FROM crm_configurations WHERE id = 892;
SELECT * FROM teams WHERE id = 942;
select * from opportunities where team_id = 942 order by updated_at desc;
select * from contacts where team_id = 942 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 942 and sa.provider = 'hubspot';
SELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430
SELECT * FROM crm_configurations WHERE id = 1;
SELECT * FROM teams WHERE crm_id = 1;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
select id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1
SELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430
select * from teams where id = 852;
select * from groups where id = 2286;
select * from sidekick_settings where team_id = 852;
select * from default_activity_types where team_id = 852;
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1 AND u.deleted_at IS NULL
AND u.crm_required = 1
AND u.team_id = 1
ORDER BY u.team_id;
SELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (
18481
);
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1
AND u.deleted_at IS NULL
AND u.crm_required = 1
# AND u.team_id = 1
AND p.id IS NULL -- Move this condition to WHERE clause
ORDER BY u.team_id;
SELECT * FROM opportunities WHERE id = 20002609;
select * from teams where id = 1122; # Velatir, 29953 - [EMAIL]
select * from crm_configurations where id = 1060;
select * from crm_layouts where crm_configuration_id = 1060;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1122 and sa.provider = 'hubspot';
select * from opportunities where team_id = 1122 order by updated_at desc;
select * from crm_field_data where object_type = 'contact';
SELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 248 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS
SELECT * FROM users where id = 24115;
SELECT * FROM accounts where id = 4002896;
SELECT * FROM teams WHERE name LIKE '%adswerve%';
SELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN ("0069N000003GIQ9QAO","0061r000019yGP9AAM","0066900001S2KWlAAN","0066900001TDpj2AAD","0066900001b8uEwAAI","0069N000001rQi0QAE","006QF00000KD40mYAD","006QF00000LzpRJYAZ","0069N000002uomtQAA","0069N000002xlMLQAY","0066900001NV6ubAAD","0061r00001HJp45AAD","006QF00000uTlUoYAK","006QF00000v0bZqYAI");
SELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203
SELECT u.id, u.email, ac.name, a.* FROM activities a
JOIN users u ON a.user_id = u.id
JOIN accounts ac ON a.account_id = ac.id
WHERE
uuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or
uuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or
uuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;
select * from users where id = 5825;
SELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;
select * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;
19594, 862
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 862 and sa.provider = 'salesforce';
select * from automated_reports where id = 36;
select ar.frequency, r.*, ar.* from automated_report_results r
join automated_reports ar on r.report_id = ar.id
where ar.frequency != 'one_off';
select s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;
select * from nudges n where n.activity_search_id
select * from teams where created_at > '2026-03-09';
SELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;
select * from users where team_id = 1 and name like '%Lukas%'; # 7160
SELECT * FROM teams WHERE id = 575;
select * from opportunities where team_id = 575;
SELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,
select * from opportunities where team_id = 1126;
SELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,
select * from opportunities where team_id = 1125;
select * from contacts c
where c.team_id = 882;
SELECT * FROM activities WHERE id = 76822967;
SELECT * FROM crm_profiles WHERE user_id = 15440;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 555;
SELECT * FROM crm_configurations WHERE id = 555;
SELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 581 and sa.provider = 'salesforce';
SELECT * FROM automated_report_results order by id desc;
select * from features;
select * from team_features where feature_id = 40;
select * from teams where id = 556;
select * from automated_reports;
where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , ["pdf","podcast"]
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
select * from automated_report_results order by id desc;
SELECT * FROM automated_report_results WHERE id = 1919;
select * from automated_report_results WHERE report_id = 54;
select * from opportunities where id = 7594349;
SELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - [EMAIL]
select * from playbooks where team_id = 711; # event 226147
SELECT * FROM playbook_categories WHERE playbook_id = 5515;
SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';
SELECT * FROM crm_fields WHERE id = 226147;
SELECT * FROM crm_field_values WHERE crm_field_id = 226147;
SELECT * FROM crm_configurations WHERE id = 692;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 711 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;
select * from leads;
select * from calendars;
SELECT
t.id AS team_id,
t.name,
LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain
FROM teams t
JOIN users u ON u.team_id = t.id
JOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'
LEFT JOIN team_domains td
ON td.team_id = t.id
AND td.deleted_at IS NULL
AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))
GROUP BY t.id, t.name, calendar_domain
ORDER BY t.name, calendar_domain;
select * from users u join calendars c on c.user_id = u.id
where u.team_id = 882;
select * from activities where id = 74049485; # team 563 crm 537
select * from activities where id = 73272382; # team 563 crm 537
select * from activities where id = 64400389; # team 563 crm 537
select * from activities where id = 58081273; # team 563 crm 537
select * from activities where id = 54520297; # team 563 crm 537
select * from participants where activity_id = 58081273;
select * from activities where crm_configuration_id = 537 and provider = 'aircall'
and account_id = 19003658 order by updated_at desc;
select * from contacts where crm_configuration_id = 537 and id = 35957759;
select * from accounts where crm_configuration_id = 537 and id = 19003658;
select * from automated_report_results where id = 1976;
select * from automated_reports where id = 583;
select * from activity_searches where id = 87714;
select * from activity_search_filters where activity_search_id = 87714;
SELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid
or uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;
SELECT * FROM crm_configurations WHERE provider = 'hubspot';
select * from rate_limits;
select * from automated_report_results where media_type = 'pdf' and status = 2
and id IN (18, 1872);
select * from automated_reports where id = 54;
SELECT * FROM users WHERE id IN (24623,29443,29613);
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app, folder
.circleci, folder
.cursor, folder
.github
.sonarlint, folder
.vscode, folder
.windsurf, folder
app, sources root
Actions
InviteUserToTeamAction.php, class
MarkUserAsOnboardableAction.php, class
SyncRecordingFlagsAction.php, class
UpdateTeamMemberAction.php, class
UpdateUserRolesAction.php, class
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
32902
|
1256
|
18
|
2026-05-13T09:44:58.463903+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665498463_m1.jpg...
|
PhpStorm
|
faVsco.js – InviteUserToTeamAction.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-943456739835505562
|
-8636494053633454656
|
click
|
hybrid
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
SlackFile Edit ViewGoHistoryWindowHelpAPPDOCKER₴81DEV (docker)₴82APP (-zshtests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleterTest.phptests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesProviderTest.phptests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesUploaderTest.phptests/Unit/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeeches?tests/Unit/Component/Transcription/Diarization/Source/MeetingBotSourceTest.phptests/Unit/Contracts/Services/Calendar/CalendarTraitTest.phptests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.phptests/Unit/Jobs/Activity/Import/ImportTwilioVideoSpeechesJobTest.phptests/Unit/Jobs/Activity/Import/IsActivityReadyForProcessingJobTest.phptests/Unit/Jobs/Calendar/SetupCalendarSyncTest.phptests/Unit/Services/Activity/ParticipantsServiceTest.phptests/Unit/Services/Calendar/Command/ImportParticipantsTest.phptests/Unit/Services/Calendar/GoogleCalendarServiceTest.phptests/Unit/Services/Crm/Close/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTest.phptests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTraitMatchActivitiesTest.phytests/Unit/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTraitOpportunitiesTe:tests/Unit/Services/Crm/Pipedrive/ImportOpportunityMatchActivitiesTest.phptests/Unit/Services/Crm/Salesforce/ServiceTest.phptests/Unit/Services/Mail/0ffice/EmailApiClientTest.phptests/Unit/Services/RecallAI/RecallAIServiceTest.php113 files changed, 4143 insertions(+), 1740 deletions(-)create mode 120000 CLAUDE.mdcreate mode 100644 app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.phpdelete mode 100644 app/Component/ES/ElasticSearchWorkerManager.phpdelete mode 100644 app/Component/ES/Worker/ActivityWorker.phpdelete mode 100644 app/Component/ES/Worker/EntityWorker.phpdelete mode100644 app/Component/ES/Worker/WorkerAmount.phpdelete mode100644 app/Component/ES/Worker/WorkerInterface.phpcreate mode100644 app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.phtcreate mode100644 app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/Assembl:create mode100644 app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNot(create mode 100644 app/Console/Commands/Crm/Backfill0pportunityUserFromAccountCommand.phpdelete mode 100644 app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.phpcreate mode100644 front-end/src/components/shared/modals/EntityPickerModal/__tests__/us‹create mode 100644 tests/Feature/Component/Nudge/Process0rganisationImmediateNudgesJobTe:create mode 100644 tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheck‹delete mode 100644 tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/ActivityWorkerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/EntityWorkerTest.phpdelete mode 100644 tests/Unit/Component/ES/Worker/WorkerAmountTest.phpcreate mode 100644 tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCr‹create mode 100644 tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.phpLukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ I|HomeDMsActivityFilesLaterMore(aol§ Support Daily - in 2h 16 m100% <78•Wed 13 May12:44:58ED-→Describe what you are looking forJiminny ...Nikolay Ivanov6 0curoaroylau# engineering# general# jiminny-bg# platform-tickets# product_launches#random# releases# sofia-office# support# thank-yous# the_people_of_jimi...MessagesAdd canvas@ Files+Lukas Kovalik 11.Today ~мен все ме праща наhttps://app.vanta.com/c/jiminny.com/employee/onboardingNikolay Ivanov 11:01 AMХм, Джейс дали не може да ти помогне?Lukas Kovalik 11:01 AMще питам James, предполагам че нямам правада мерсиNikolay Ivanov 11:01 AMмда° Direct messages& Nikolay Ivanovdo James Graham. Stoyan Tanev. Galya Dimitrova. Steliyan Georgievo Petko Kashinski®. Aneliya Angelovaã. Stefka Stoyanova•. Vasil Vasilev •!Lukas Kovalik y...МОЛЯLukas Kovalik 12:13 PMНики сори, още един въпрос имамкогато ги правеше ти FE ли оправяима vulnerabilities no npmNikolay Ivanov 12:28 PMнетях ги оставямLukas Kovalik 12:29 PMаз погледнах твоя тикет и там друго нямашесамо FEкак стигна до Workerl:: AppsJira CloudMessage Nikolay IvanovToast...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
32903
|
1257
|
15
|
2026-05-13T09:44:58.477887+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665498477_m2.jpg...
|
PhpStorm
|
faVsco.js – InviteUserToTeamAction.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.034242023,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-943456739835505562
|
-8636494053633454656
|
click
|
hybrid
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
PhostormVIeWINavigarecodeLaravelKeractorWindowFV faVsco.js°9 master ~ProjectC) CreateTeam.onp© InviteUserToTeamAction.php >vDappv D Actionsc Inviteuserlol eamactionncmiiclotie rsuisaninleeeelnetС мaгkuserasOnboardable.© SyncRecordingFlagsActio© UpdateTeamMemberActi 19© UpdateUserRolesAction.p 20v _ componentC7 AclActionitemsW ActivityActivitvAnalvticsActivitySearchAlActivitv ivoeIM A AutomationM AiCal|ScorinaAskAnything>M DtosM svents(c) AckAnvthinaPromntSe 34© HistoryService.phpD AskJiminnyAiD AWSD BillingManagementD Cache_ coachingreedbackD CountryC CustomerAp®0) Database_ Datadoo0 DateTimeDealinsiahtsDealRiskSElasticSearchEloquentD Encodinga EncrvotionMESFaken/ FeatureFlaasM SsMnedM silleSvstemM GeckoD GongD GuzzleHttpN KevPoints|iM KiockMlanaunaoNotontionMlivoSoodMlockeM Mothpubuic tunccion-_constructprivace kolekeposicoryincertace srolekeposicory.private koLechangelogger srorechangerogger,{...}oubuc tuncrion execure userinvirarionulu soro: vo1oi** ovar Invitation Sinvitation *Sinvitation = Invitation::update0rCreate('team_1d" => $dto->teamid,emanl => sdto->emanu'aroun id' = Sdto->arountd.'secondary emarl' => Sdto->secondarveman.erm reauired' => Sdto->crmRequirediItoken! => Stn. •randomd lenath: 40).1is ownent => Sdto->ichwnen-loadMiccina("'team'l)•Sinvitation->roles->sync($dto->roleIds):Snotifiable = new EmailNotifiable(Sinvitation->email, Sinvitation->getTeamO):lSLoonessace = "user 1nviced co crial'.if (Sinvitation->qetTeam->owner_ id === null) {Snotifiable->notifyNowCnew OwnerInvitedToTrial(Sinvitation)):SloqMessage = 'Owner invited to trial':—eLse <Snot1r1able->not1fvvownew Userinvitedioleamsinvitatlon.:collect(Sdto->roleids)->man(fn Gint Sroleid): Role => Sthis->roleRenository->aet(Sroletd))->eachfunction Role Srole) use Sdto. Sinvitation: void «...):lnn. •into SioaMeccaap."toantdi => Cinvitation->teamid.lItpamlamel => Sinvitation->aetTeamo->name.A3V1A|aravel.l0gA SF (jiminny@localhost]4 HS_local [jiminny@localhost]& console (PROD] X A console [EU]A console [STAGING] S616Tx: AutovSo jiminnyCONCAT(u.id, CASE WHEN U.id = t.owner_id THEN ' (owner)' ELSE'' END) AS user_id,040 A1 A40 V 64 ^sa.*t.owner_id FROM social_accounts saNolN usens u on u.id e sa.sociablle i.diJOIN teams t .n<->l: on t.id = u.team_icWHERE u.team_id = 581 and sa.provider = 'salesforce';SELECT * FROM automated_report_results order by id desc;select * from features;select * from team_features where feature_id = 40;select * from teams where id = 556:select * from automated_reports:where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044["pdf" "podcast"]SELECT * FROM automated report_ results WHERE uuid to bin( '822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid:select * from automated_report_results order by za desc;SELECT * FROM automated report resultsWHERE id = 1919select * from automated report results WHERE report id = 54:select * from opportunities where 1d = 75943494SELE * FROM teamsWHERE name LIKE '%Les%': # 711, 692. 16067 -Timinnvintearationdlesmills.comselect * from playbooks where team id = 711; # event 226147SELEd * FROM Davbook catedonies WHERE Dlavbook 10 e 55151SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type =SELECT * EROM eom fields WHERE 1d = 226147-1SELECT * EROM eom field values WHERE com field 1d = 226147.SELECT * FROM crm_configurations WHERE id = 692;SEISCTCONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '• END) AS user_id,nemailSa.xt.owner id FROM social accounts saJOIN users u on u.id = sa.sociable idJOIN teams t 1..n<->1: on t.id = u.team_idWHERE U.team id = 711 and sa.provider = 'salesforce':SELECT * FROM crm profiles co JOIN users u 1..n<->1: on u.id = co.user id WHERE u.team_id = 711:select * from leads:select * from calendars:SELECTS0 hl• suppont Dally • In Zn 10m100% L2• Wed 13 May 12:44:58AskJiminnyReportActivityServiceTest-CascadeTrial Owner Role SelecThouaht for 3s >6 / 7 tasks done• Review current role assianment when owner sians in(7 Document findinas and provide imolementation olanTnoughttor 4s7 7 tasks done)I nought for 4SCurrent Flow Analvsis: Owner Role Assianment in Trial CreationBackend Flow1. Team Creation Entry Point• TeamController::store() (lines 24-45)Calls GreateTeam interaction to create the team•Colle TnvitellcerToTeamAct ion with UserInvitationDT0:: for0wner Srequest, Steam)2. app/DTO/Invitation/UserInvitationDTO.ohpD• UserInvitationDT0:: for0wner() (lines 52-72 in /app/DT0/Invitation/UserInvitationDT0.oho)•Lines 54-57: This is where the owner's role is hardcodediohrSrolelds = Role::whereln"name',User::ROLE RECORDER,→>oluck("id'→>toArravo:• Awavs assians ROIF ADMIN + ROLF RECORDER to the ownen• This is the key location that needs modificationS. Invitation Creation•InviteUserToTeamAction: :execute@ (Uines 28-81)+0 ..• Creates an Invitation with roles from the DTO (line 45: Sinvitation->roles()->sync(Sdto->roleIds))• Sends OwnerInvitedToTrial notificationl1. Owner Sian-in Flow•Owner receives email invitation• RegisterController::showRegistrationForm• shows reaistration form with invitation dataOwner redisters and accents invitation•Roles are already assigned via the invitation, so owner gets ROLE ADMIN + ROLE RECORDER automaticallyFrontend Flow1. EditTeamModal.vue (/front-end/src/comnonentc/Settinas/Kiock/modals/FditTeamModal/FditTearModal.vne)Ask anvthina (884-L)SWE-16O0 1WN Windsurf Teams29-58io 4 spaces...
|
32901
|
NULL
|
NULL
|
NULL
|
|
32904
|
1256
|
19
|
2026-05-13T09:45:05.330906+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665505330_m1.jpg...
|
PhpStorm
|
faVsco.js – UserInvitationDTO.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
4
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\DTO\Invitation;
use Jiminny\DTO\UserEmail;
use Jiminny\Http\Requests\Settings\Teams\CreateInvitationRequest;
use Jiminny\Http\Requests\Settings\Teams\CreateTeamRequest;
use Jiminny\Http\Requests\Settings\Teams\EditTeamRequest;
use Jiminny\Models\Group;
use Jiminny\Models\Invitation;
use Jiminny\Models\Role;
use Jiminny\Models\Team;
use Jiminny\Models\User;
class UserInvitationDTO
{
use UserEmail;
public string $email;
public ?string $secondaryEmail;
public ?int $groupId;
public int $teamId;
public bool $crmRequired;
public array $roleIds;
public bool $isOwner;
public ?User $currentUser = null;
/**
* @param array{
* email: string,
* secondaryEmail: string|null,
* groupId: int|null,
* teamId: int|string,
* crmRequired: bool,
* roleIds: int[],
* isOwner: bool,
* user?: User
* } $attributes
*/
private function __construct(array $attributes)
{
$this->email = mb_strtolower($attributes['email']);
$this->secondaryEmail = $this->normalizeNullable($attributes['secondaryEmail']);
$this->groupId = $attributes['groupId'];
$this->teamId = (int) $attributes['teamId'];
$this->crmRequired = (bool) $attributes['crmRequired'];
$this->roleIds = $attributes['roleIds'];
$this->isOwner = $attributes['isOwner'];
$this->currentUser = $attributes['user'] ?? null;
}
public static function forOwner(CreateTeamRequest|EditTeamRequest $request, Team $team): self
{
$roleIds = Role::whereIn('name', [
User::ROLE_ADMIN,
User::ROLE_RECORDER,
])->pluck('id')->toArray();
/** @var User $currentUser */
$currentUser = $request->user();
return new self([
'email' => $request->getOwnerEmail(),
'secondaryEmail' => null,
'groupId' => null,
'teamId' => $team->getId(),
'crmRequired' => true,
'roleIds' => $roleIds,
'user' => $currentUser,
'isOwner' => true,
]);
}
public static function fromRequest(CreateInvitationRequest $request): self
{
$data = $request->validated();
$groupId = isset($data['group_id']) ? Group::uuid($request->input('group_id'))->getId() : null;
$teamId = Team::uuid($data['team_id'])->getId();
/** @var User $currentUser */
$currentUser = $request->user();
return new self([
'email' => mb_strtolower($data['email']),
'secondaryEmail' => $data['secondary_email'] ?? null,
'groupId' => $groupId,
'teamId' => $teamId,
'crmRequired' => $data['crm_required'],
'roleIds' => $data['roles'],
'user' => $currentUser,
'isOwner' => false,
]);
}
public static function fromInvitation(Invitation $invitation, User $currentUser): self
{
$roles = $invitation->roles()->get();
$isOwner = $invitation->isOwner();
return new self([
'email' => $invitation->email,
'secondaryEmail' => $invitation->getSecondaryEmail(),
'groupId' => $invitation->group_id,
'teamId' => $invitation->team_id,
'crmRequired' => $invitation->crm_required,
'roleIds' => $roles->pluck('id')->toArray(),
'user' => $currentUser,
'isOwner' => $isOwner,
]);
}
}
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
40
1
40
64
Previous Highlighted Error
Next Highlighted Error
SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993
SELECT * FROM users WHERE id = 25061;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 994;
SELECT * FROM crm_profiles WHERE user_id = 25061;
select * from crm_configurations where id = 834;
SELECT * FROM teams WHERE id = 882;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;
SELECT * FROM contacts where crm_configuration_id = 834;
SELECT * FROM opportunities WHERE team_id = 933
# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');
AND id IN (8482561,18352941,19042734,19232139,19445140,19472541);
SELECT * FROM opportunity_contacts
WHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 485; #
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
select crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id
where crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')
# and l.converted_at IS NOT NULL
;
# [PASSWORD_DOTS]
SELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')
and opportunity_id IS NULL
order by id desc;
SELECT * FROM teams WHERE id = 604; # 598
SELECT * FROM activities WHERE id = 74410828; # [EMAIL]
SELECT * FROM accounts WHERE id = 20068382;
SELECT * FROM accounts WHERE id = 35186038;
SELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 559 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;
select * from sidekick_settings where team_id = 781;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100
SELECT * FROM crm_layouts WHERE crm_configuration_id = 711;
SELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL
and is_internal = 0 and status = 'completed'
order by id desc;
SELECT * FROM crm_layout_entities
WHERE crm_layout_id IN (2352, 2353);
;
SELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 556 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;
SELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;
select * from contacts
where crm_configuration_id = 530
and crm_provider_id = 872252;
select * from activities where crm_configuration_id = 530
and user_id = 14343 and type like '%softphone%'
and created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);
SELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t
JOIN crm_configurations c ON t.id = c.team_id
WHERE t.status = 'active';
SELECT * FROM teams where id = 1091;
SELECT * FROM crm_configurations where team_id = 1091;
SELECT * FROM activity_providers where team_id = 1091;
SELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT * FROM teams WHERE name LIKE '%Leadventure%';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1091 and sa.provider = 'salesforce';
SELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812
SELECT * FROM teams where id = 862;
SELECT * FROM crm_configurations where team_id = 862;
SELECT * FROM activity_providers where team_id = 862;
SELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT t.id, crm.id, crm.provider, ap.* FROM teams t
join crm_configurations crm on t.id = crm.team_id
join activity_providers ap on t.id = ap.team_id
where t.status = 'active' and ap.is_enabled = 1
and crm.provider = 'hubspot'
and ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',
'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');
SELECT * FROM teams where id = 1068;
SELECT * FROM crm_configurations where team_id = 1068;
SELECT * FROM activity_providers where team_id = 1068;
SELECT * FROM activities a
where crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')
and a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'
)
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by a.id desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1068 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262
SELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
select * from crm_layouts where crm_configuration_id = 834;
select * from crm_layout_entities where crm_layout_id = 2780;
select * from crm_fields where id IN (321153,321192,321193,321194);
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1057 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8
SELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20
SELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10
SELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #
SELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;
select * from users where team_id = 51; # 7783
SELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130
select * from activity_searches where user_id = 7783;
select * from activity_search_filters where activity_search_id IN (32291, 32292);
SELECT asf.activity_search_id, asf.id, asf.value
FROM activity_search_filters asf
WHERE asf.filter = 'group_id'
AND asf.value IN (
SELECT CONCAT(
HEX(SUBSTR(uuid, 5, 4)), '-',
HEX(SUBSTR(uuid, 3, 2)), '-',
HEX(SUBSTR(uuid, 1, 2)), '-',
HEX(SUBSTR(uuid, 9, 2)), '-',
HEX(SUBSTR(uuid, 11))
)
FROM groups
WHERE deleted_at IS NOT NULL
);
SELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where provider = 'hubspot';
SELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133
SELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null
# [PASSWORD_DOTS]
select * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';
select
cp.*
# DISTINCT t.id
# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields
FROM crm_profiles cp
JOIN crm_configurations crm on crm.id = cp.crm_configuration_id
JOIN users u on u.id = cp.user_id
JOIN teams t ON t.id = crm.team_id
WHERE crm.provider = 'salesforce' and t.status = 'active'
and cp.archived_at IS NULL and u.deleted_at IS NULL
and t.id NOT IN (1093)
and t.id = 2
and cp.contact_fields IS NULL;
# and c.crm_provider_id = '003Uu00000ojD4NIAU';
SELECT * FROM users WHERE id = 26484;
SELECT * FROM crm_profiles WHERE user_id = 26484;
SELECT * FROM social_accounts WHERE sociable_id = 26484;
SELECT * FROM crm_configurations where provider = 'salesforce';
select * from users where id IN (10022, 10403);
select * from users where team_id IN (526);
select * from teams where id IN (526, 532);
select * from crm_configurations where id IN (500, 516);
select * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);
select * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 526 and sa.provider = 'salesforce';
select * from team_settings where team_id IN (526, 532);
select * from users where id IN (22824);
select * from crm_profiles where crm_configuration_id IN (1026);
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1093 and sa.provider = 'salesforce';
select * from teams where id = 1099;
select * from users where id = 29643
select * from activity_processing_states;
SELECT * FROM teams where name LIKE '%Fare%'; # 233
SELECT * FROM opportunities where crm_configuration_id = 215
# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'
;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1088 and sa.provider = 'hubspot';
SELECT * FROM teams order by updated_at DESC
SELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account
select * from crm_configurations where provider = 'pipedrive';
select * from teams where id = 957;
select * from crm_configurations where id = 957;
SELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743
SELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;
select * from users where team_id = 1; # 26726 - Gabriela Dureva
SELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific
select * from activities where user_id = 26726 order by id desc;
select * from contacts where crm_configuration_id = 1
and email IN ('[EMAIL]', '[EMAIL]'); # 2094416, 2093620
SELECT * FROM contacts WHERE id = 6284931;
SELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id
WHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;
select * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);
select * from crm_configurations where id = 1;
43801692-1aeb-32ce-acba-5b80a479701a
44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b
405975c0-b3d0-7aaa-821f-09d59cae6dd1
4caf848d-4bed-2299-b248-7788d41f9fca
49bedc3f-f196-eef3-89c3-dea6a3b4aa63
43420989-a09d-b8f8-9806-c8bbf7a02aac
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
SELECT * FROM activities WHERE id = 75461988;
SELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;
select * from contacts where id = 17900517;
select * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id
where crm.provider != 'salesforce';
select * from users where id = 21047;
SELECT * FROM crm_configurations WHERE id = 892;
SELECT * FROM teams WHERE id = 942;
select * from opportunities where team_id = 942 order by updated_at desc;
select * from contacts where team_id = 942 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 942 and sa.provider = 'hubspot';
SELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430
SELECT * FROM crm_configurations WHERE id = 1;
SELECT * FROM teams WHERE crm_id = 1;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
select id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1
SELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430
select * from teams where id = 852;
select * from groups where id = 2286;
select * from sidekick_settings where team_id = 852;
select * from default_activity_types where team_id = 852;
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1 AND u.deleted_at IS NULL
AND u.crm_required = 1
AND u.team_id = 1
ORDER BY u.team_id;
SELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (
18481
);
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1
AND u.deleted_at IS NULL
AND u.crm_required = 1
# AND u.team_id = 1
AND p.id IS NULL -- Move this condition to WHERE clause
ORDER BY u.team_id;
SELECT * FROM opportunities WHERE id = 20002609;
select * from teams where id = 1122; # Velatir, 29953 - [EMAIL]
select * from crm_configurations where id = 1060;
select * from crm_layouts where crm_configuration_id = 1060;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1122 and sa.provider = 'hubspot';
select * from opportunities where team_id = 1122 order by updated_at desc;
select * from crm_field_data where object_type = 'contact';
SELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 248 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS
SELECT * FROM users where id = 24115;
SELECT * FROM accounts where id = 4002896;
SELECT * FROM teams WHERE name LIKE '%adswerve%';
SELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN ("0069N000003GIQ9QAO","0061r000019yGP9AAM","0066900001S2KWlAAN","0066900001TDpj2AAD","0066900001b8uEwAAI","0069N000001rQi0QAE","006QF00000KD40mYAD","006QF00000LzpRJYAZ","0069N000002uomtQAA","0069N000002xlMLQAY","0066900001NV6ubAAD","0061r00001HJp45AAD","006QF00000uTlUoYAK","006QF00000v0bZqYAI");
SELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203
SELECT u.id, u.email, ac.name, a.* FROM activities a
JOIN users u ON a.user_id = u.id
JOIN accounts ac ON a.account_id = ac.id
WHERE
uuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or
uuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or
uuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;
select * from users where id = 5825;
SELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;
select * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;
19594, 862
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 862 and sa.provider = 'salesforce';
select * from automated_reports where id = 36;
select ar.frequency, r.*, ar.* from automated_report_results r
join automated_reports ar on r.report_id = ar.id
where ar.frequency != 'one_off';
select s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;
select * from nudges n where n.activity_search_id
select * from teams where created_at > '2026-03-09';
SELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;
select * from users where team_id = 1 and name like '%Lukas%'; # 7160
SELECT * FROM teams WHERE id = 575;
select * from opportunities where team_id = 575;
SELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,
select * from opportunities where team_id = 1126;
SELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,
select * from opportunities where team_id = 1125;
select * from contacts c
where c.team_id = 882;
SELECT * FROM activities WHERE id = 76822967;
SELECT * FROM crm_profiles WHERE user_id = 15440;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 555;
SELECT * FROM crm_configurations WHERE id = 555;
SELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 581 and sa.provider = 'salesforce';
SELECT * FROM automated_report_results order by id desc;
select * from features;
select * from team_features where feature_id = 40;
select * from teams where id = 556;
select * from automated_reports;
where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , ["pdf","podcast"]
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
select * from automated_report_results order by id desc;
SELECT * FROM automated_report_results WHERE id = 1919;
select * from automated_report_results WHERE report_id = 54;
select * from opportunities where id = 7594349;
SELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - [EMAIL]
select * from playbooks where team_id = 711; # event 226147
SELECT * FROM playbook_categories WHERE playbook_id = 5515;
SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';
SELECT * FROM crm_fields WHERE id = 226147;
SELECT * FROM crm_field_values WHERE crm_field_id = 226147;
SELECT * FROM crm_configurations WHERE id = 692;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 711 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;
select * from leads;
select * from calendars;
SELECT
t.id AS team_id,
t.name,
LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain
FROM teams t
JOIN users u ON u.team_id = t.id
JOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'
LEFT JOIN team_domains td
ON td.team_id = t.id
AND td.deleted_at IS NULL
AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))
GROUP BY t.id, t.name, calendar_domain
ORDER BY t.name, calendar_domain;
select * from users u join calendars c on c.user_id = u.id
where u.team_id = 882;
select * from activities where id = 74049485; # team 563 crm 537
select * from activities where id = 73272382; # team 563 crm 537
select * from activities where id = 64400389; # team 563 crm 537
select * from activities where id = 58081273; # team 563 crm 537
select * from activities where id = 54520297; # team 563 crm 537
select * from participants where activity_id = 58081273;
select * from activities where crm_configuration_id = 537 and provider = 'aircall'
and account_id = 19003658 order by updated_at desc;
select * from contacts where crm_configuration_id = 537 and id = 35957759;
select * from accounts where crm_configuration_id = 537 and id = 19003658;
select * from automated_report_results where id = 1976;
select * from automated_reports where id = 583;
select * from activity_searches where id = 87714;
select * from activity_search_filters where activity_search_id = 87714;
SELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid
or uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;
SELECT * FROM crm_configurations WHERE provider = 'hubspot';
select * from rate_limits;
select * from automated_report_results where media_type = 'pdf' and status = 2
and id IN (18, 1872);
select * from automated_reports where id = 54;
SELECT * FROM users WHERE id IN (24623,29443,29613);
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app, folder
.circleci, folder
.cursor, folder
.github
.sonarlint, folder
.vscode, folder
.windsurf, folder
app, sources root
Actions
InviteUserToTeamAction.php, class
MarkUserAsOnboardableAction.php, class
SyncRecordingFlagsAction.php, class
UpdateTeamMemberAction.php, class
UpdateUserRolesAction.php, class
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"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\\DTO\\Invitation;\n\nuse Jiminny\\DTO\\UserEmail;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\CreateInvitationRequest;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\CreateTeamRequest;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\EditTeamRequest;\nuse Jiminny\\Models\\Group;\nuse Jiminny\\Models\\Invitation;\nuse Jiminny\\Models\\Role;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\n\nclass UserInvitationDTO\n{\n use UserEmail;\n\n public string $email;\n public ?string $secondaryEmail;\n public ?int $groupId;\n public int $teamId;\n public bool $crmRequired;\n public array $roleIds;\n public bool $isOwner;\n public ?User $currentUser = null;\n\n /**\n * @param array{\n * email: string,\n * secondaryEmail: string|null,\n * groupId: int|null,\n * teamId: int|string,\n * crmRequired: bool,\n * roleIds: int[],\n * isOwner: bool,\n * user?: User\n * } $attributes\n */\n private function __construct(array $attributes)\n {\n $this->email = mb_strtolower($attributes['email']);\n $this->secondaryEmail = $this->normalizeNullable($attributes['secondaryEmail']);\n $this->groupId = $attributes['groupId'];\n $this->teamId = (int) $attributes['teamId'];\n $this->crmRequired = (bool) $attributes['crmRequired'];\n $this->roleIds = $attributes['roleIds'];\n $this->isOwner = $attributes['isOwner'];\n $this->currentUser = $attributes['user'] ?? null;\n }\n\n public static function forOwner(CreateTeamRequest|EditTeamRequest $request, Team $team): self\n {\n $roleIds = Role::whereIn('name', [\n User::ROLE_ADMIN,\n User::ROLE_RECORDER,\n ])->pluck('id')->toArray();\n\n /** @var User $currentUser */\n $currentUser = $request->user();\n\n return new self([\n 'email' => $request->getOwnerEmail(),\n 'secondaryEmail' => null,\n 'groupId' => null,\n 'teamId' => $team->getId(),\n 'crmRequired' => true,\n 'roleIds' => $roleIds,\n 'user' => $currentUser,\n 'isOwner' => true,\n ]);\n }\n\n public static function fromRequest(CreateInvitationRequest $request): self\n {\n $data = $request->validated();\n\n $groupId = isset($data['group_id']) ? Group::uuid($request->input('group_id'))->getId() : null;\n $teamId = Team::uuid($data['team_id'])->getId();\n\n /** @var User $currentUser */\n $currentUser = $request->user();\n\n return new self([\n 'email' => mb_strtolower($data['email']),\n 'secondaryEmail' => $data['secondary_email'] ?? null,\n 'groupId' => $groupId,\n 'teamId' => $teamId,\n 'crmRequired' => $data['crm_required'],\n 'roleIds' => $data['roles'],\n 'user' => $currentUser,\n 'isOwner' => false,\n ]);\n }\n\n public static function fromInvitation(Invitation $invitation, User $currentUser): self\n {\n $roles = $invitation->roles()->get();\n $isOwner = $invitation->isOwner();\n\n return new self([\n 'email' => $invitation->email,\n 'secondaryEmail' => $invitation->getSecondaryEmail(),\n 'groupId' => $invitation->group_id,\n 'teamId' => $invitation->team_id,\n 'crmRequired' => $invitation->crm_required,\n 'roleIds' => $roles->pluck('id')->toArray(),\n 'user' => $currentUser,\n 'isOwner' => $isOwner,\n ]);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\DTO\\Invitation;\n\nuse Jiminny\\DTO\\UserEmail;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\CreateInvitationRequest;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\CreateTeamRequest;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\EditTeamRequest;\nuse Jiminny\\Models\\Group;\nuse Jiminny\\Models\\Invitation;\nuse Jiminny\\Models\\Role;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\n\nclass UserInvitationDTO\n{\n use UserEmail;\n\n public string $email;\n public ?string $secondaryEmail;\n public ?int $groupId;\n public int $teamId;\n public bool $crmRequired;\n public array $roleIds;\n public bool $isOwner;\n public ?User $currentUser = null;\n\n /**\n * @param array{\n * email: string,\n * secondaryEmail: string|null,\n * groupId: int|null,\n * teamId: int|string,\n * crmRequired: bool,\n * roleIds: int[],\n * isOwner: bool,\n * user?: User\n * } $attributes\n */\n private function __construct(array $attributes)\n {\n $this->email = mb_strtolower($attributes['email']);\n $this->secondaryEmail = $this->normalizeNullable($attributes['secondaryEmail']);\n $this->groupId = $attributes['groupId'];\n $this->teamId = (int) $attributes['teamId'];\n $this->crmRequired = (bool) $attributes['crmRequired'];\n $this->roleIds = $attributes['roleIds'];\n $this->isOwner = $attributes['isOwner'];\n $this->currentUser = $attributes['user'] ?? null;\n }\n\n public static function forOwner(CreateTeamRequest|EditTeamRequest $request, Team $team): self\n {\n $roleIds = Role::whereIn('name', [\n User::ROLE_ADMIN,\n User::ROLE_RECORDER,\n ])->pluck('id')->toArray();\n\n /** @var User $currentUser */\n $currentUser = $request->user();\n\n return new self([\n 'email' => $request->getOwnerEmail(),\n 'secondaryEmail' => null,\n 'groupId' => null,\n 'teamId' => $team->getId(),\n 'crmRequired' => true,\n 'roleIds' => $roleIds,\n 'user' => $currentUser,\n 'isOwner' => true,\n ]);\n }\n\n public static function fromRequest(CreateInvitationRequest $request): self\n {\n $data = $request->validated();\n\n $groupId = isset($data['group_id']) ? Group::uuid($request->input('group_id'))->getId() : null;\n $teamId = Team::uuid($data['team_id'])->getId();\n\n /** @var User $currentUser */\n $currentUser = $request->user();\n\n return new self([\n 'email' => mb_strtolower($data['email']),\n 'secondaryEmail' => $data['secondary_email'] ?? null,\n 'groupId' => $groupId,\n 'teamId' => $teamId,\n 'crmRequired' => $data['crm_required'],\n 'roleIds' => $data['roles'],\n 'user' => $currentUser,\n 'isOwner' => false,\n ]);\n }\n\n public static function fromInvitation(Invitation $invitation, User $currentUser): self\n {\n $roles = $invitation->roles()->get();\n $isOwner = $invitation->isOwner();\n\n return new self([\n 'email' => $invitation->email,\n 'secondaryEmail' => $invitation->getSecondaryEmail(),\n 'groupId' => $invitation->group_id,\n 'teamId' => $invitation->team_id,\n 'crmRequired' => $invitation->crm_required,\n 'roleIds' => $roles->pluck('id')->toArray(),\n 'user' => $currentUser,\n 'isOwner' => $isOwner,\n ]);\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":"40","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"40","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"64","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","depth":4,"on_screen":true,"value":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app, 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":".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","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"InviteUserToTeamAction.php, class","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MarkUserAsOnboardableAction.php, class","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncRecordingFlagsAction.php, class","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"UpdateTeamMemberAction.php, class","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"UpdateUserRolesAction.php, class","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dtos","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Events","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Country","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Database","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Datadog","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DateTime","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encoding","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encryption","depth":9,"on_screen":false,"role_description":"text"}]...
|
328271563575438936
|
1065696262820869709
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
4
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\DTO\Invitation;
use Jiminny\DTO\UserEmail;
use Jiminny\Http\Requests\Settings\Teams\CreateInvitationRequest;
use Jiminny\Http\Requests\Settings\Teams\CreateTeamRequest;
use Jiminny\Http\Requests\Settings\Teams\EditTeamRequest;
use Jiminny\Models\Group;
use Jiminny\Models\Invitation;
use Jiminny\Models\Role;
use Jiminny\Models\Team;
use Jiminny\Models\User;
class UserInvitationDTO
{
use UserEmail;
public string $email;
public ?string $secondaryEmail;
public ?int $groupId;
public int $teamId;
public bool $crmRequired;
public array $roleIds;
public bool $isOwner;
public ?User $currentUser = null;
/**
* @param array{
* email: string,
* secondaryEmail: string|null,
* groupId: int|null,
* teamId: int|string,
* crmRequired: bool,
* roleIds: int[],
* isOwner: bool,
* user?: User
* } $attributes
*/
private function __construct(array $attributes)
{
$this->email = mb_strtolower($attributes['email']);
$this->secondaryEmail = $this->normalizeNullable($attributes['secondaryEmail']);
$this->groupId = $attributes['groupId'];
$this->teamId = (int) $attributes['teamId'];
$this->crmRequired = (bool) $attributes['crmRequired'];
$this->roleIds = $attributes['roleIds'];
$this->isOwner = $attributes['isOwner'];
$this->currentUser = $attributes['user'] ?? null;
}
public static function forOwner(CreateTeamRequest|EditTeamRequest $request, Team $team): self
{
$roleIds = Role::whereIn('name', [
User::ROLE_ADMIN,
User::ROLE_RECORDER,
])->pluck('id')->toArray();
/** @var User $currentUser */
$currentUser = $request->user();
return new self([
'email' => $request->getOwnerEmail(),
'secondaryEmail' => null,
'groupId' => null,
'teamId' => $team->getId(),
'crmRequired' => true,
'roleIds' => $roleIds,
'user' => $currentUser,
'isOwner' => true,
]);
}
public static function fromRequest(CreateInvitationRequest $request): self
{
$data = $request->validated();
$groupId = isset($data['group_id']) ? Group::uuid($request->input('group_id'))->getId() : null;
$teamId = Team::uuid($data['team_id'])->getId();
/** @var User $currentUser */
$currentUser = $request->user();
return new self([
'email' => mb_strtolower($data['email']),
'secondaryEmail' => $data['secondary_email'] ?? null,
'groupId' => $groupId,
'teamId' => $teamId,
'crmRequired' => $data['crm_required'],
'roleIds' => $data['roles'],
'user' => $currentUser,
'isOwner' => false,
]);
}
public static function fromInvitation(Invitation $invitation, User $currentUser): self
{
$roles = $invitation->roles()->get();
$isOwner = $invitation->isOwner();
return new self([
'email' => $invitation->email,
'secondaryEmail' => $invitation->getSecondaryEmail(),
'groupId' => $invitation->group_id,
'teamId' => $invitation->team_id,
'crmRequired' => $invitation->crm_required,
'roleIds' => $roles->pluck('id')->toArray(),
'user' => $currentUser,
'isOwner' => $isOwner,
]);
}
}
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
40
1
40
64
Previous Highlighted Error
Next Highlighted Error
SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993
SELECT * FROM users WHERE id = 25061;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 994;
SELECT * FROM crm_profiles WHERE user_id = 25061;
select * from crm_configurations where id = 834;
SELECT * FROM teams WHERE id = 882;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;
SELECT * FROM contacts where crm_configuration_id = 834;
SELECT * FROM opportunities WHERE team_id = 933
# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');
AND id IN (8482561,18352941,19042734,19232139,19445140,19472541);
SELECT * FROM opportunity_contacts
WHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 485; #
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
select crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id
where crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')
# and l.converted_at IS NOT NULL
;
# [PASSWORD_DOTS]
SELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')
and opportunity_id IS NULL
order by id desc;
SELECT * FROM teams WHERE id = 604; # 598
SELECT * FROM activities WHERE id = 74410828; # [EMAIL]
SELECT * FROM accounts WHERE id = 20068382;
SELECT * FROM accounts WHERE id = 35186038;
SELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 559 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;
select * from sidekick_settings where team_id = 781;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100
SELECT * FROM crm_layouts WHERE crm_configuration_id = 711;
SELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL
and is_internal = 0 and status = 'completed'
order by id desc;
SELECT * FROM crm_layout_entities
WHERE crm_layout_id IN (2352, 2353);
;
SELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 556 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;
SELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;
select * from contacts
where crm_configuration_id = 530
and crm_provider_id = 872252;
select * from activities where crm_configuration_id = 530
and user_id = 14343 and type like '%softphone%'
and created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);
SELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t
JOIN crm_configurations c ON t.id = c.team_id
WHERE t.status = 'active';
SELECT * FROM teams where id = 1091;
SELECT * FROM crm_configurations where team_id = 1091;
SELECT * FROM activity_providers where team_id = 1091;
SELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT * FROM teams WHERE name LIKE '%Leadventure%';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1091 and sa.provider = 'salesforce';
SELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812
SELECT * FROM teams where id = 862;
SELECT * FROM crm_configurations where team_id = 862;
SELECT * FROM activity_providers where team_id = 862;
SELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT t.id, crm.id, crm.provider, ap.* FROM teams t
join crm_configurations crm on t.id = crm.team_id
join activity_providers ap on t.id = ap.team_id
where t.status = 'active' and ap.is_enabled = 1
and crm.provider = 'hubspot'
and ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',
'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');
SELECT * FROM teams where id = 1068;
SELECT * FROM crm_configurations where team_id = 1068;
SELECT * FROM activity_providers where team_id = 1068;
SELECT * FROM activities a
where crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')
and a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'
)
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by a.id desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1068 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262
SELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
select * from crm_layouts where crm_configuration_id = 834;
select * from crm_layout_entities where crm_layout_id = 2780;
select * from crm_fields where id IN (321153,321192,321193,321194);
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1057 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8
SELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20
SELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10
SELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #
SELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;
select * from users where team_id = 51; # 7783
SELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130
select * from activity_searches where user_id = 7783;
select * from activity_search_filters where activity_search_id IN (32291, 32292);
SELECT asf.activity_search_id, asf.id, asf.value
FROM activity_search_filters asf
WHERE asf.filter = 'group_id'
AND asf.value IN (
SELECT CONCAT(
HEX(SUBSTR(uuid, 5, 4)), '-',
HEX(SUBSTR(uuid, 3, 2)), '-',
HEX(SUBSTR(uuid, 1, 2)), '-',
HEX(SUBSTR(uuid, 9, 2)), '-',
HEX(SUBSTR(uuid, 11))
)
FROM groups
WHERE deleted_at IS NOT NULL
);
SELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where provider = 'hubspot';
SELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133
SELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null
# [PASSWORD_DOTS]
select * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';
select
cp.*
# DISTINCT t.id
# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields
FROM crm_profiles cp
JOIN crm_configurations crm on crm.id = cp.crm_configuration_id
JOIN users u on u.id = cp.user_id
JOIN teams t ON t.id = crm.team_id
WHERE crm.provider = 'salesforce' and t.status = 'active'
and cp.archived_at IS NULL and u.deleted_at IS NULL
and t.id NOT IN (1093)
and t.id = 2
and cp.contact_fields IS NULL;
# and c.crm_provider_id = '003Uu00000ojD4NIAU';
SELECT * FROM users WHERE id = 26484;
SELECT * FROM crm_profiles WHERE user_id = 26484;
SELECT * FROM social_accounts WHERE sociable_id = 26484;
SELECT * FROM crm_configurations where provider = 'salesforce';
select * from users where id IN (10022, 10403);
select * from users where team_id IN (526);
select * from teams where id IN (526, 532);
select * from crm_configurations where id IN (500, 516);
select * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);
select * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 526 and sa.provider = 'salesforce';
select * from team_settings where team_id IN (526, 532);
select * from users where id IN (22824);
select * from crm_profiles where crm_configuration_id IN (1026);
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1093 and sa.provider = 'salesforce';
select * from teams where id = 1099;
select * from users where id = 29643
select * from activity_processing_states;
SELECT * FROM teams where name LIKE '%Fare%'; # 233
SELECT * FROM opportunities where crm_configuration_id = 215
# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'
;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1088 and sa.provider = 'hubspot';
SELECT * FROM teams order by updated_at DESC
SELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account
select * from crm_configurations where provider = 'pipedrive';
select * from teams where id = 957;
select * from crm_configurations where id = 957;
SELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743
SELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;
select * from users where team_id = 1; # 26726 - Gabriela Dureva
SELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific
select * from activities where user_id = 26726 order by id desc;
select * from contacts where crm_configuration_id = 1
and email IN ('[EMAIL]', '[EMAIL]'); # 2094416, 2093620
SELECT * FROM contacts WHERE id = 6284931;
SELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id
WHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;
select * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);
select * from crm_configurations where id = 1;
43801692-1aeb-32ce-acba-5b80a479701a
44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b
405975c0-b3d0-7aaa-821f-09d59cae6dd1
4caf848d-4bed-2299-b248-7788d41f9fca
49bedc3f-f196-eef3-89c3-dea6a3b4aa63
43420989-a09d-b8f8-9806-c8bbf7a02aac
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
SELECT * FROM activities WHERE id = 75461988;
SELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;
select * from contacts where id = 17900517;
select * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id
where crm.provider != 'salesforce';
select * from users where id = 21047;
SELECT * FROM crm_configurations WHERE id = 892;
SELECT * FROM teams WHERE id = 942;
select * from opportunities where team_id = 942 order by updated_at desc;
select * from contacts where team_id = 942 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 942 and sa.provider = 'hubspot';
SELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430
SELECT * FROM crm_configurations WHERE id = 1;
SELECT * FROM teams WHERE crm_id = 1;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
select id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1
SELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430
select * from teams where id = 852;
select * from groups where id = 2286;
select * from sidekick_settings where team_id = 852;
select * from default_activity_types where team_id = 852;
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1 AND u.deleted_at IS NULL
AND u.crm_required = 1
AND u.team_id = 1
ORDER BY u.team_id;
SELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (
18481
);
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1
AND u.deleted_at IS NULL
AND u.crm_required = 1
# AND u.team_id = 1
AND p.id IS NULL -- Move this condition to WHERE clause
ORDER BY u.team_id;
SELECT * FROM opportunities WHERE id = 20002609;
select * from teams where id = 1122; # Velatir, 29953 - [EMAIL]
select * from crm_configurations where id = 1060;
select * from crm_layouts where crm_configuration_id = 1060;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1122 and sa.provider = 'hubspot';
select * from opportunities where team_id = 1122 order by updated_at desc;
select * from crm_field_data where object_type = 'contact';
SELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 248 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS
SELECT * FROM users where id = 24115;
SELECT * FROM accounts where id = 4002896;
SELECT * FROM teams WHERE name LIKE '%adswerve%';
SELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN ("0069N000003GIQ9QAO","0061r000019yGP9AAM","0066900001S2KWlAAN","0066900001TDpj2AAD","0066900001b8uEwAAI","0069N000001rQi0QAE","006QF00000KD40mYAD","006QF00000LzpRJYAZ","0069N000002uomtQAA","0069N000002xlMLQAY","0066900001NV6ubAAD","0061r00001HJp45AAD","006QF00000uTlUoYAK","006QF00000v0bZqYAI");
SELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203
SELECT u.id, u.email, ac.name, a.* FROM activities a
JOIN users u ON a.user_id = u.id
JOIN accounts ac ON a.account_id = ac.id
WHERE
uuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or
uuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or
uuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;
select * from users where id = 5825;
SELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;
select * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;
19594, 862
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 862 and sa.provider = 'salesforce';
select * from automated_reports where id = 36;
select ar.frequency, r.*, ar.* from automated_report_results r
join automated_reports ar on r.report_id = ar.id
where ar.frequency != 'one_off';
select s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;
select * from nudges n where n.activity_search_id
select * from teams where created_at > '2026-03-09';
SELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;
select * from users where team_id = 1 and name like '%Lukas%'; # 7160
SELECT * FROM teams WHERE id = 575;
select * from opportunities where team_id = 575;
SELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,
select * from opportunities where team_id = 1126;
SELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,
select * from opportunities where team_id = 1125;
select * from contacts c
where c.team_id = 882;
SELECT * FROM activities WHERE id = 76822967;
SELECT * FROM crm_profiles WHERE user_id = 15440;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 555;
SELECT * FROM crm_configurations WHERE id = 555;
SELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 581 and sa.provider = 'salesforce';
SELECT * FROM automated_report_results order by id desc;
select * from features;
select * from team_features where feature_id = 40;
select * from teams where id = 556;
select * from automated_reports;
where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , ["pdf","podcast"]
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
select * from automated_report_results order by id desc;
SELECT * FROM automated_report_results WHERE id = 1919;
select * from automated_report_results WHERE report_id = 54;
select * from opportunities where id = 7594349;
SELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - [EMAIL]
select * from playbooks where team_id = 711; # event 226147
SELECT * FROM playbook_categories WHERE playbook_id = 5515;
SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';
SELECT * FROM crm_fields WHERE id = 226147;
SELECT * FROM crm_field_values WHERE crm_field_id = 226147;
SELECT * FROM crm_configurations WHERE id = 692;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 711 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;
select * from leads;
select * from calendars;
SELECT
t.id AS team_id,
t.name,
LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain
FROM teams t
JOIN users u ON u.team_id = t.id
JOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'
LEFT JOIN team_domains td
ON td.team_id = t.id
AND td.deleted_at IS NULL
AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))
GROUP BY t.id, t.name, calendar_domain
ORDER BY t.name, calendar_domain;
select * from users u join calendars c on c.user_id = u.id
where u.team_id = 882;
select * from activities where id = 74049485; # team 563 crm 537
select * from activities where id = 73272382; # team 563 crm 537
select * from activities where id = 64400389; # team 563 crm 537
select * from activities where id = 58081273; # team 563 crm 537
select * from activities where id = 54520297; # team 563 crm 537
select * from participants where activity_id = 58081273;
select * from activities where crm_configuration_id = 537 and provider = 'aircall'
and account_id = 19003658 order by updated_at desc;
select * from contacts where crm_configuration_id = 537 and id = 35957759;
select * from accounts where crm_configuration_id = 537 and id = 19003658;
select * from automated_report_results where id = 1976;
select * from automated_reports where id = 583;
select * from activity_searches where id = 87714;
select * from activity_search_filters where activity_search_id = 87714;
SELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid
or uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;
SELECT * FROM crm_configurations WHERE provider = 'hubspot';
select * from rate_limits;
select * from automated_report_results where media_type = 'pdf' and status = 2
and id IN (18, 1872);
select * from automated_reports where id = 54;
SELECT * FROM users WHERE id IN (24623,29443,29613);
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app, folder
.circleci, folder
.cursor, folder
.github
.sonarlint, folder
.vscode, folder
.windsurf, folder
app, sources root
Actions
InviteUserToTeamAction.php, class
MarkUserAsOnboardableAction.php, class
SyncRecordingFlagsAction.php, class
UpdateTeamMemberAction.php, class
UpdateUserRolesAction.php, class
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption...
|
32902
|
NULL
|
NULL
|
NULL
|
|
32905
|
1257
|
16
|
2026-05-13T09:45:05.336327+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665505336_m2.jpg...
|
PhpStorm
|
faVsco.js – UserInvitationDTO.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
4
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\DTO\Invitation;
use Jiminny\DTO\UserEmail;
use Jiminny\Http\Requests\Settings\Teams\CreateInvitationRequest;
use Jiminny\Http\Requests\Settings\Teams\CreateTeamRequest;
use Jiminny\Http\Requests\Settings\Teams\EditTeamRequest;
use Jiminny\Models\Group;
use Jiminny\Models\Invitation;
use Jiminny\Models\Role;
use Jiminny\Models\Team;
use Jiminny\Models\User;
class UserInvitationDTO
{
use UserEmail;
public string $email;
public ?string $secondaryEmail;
public ?int $groupId;
public int $teamId;
public bool $crmRequired;
public array $roleIds;
public bool $isOwner;
public ?User $currentUser = null;
/**
* @param array{
* email: string,
* secondaryEmail: string|null,
* groupId: int|null,
* teamId: int|string,
* crmRequired: bool,
* roleIds: int[],
* isOwner: bool,
* user?: User
* } $attributes
*/
private function __construct(array $attributes)
{
$this->email = mb_strtolower($attributes['email']);
$this->secondaryEmail = $this->normalizeNullable($attributes['secondaryEmail']);
$this->groupId = $attributes['groupId'];
$this->teamId = (int) $attributes['teamId'];
$this->crmRequired = (bool) $attributes['crmRequired'];
$this->roleIds = $attributes['roleIds'];
$this->isOwner = $attributes['isOwner'];
$this->currentUser = $attributes['user'] ?? null;
}
public static function forOwner(CreateTeamRequest|EditTeamRequest $request, Team $team): self
{
$roleIds = Role::whereIn('name', [
User::ROLE_ADMIN,
User::ROLE_RECORDER,
])->pluck('id')->toArray();
/** @var User $currentUser */
$currentUser = $request->user();
return new self([
'email' => $request->getOwnerEmail(),
'secondaryEmail' => null,
'groupId' => null,
'teamId' => $team->getId(),
'crmRequired' => true,
'roleIds' => $roleIds,
'user' => $currentUser,
'isOwner' => true,
]);
}
public static function fromRequest(CreateInvitationRequest $request): self
{
$data = $request->validated();
$groupId = isset($data['group_id']) ? Group::uuid($request->input('group_id'))->getId() : null;
$teamId = Team::uuid($data['team_id'])->getId();
/** @var User $currentUser */
$currentUser = $request->user();
return new self([
'email' => mb_strtolower($data['email']),
'secondaryEmail' => $data['secondary_email'] ?? null,
'groupId' => $groupId,
'teamId' => $teamId,
'crmRequired' => $data['crm_required'],
'roleIds' => $data['roles'],
'user' => $currentUser,
'isOwner' => false,
]);
}
public static function fromInvitation(Invitation $invitation, User $currentUser): self
{
$roles = $invitation->roles()->get();
$isOwner = $invitation->isOwner();
return new self([
'email' => $invitation->email,
'secondaryEmail' => $invitation->getSecondaryEmail(),
'groupId' => $invitation->group_id,
'teamId' => $invitation->team_id,
'crmRequired' => $invitation->crm_required,
'roleIds' => $roles->pluck('id')->toArray(),
'user' => $currentUser,
'isOwner' => $isOwner,
]);
}
}
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
40
1
40
64
Previous Highlighted Error
Next Highlighted Error
SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993
SELECT * FROM users WHERE id = 25061;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 994;
SELECT * FROM crm_profiles WHERE user_id = 25061;
select * from crm_configurations where id = 834;
SELECT * FROM teams WHERE id = 882;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;
SELECT * FROM contacts where crm_configuration_id = 834;
SELECT * FROM opportunities WHERE team_id = 933
# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');
AND id IN (8482561,18352941,19042734,19232139,19445140,19472541);
SELECT * FROM opportunity_contacts
WHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 485; #
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
select crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id
where crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')
# and l.converted_at IS NOT NULL
;
# [PASSWORD_DOTS]
SELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')
and opportunity_id IS NULL
order by id desc;
SELECT * FROM teams WHERE id = 604; # 598
SELECT * FROM activities WHERE id = 74410828; # [EMAIL]
SELECT * FROM accounts WHERE id = 20068382;
SELECT * FROM accounts WHERE id = 35186038;
SELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 559 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;
select * from sidekick_settings where team_id = 781;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100
SELECT * FROM crm_layouts WHERE crm_configuration_id = 711;
SELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL
and is_internal = 0 and status = 'completed'
order by id desc;
SELECT * FROM crm_layout_entities
WHERE crm_layout_id IN (2352, 2353);
;
SELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 556 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;
SELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;
select * from contacts
where crm_configuration_id = 530
and crm_provider_id = 872252;
select * from activities where crm_configuration_id = 530
and user_id = 14343 and type like '%softphone%'
and created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);
SELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t
JOIN crm_configurations c ON t.id = c.team_id
WHERE t.status = 'active';
SELECT * FROM teams where id = 1091;
SELECT * FROM crm_configurations where team_id = 1091;
SELECT * FROM activity_providers where team_id = 1091;
SELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT * FROM teams WHERE name LIKE '%Leadventure%';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1091 and sa.provider = 'salesforce';
SELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812
SELECT * FROM teams where id = 862;
SELECT * FROM crm_configurations where team_id = 862;
SELECT * FROM activity_providers where team_id = 862;
SELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT t.id, crm.id, crm.provider, ap.* FROM teams t
join crm_configurations crm on t.id = crm.team_id
join activity_providers ap on t.id = ap.team_id
where t.status = 'active' and ap.is_enabled = 1
and crm.provider = 'hubspot'
and ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',
'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');
SELECT * FROM teams where id = 1068;
SELECT * FROM crm_configurations where team_id = 1068;
SELECT * FROM activity_providers where team_id = 1068;
SELECT * FROM activities a
where crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')
and a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'
)
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by a.id desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1068 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262
SELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
select * from crm_layouts where crm_configuration_id = 834;
select * from crm_layout_entities where crm_layout_id = 2780;
select * from crm_fields where id IN (321153,321192,321193,321194);
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1057 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8
SELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20
SELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10
SELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #
SELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;
select * from users where team_id = 51; # 7783
SELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130
select * from activity_searches where user_id = 7783;
select * from activity_search_filters where activity_search_id IN (32291, 32292);
SELECT asf.activity_search_id, asf.id, asf.value
FROM activity_search_filters asf
WHERE asf.filter = 'group_id'
AND asf.value IN (
SELECT CONCAT(
HEX(SUBSTR(uuid, 5, 4)), '-',
HEX(SUBSTR(uuid, 3, 2)), '-',
HEX(SUBSTR(uuid, 1, 2)), '-',
HEX(SUBSTR(uuid, 9, 2)), '-',
HEX(SUBSTR(uuid, 11))
)
FROM groups
WHERE deleted_at IS NOT NULL
);
SELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where provider = 'hubspot';
SELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133
SELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null
# [PASSWORD_DOTS]
select * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';
select
cp.*
# DISTINCT t.id
# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields
FROM crm_profiles cp
JOIN crm_configurations crm on crm.id = cp.crm_configuration_id
JOIN users u on u.id = cp.user_id
JOIN teams t ON t.id = crm.team_id
WHERE crm.provider = 'salesforce' and t.status = 'active'
and cp.archived_at IS NULL and u.deleted_at IS NULL
and t.id NOT IN (1093)
and t.id = 2
and cp.contact_fields IS NULL;
# and c.crm_provider_id = '003Uu00000ojD4NIAU';
SELECT * FROM users WHERE id = 26484;
SELECT * FROM crm_profiles WHERE user_id = 26484;
SELECT * FROM social_accounts WHERE sociable_id = 26484;
SELECT * FROM crm_configurations where provider = 'salesforce';
select * from users where id IN (10022, 10403);
select * from users where team_id IN (526);
select * from teams where id IN (526, 532);
select * from crm_configurations where id IN (500, 516);
select * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);
select * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 526 and sa.provider = 'salesforce';
select * from team_settings where team_id IN (526, 532);
select * from users where id IN (22824);
select * from crm_profiles where crm_configuration_id IN (1026);
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1093 and sa.provider = 'salesforce';
select * from teams where id = 1099;
select * from users where id = 29643
select * from activity_processing_states;
SELECT * FROM teams where name LIKE '%Fare%'; # 233
SELECT * FROM opportunities where crm_configuration_id = 215
# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'
;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1088 and sa.provider = 'hubspot';
SELECT * FROM teams order by updated_at DESC
SELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account
select * from crm_configurations where provider = 'pipedrive';
select * from teams where id = 957;
select * from crm_configurations where id = 957;
SELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743
SELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;
select * from users where team_id = 1; # 26726 - Gabriela Dureva
SELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific
select * from activities where user_id = 26726 order by id desc;
select * from contacts where crm_configuration_id = 1
and email IN ('[EMAIL]', '[EMAIL]'); # 2094416, 2093620
SELECT * FROM contacts WHERE id = 6284931;
SELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id
WHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;
select * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);
select * from crm_configurations where id = 1;
43801692-1aeb-32ce-acba-5b80a479701a
44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b
405975c0-b3d0-7aaa-821f-09d59cae6dd1
4caf848d-4bed-2299-b248-7788d41f9fca
49bedc3f-f196-eef3-89c3-dea6a3b4aa63
43420989-a09d-b8f8-9806-c8bbf7a02aac
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
SELECT * FROM activities WHERE id = 75461988;
SELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;
select * from contacts where id = 17900517;
select * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id
where crm.provider != 'salesforce';
select * from users where id = 21047;
SELECT * FROM crm_configurations WHERE id = 892;
SELECT * FROM teams WHERE id = 942;
select * from opportunities where team_id = 942 order by updated_at desc;
select * from contacts where team_id = 942 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 942 and sa.provider = 'hubspot';
SELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430
SELECT * FROM crm_configurations WHERE id = 1;
SELECT * FROM teams WHERE crm_id = 1;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
select id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1
SELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430
select * from teams where id = 852;
select * from groups where id = 2286;
select * from sidekick_settings where team_id = 852;
select * from default_activity_types where team_id = 852;
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1 AND u.deleted_at IS NULL
AND u.crm_required = 1
AND u.team_id = 1
ORDER BY u.team_id;
SELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (
18481
);
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1
AND u.deleted_at IS NULL
AND u.crm_required = 1
# AND u.team_id = 1
AND p.id IS NULL -- Move this condition to WHERE clause
ORDER BY u.team_id;
SELECT * FROM opportunities WHERE id = 20002609;
select * from teams where id = 1122; # Velatir, 29953 - [EMAIL]
select * from crm_configurations where id = 1060;
select * from crm_layouts where crm_configuration_id = 1060;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1122 and sa.provider = 'hubspot';
select * from opportunities where team_id = 1122 order by updated_at desc;
select * from crm_field_data where object_type = 'contact';
SELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 248 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS
SELECT * FROM users where id = 24115;
SELECT * FROM accounts where id = 4002896;
SELECT * FROM teams WHERE name LIKE '%adswerve%';
SELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN ("0069N000003GIQ9QAO","0061r000019yGP9AAM","0066900001S2KWlAAN","0066900001TDpj2AAD","0066900001b8uEwAAI","0069N000001rQi0QAE","006QF00000KD40mYAD","006QF00000LzpRJYAZ","0069N000002uomtQAA","0069N000002xlMLQAY","0066900001NV6ubAAD","0061r00001HJp45AAD","006QF00000uTlUoYAK","006QF00000v0bZqYAI");
SELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203
SELECT u.id, u.email, ac.name, a.* FROM activities a
JOIN users u ON a.user_id = u.id
JOIN accounts ac ON a.account_id = ac.id
WHERE
uuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or
uuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or
uuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;
select * from users where id = 5825;
SELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;
select * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;
19594, 862
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 862 and sa.provider = 'salesforce';
select * from automated_reports where id = 36;
select ar.frequency, r.*, ar.* from automated_report_results r
join automated_reports ar on r.report_id = ar.id
where ar.frequency != 'one_off';
select s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;
select * from nudges n where n.activity_search_id
select * from teams where created_at > '2026-03-09';
SELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;
select * from users where team_id = 1 and name like '%Lukas%'; # 7160
SELECT * FROM teams WHERE id = 575;
select * from opportunities where team_id = 575;
SELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,
select * from opportunities where team_id = 1126;
SELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,
select * from opportunities where team_id = 1125;
select * from contacts c
where c.team_id = 882;
SELECT * FROM activities WHERE id = 76822967;
SELECT * FROM crm_profiles WHERE user_id = 15440;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 555;
SELECT * FROM crm_configurations WHERE id = 555;
SELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 581 and sa.provider = 'salesforce';
SELECT * FROM automated_report_results order by id desc;
select * from features;
select * from team_features where feature_id = 40;
select * from teams where id = 556;
select * from automated_reports;
where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , ["pdf","podcast"]
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
select * from automated_report_results order by id desc;
SELECT * FROM automated_report_results WHERE id = 1919;
select * from automated_report_results WHERE report_id = 54;
select * from opportunities where id = 7594349;
SELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - [EMAIL]
select * from playbooks where team_id = 711; # event 226147
SELECT * FROM playbook_categories WHERE playbook_id = 5515;
SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';
SELECT * FROM crm_fields WHERE id = 226147;
SELECT * FROM crm_field_values WHERE crm_field_id = 226147;
SELECT * FROM crm_configurations WHERE id = 692;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 711 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;
select * from leads;
select * from calendars;
SELECT
t.id AS team_id,
t.name,
LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain
FROM teams t
JOIN users u ON u.team_id = t.id
JOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'
LEFT JOIN team_domains td
ON td.team_id = t.id
AND td.deleted_at IS NULL
AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))
GROUP BY t.id, t.name, calendar_domain
ORDER BY t.name, calendar_domain;
select * from users u join calendars c on c.user_id = u.id
where u.team_id = 882;
select * from activities where id = 74049485; # team 563 crm 537
select * from activities where id = 73272382; # team 563 crm 537
select * from activities where id = 64400389; # team 563 crm 537
select * from activities where id = 58081273; # team 563 crm 537
select * from activities where id = 54520297; # team 563 crm 537
select * from participants where activity_id = 58081273;
select * from activities where crm_configuration_id = 537 and provider = 'aircall'
and account_id = 19003658 order by updated_at desc;
select * from contacts where crm_configuration_id = 537 and id = 35957759;
select * from accounts where crm_configuration_id = 537 and id = 19003658;
select * from automated_report_results where id = 1976;
select * from automated_reports where id = 583;
select * from activity_searches where id = 87714;
select * from activity_search_filters where activity_search_id = 87714;
SELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid
or uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;
SELECT * FROM crm_configurations WHERE provider = 'hubspot';
select * from rate_limits;
select * from automated_report_results where media_type = 'pdf' and status = 2
and id IN (18, 1872);
select * from automated_reports where id = 54;
SELECT * FROM users WHERE id IN (24623,29443,29613);
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app, folder
.circleci, folder
.cursor, folder
.github
.sonarlint, folder
.vscode, folder
.windsurf, folder
app, sources root
Actions
InviteUserToTeamAction.php, class
MarkUserAsOnboardableAction.php, class
SyncRecordingFlagsAction.php, class
UpdateTeamMemberAction.php, class
UpdateUserRolesAction.php, class
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.034242023,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.37400267,"top":0.07581804,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.38397607,"top":0.07581804,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.39361703,"top":0.074221864,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.40093085,"top":0.074221864,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\DTO\\Invitation;\n\nuse Jiminny\\DTO\\UserEmail;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\CreateInvitationRequest;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\CreateTeamRequest;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\EditTeamRequest;\nuse Jiminny\\Models\\Group;\nuse Jiminny\\Models\\Invitation;\nuse Jiminny\\Models\\Role;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\n\nclass UserInvitationDTO\n{\n use UserEmail;\n\n public string $email;\n public ?string $secondaryEmail;\n public ?int $groupId;\n public int $teamId;\n public bool $crmRequired;\n public array $roleIds;\n public bool $isOwner;\n public ?User $currentUser = null;\n\n /**\n * @param array{\n * email: string,\n * secondaryEmail: string|null,\n * groupId: int|null,\n * teamId: int|string,\n * crmRequired: bool,\n * roleIds: int[],\n * isOwner: bool,\n * user?: User\n * } $attributes\n */\n private function __construct(array $attributes)\n {\n $this->email = mb_strtolower($attributes['email']);\n $this->secondaryEmail = $this->normalizeNullable($attributes['secondaryEmail']);\n $this->groupId = $attributes['groupId'];\n $this->teamId = (int) $attributes['teamId'];\n $this->crmRequired = (bool) $attributes['crmRequired'];\n $this->roleIds = $attributes['roleIds'];\n $this->isOwner = $attributes['isOwner'];\n $this->currentUser = $attributes['user'] ?? null;\n }\n\n public static function forOwner(CreateTeamRequest|EditTeamRequest $request, Team $team): self\n {\n $roleIds = Role::whereIn('name', [\n User::ROLE_ADMIN,\n User::ROLE_RECORDER,\n ])->pluck('id')->toArray();\n\n /** @var User $currentUser */\n $currentUser = $request->user();\n\n return new self([\n 'email' => $request->getOwnerEmail(),\n 'secondaryEmail' => null,\n 'groupId' => null,\n 'teamId' => $team->getId(),\n 'crmRequired' => true,\n 'roleIds' => $roleIds,\n 'user' => $currentUser,\n 'isOwner' => true,\n ]);\n }\n\n public static function fromRequest(CreateInvitationRequest $request): self\n {\n $data = $request->validated();\n\n $groupId = isset($data['group_id']) ? Group::uuid($request->input('group_id'))->getId() : null;\n $teamId = Team::uuid($data['team_id'])->getId();\n\n /** @var User $currentUser */\n $currentUser = $request->user();\n\n return new self([\n 'email' => mb_strtolower($data['email']),\n 'secondaryEmail' => $data['secondary_email'] ?? null,\n 'groupId' => $groupId,\n 'teamId' => $teamId,\n 'crmRequired' => $data['crm_required'],\n 'roleIds' => $data['roles'],\n 'user' => $currentUser,\n 'isOwner' => false,\n ]);\n }\n\n public static function fromInvitation(Invitation $invitation, User $currentUser): self\n {\n $roles = $invitation->roles()->get();\n $isOwner = $invitation->isOwner();\n\n return new self([\n 'email' => $invitation->email,\n 'secondaryEmail' => $invitation->getSecondaryEmail(),\n 'groupId' => $invitation->group_id,\n 'teamId' => $invitation->team_id,\n 'crmRequired' => $invitation->crm_required,\n 'roleIds' => $roles->pluck('id')->toArray(),\n 'user' => $currentUser,\n 'isOwner' => $isOwner,\n ]);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\DTO\\Invitation;\n\nuse Jiminny\\DTO\\UserEmail;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\CreateInvitationRequest;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\CreateTeamRequest;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\EditTeamRequest;\nuse Jiminny\\Models\\Group;\nuse Jiminny\\Models\\Invitation;\nuse Jiminny\\Models\\Role;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\n\nclass UserInvitationDTO\n{\n use UserEmail;\n\n public string $email;\n public ?string $secondaryEmail;\n public ?int $groupId;\n public int $teamId;\n public bool $crmRequired;\n public array $roleIds;\n public bool $isOwner;\n public ?User $currentUser = null;\n\n /**\n * @param array{\n * email: string,\n * secondaryEmail: string|null,\n * groupId: int|null,\n * teamId: int|string,\n * crmRequired: bool,\n * roleIds: int[],\n * isOwner: bool,\n * user?: User\n * } $attributes\n */\n private function __construct(array $attributes)\n {\n $this->email = mb_strtolower($attributes['email']);\n $this->secondaryEmail = $this->normalizeNullable($attributes['secondaryEmail']);\n $this->groupId = $attributes['groupId'];\n $this->teamId = (int) $attributes['teamId'];\n $this->crmRequired = (bool) $attributes['crmRequired'];\n $this->roleIds = $attributes['roleIds'];\n $this->isOwner = $attributes['isOwner'];\n $this->currentUser = $attributes['user'] ?? null;\n }\n\n public static function forOwner(CreateTeamRequest|EditTeamRequest $request, Team $team): self\n {\n $roleIds = Role::whereIn('name', [\n User::ROLE_ADMIN,\n User::ROLE_RECORDER,\n ])->pluck('id')->toArray();\n\n /** @var User $currentUser */\n $currentUser = $request->user();\n\n return new self([\n 'email' => $request->getOwnerEmail(),\n 'secondaryEmail' => null,\n 'groupId' => null,\n 'teamId' => $team->getId(),\n 'crmRequired' => true,\n 'roleIds' => $roleIds,\n 'user' => $currentUser,\n 'isOwner' => true,\n ]);\n }\n\n public static function fromRequest(CreateInvitationRequest $request): self\n {\n $data = $request->validated();\n\n $groupId = isset($data['group_id']) ? Group::uuid($request->input('group_id'))->getId() : null;\n $teamId = Team::uuid($data['team_id'])->getId();\n\n /** @var User $currentUser */\n $currentUser = $request->user();\n\n return new self([\n 'email' => mb_strtolower($data['email']),\n 'secondaryEmail' => $data['secondary_email'] ?? null,\n 'groupId' => $groupId,\n 'teamId' => $teamId,\n 'crmRequired' => $data['crm_required'],\n 'roleIds' => $data['roles'],\n 'user' => $currentUser,\n 'isOwner' => false,\n ]);\n }\n\n public static function fromInvitation(Invitation $invitation, User $currentUser): self\n {\n $roles = $invitation->roles()->get();\n $isOwner = $invitation->isOwner();\n\n return new self([\n 'email' => $invitation->email,\n 'secondaryEmail' => $invitation->getSecondaryEmail(),\n 'groupId' => $invitation->group_id,\n 'teamId' => $invitation->team_id,\n 'crmRequired' => $invitation->crm_required,\n 'roleIds' => $roles->pluck('id')->toArray(),\n 'user' => $currentUser,\n 'isOwner' => $isOwner,\n ]);\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.40957448,"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.41821808,"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.42918882,"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.43783244,"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.44647607,"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.4574468,"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.46841756,"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.4950133,"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.50598407,"top":0.09896249,"width":0.029587766,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"bounds":{"left":0.7084442,"top":0.09896249,"width":0.02825798,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"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":"40","depth":4,"bounds":{"left":0.67785907,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.69015956,"top":0.123703115,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"40","depth":4,"bounds":{"left":0.6994681,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"64","depth":4,"bounds":{"left":0.7117686,"top":0.123703115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.7237367,"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.73105055,"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 * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","depth":4,"on_screen":true,"value":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","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":".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","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"InviteUserToTeamAction.php, class","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MarkUserAsOnboardableAction.php, class","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncRecordingFlagsAction.php, class","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"UpdateTeamMemberAction.php, class","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"UpdateUserRolesAction.php, class","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dtos","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Events","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Country","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Database","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Datadog","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DateTime","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"on_screen":false,"role_description":"text"}]...
|
919171767952204454
|
1065696262820869709
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
4
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\DTO\Invitation;
use Jiminny\DTO\UserEmail;
use Jiminny\Http\Requests\Settings\Teams\CreateInvitationRequest;
use Jiminny\Http\Requests\Settings\Teams\CreateTeamRequest;
use Jiminny\Http\Requests\Settings\Teams\EditTeamRequest;
use Jiminny\Models\Group;
use Jiminny\Models\Invitation;
use Jiminny\Models\Role;
use Jiminny\Models\Team;
use Jiminny\Models\User;
class UserInvitationDTO
{
use UserEmail;
public string $email;
public ?string $secondaryEmail;
public ?int $groupId;
public int $teamId;
public bool $crmRequired;
public array $roleIds;
public bool $isOwner;
public ?User $currentUser = null;
/**
* @param array{
* email: string,
* secondaryEmail: string|null,
* groupId: int|null,
* teamId: int|string,
* crmRequired: bool,
* roleIds: int[],
* isOwner: bool,
* user?: User
* } $attributes
*/
private function __construct(array $attributes)
{
$this->email = mb_strtolower($attributes['email']);
$this->secondaryEmail = $this->normalizeNullable($attributes['secondaryEmail']);
$this->groupId = $attributes['groupId'];
$this->teamId = (int) $attributes['teamId'];
$this->crmRequired = (bool) $attributes['crmRequired'];
$this->roleIds = $attributes['roleIds'];
$this->isOwner = $attributes['isOwner'];
$this->currentUser = $attributes['user'] ?? null;
}
public static function forOwner(CreateTeamRequest|EditTeamRequest $request, Team $team): self
{
$roleIds = Role::whereIn('name', [
User::ROLE_ADMIN,
User::ROLE_RECORDER,
])->pluck('id')->toArray();
/** @var User $currentUser */
$currentUser = $request->user();
return new self([
'email' => $request->getOwnerEmail(),
'secondaryEmail' => null,
'groupId' => null,
'teamId' => $team->getId(),
'crmRequired' => true,
'roleIds' => $roleIds,
'user' => $currentUser,
'isOwner' => true,
]);
}
public static function fromRequest(CreateInvitationRequest $request): self
{
$data = $request->validated();
$groupId = isset($data['group_id']) ? Group::uuid($request->input('group_id'))->getId() : null;
$teamId = Team::uuid($data['team_id'])->getId();
/** @var User $currentUser */
$currentUser = $request->user();
return new self([
'email' => mb_strtolower($data['email']),
'secondaryEmail' => $data['secondary_email'] ?? null,
'groupId' => $groupId,
'teamId' => $teamId,
'crmRequired' => $data['crm_required'],
'roleIds' => $data['roles'],
'user' => $currentUser,
'isOwner' => false,
]);
}
public static function fromInvitation(Invitation $invitation, User $currentUser): self
{
$roles = $invitation->roles()->get();
$isOwner = $invitation->isOwner();
return new self([
'email' => $invitation->email,
'secondaryEmail' => $invitation->getSecondaryEmail(),
'groupId' => $invitation->group_id,
'teamId' => $invitation->team_id,
'crmRequired' => $invitation->crm_required,
'roleIds' => $roles->pluck('id')->toArray(),
'user' => $currentUser,
'isOwner' => $isOwner,
]);
}
}
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
40
1
40
64
Previous Highlighted Error
Next Highlighted Error
SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993
SELECT * FROM users WHERE id = 25061;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 994;
SELECT * FROM crm_profiles WHERE user_id = 25061;
select * from crm_configurations where id = 834;
SELECT * FROM teams WHERE id = 882;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;
SELECT * FROM contacts where crm_configuration_id = 834;
SELECT * FROM opportunities WHERE team_id = 933
# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');
AND id IN (8482561,18352941,19042734,19232139,19445140,19472541);
SELECT * FROM opportunity_contacts
WHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 485; #
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
select crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id
where crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')
# and l.converted_at IS NOT NULL
;
# [PASSWORD_DOTS]
SELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')
and opportunity_id IS NULL
order by id desc;
SELECT * FROM teams WHERE id = 604; # 598
SELECT * FROM activities WHERE id = 74410828; # [EMAIL]
SELECT * FROM accounts WHERE id = 20068382;
SELECT * FROM accounts WHERE id = 35186038;
SELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 559 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;
select * from sidekick_settings where team_id = 781;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100
SELECT * FROM crm_layouts WHERE crm_configuration_id = 711;
SELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL
and is_internal = 0 and status = 'completed'
order by id desc;
SELECT * FROM crm_layout_entities
WHERE crm_layout_id IN (2352, 2353);
;
SELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 556 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;
SELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;
select * from contacts
where crm_configuration_id = 530
and crm_provider_id = 872252;
select * from activities where crm_configuration_id = 530
and user_id = 14343 and type like '%softphone%'
and created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);
SELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t
JOIN crm_configurations c ON t.id = c.team_id
WHERE t.status = 'active';
SELECT * FROM teams where id = 1091;
SELECT * FROM crm_configurations where team_id = 1091;
SELECT * FROM activity_providers where team_id = 1091;
SELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT * FROM teams WHERE name LIKE '%Leadventure%';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1091 and sa.provider = 'salesforce';
SELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812
SELECT * FROM teams where id = 862;
SELECT * FROM crm_configurations where team_id = 862;
SELECT * FROM activity_providers where team_id = 862;
SELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT t.id, crm.id, crm.provider, ap.* FROM teams t
join crm_configurations crm on t.id = crm.team_id
join activity_providers ap on t.id = ap.team_id
where t.status = 'active' and ap.is_enabled = 1
and crm.provider = 'hubspot'
and ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',
'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');
SELECT * FROM teams where id = 1068;
SELECT * FROM crm_configurations where team_id = 1068;
SELECT * FROM activity_providers where team_id = 1068;
SELECT * FROM activities a
where crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')
and a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'
)
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by a.id desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1068 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262
SELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
select * from crm_layouts where crm_configuration_id = 834;
select * from crm_layout_entities where crm_layout_id = 2780;
select * from crm_fields where id IN (321153,321192,321193,321194);
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1057 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8
SELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20
SELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10
SELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #
SELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;
select * from users where team_id = 51; # 7783
SELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130
select * from activity_searches where user_id = 7783;
select * from activity_search_filters where activity_search_id IN (32291, 32292);
SELECT asf.activity_search_id, asf.id, asf.value
FROM activity_search_filters asf
WHERE asf.filter = 'group_id'
AND asf.value IN (
SELECT CONCAT(
HEX(SUBSTR(uuid, 5, 4)), '-',
HEX(SUBSTR(uuid, 3, 2)), '-',
HEX(SUBSTR(uuid, 1, 2)), '-',
HEX(SUBSTR(uuid, 9, 2)), '-',
HEX(SUBSTR(uuid, 11))
)
FROM groups
WHERE deleted_at IS NOT NULL
);
SELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where provider = 'hubspot';
SELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133
SELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null
# [PASSWORD_DOTS]
select * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';
select
cp.*
# DISTINCT t.id
# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields
FROM crm_profiles cp
JOIN crm_configurations crm on crm.id = cp.crm_configuration_id
JOIN users u on u.id = cp.user_id
JOIN teams t ON t.id = crm.team_id
WHERE crm.provider = 'salesforce' and t.status = 'active'
and cp.archived_at IS NULL and u.deleted_at IS NULL
and t.id NOT IN (1093)
and t.id = 2
and cp.contact_fields IS NULL;
# and c.crm_provider_id = '003Uu00000ojD4NIAU';
SELECT * FROM users WHERE id = 26484;
SELECT * FROM crm_profiles WHERE user_id = 26484;
SELECT * FROM social_accounts WHERE sociable_id = 26484;
SELECT * FROM crm_configurations where provider = 'salesforce';
select * from users where id IN (10022, 10403);
select * from users where team_id IN (526);
select * from teams where id IN (526, 532);
select * from crm_configurations where id IN (500, 516);
select * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);
select * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 526 and sa.provider = 'salesforce';
select * from team_settings where team_id IN (526, 532);
select * from users where id IN (22824);
select * from crm_profiles where crm_configuration_id IN (1026);
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1093 and sa.provider = 'salesforce';
select * from teams where id = 1099;
select * from users where id = 29643
select * from activity_processing_states;
SELECT * FROM teams where name LIKE '%Fare%'; # 233
SELECT * FROM opportunities where crm_configuration_id = 215
# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'
;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1088 and sa.provider = 'hubspot';
SELECT * FROM teams order by updated_at DESC
SELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account
select * from crm_configurations where provider = 'pipedrive';
select * from teams where id = 957;
select * from crm_configurations where id = 957;
SELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743
SELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;
select * from users where team_id = 1; # 26726 - Gabriela Dureva
SELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific
select * from activities where user_id = 26726 order by id desc;
select * from contacts where crm_configuration_id = 1
and email IN ('[EMAIL]', '[EMAIL]'); # 2094416, 2093620
SELECT * FROM contacts WHERE id = 6284931;
SELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id
WHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;
select * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);
select * from crm_configurations where id = 1;
43801692-1aeb-32ce-acba-5b80a479701a
44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b
405975c0-b3d0-7aaa-821f-09d59cae6dd1
4caf848d-4bed-2299-b248-7788d41f9fca
49bedc3f-f196-eef3-89c3-dea6a3b4aa63
43420989-a09d-b8f8-9806-c8bbf7a02aac
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
SELECT * FROM activities WHERE id = 75461988;
SELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;
select * from contacts where id = 17900517;
select * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id
where crm.provider != 'salesforce';
select * from users where id = 21047;
SELECT * FROM crm_configurations WHERE id = 892;
SELECT * FROM teams WHERE id = 942;
select * from opportunities where team_id = 942 order by updated_at desc;
select * from contacts where team_id = 942 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 942 and sa.provider = 'hubspot';
SELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430
SELECT * FROM crm_configurations WHERE id = 1;
SELECT * FROM teams WHERE crm_id = 1;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
select id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1
SELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430
select * from teams where id = 852;
select * from groups where id = 2286;
select * from sidekick_settings where team_id = 852;
select * from default_activity_types where team_id = 852;
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1 AND u.deleted_at IS NULL
AND u.crm_required = 1
AND u.team_id = 1
ORDER BY u.team_id;
SELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (
18481
);
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1
AND u.deleted_at IS NULL
AND u.crm_required = 1
# AND u.team_id = 1
AND p.id IS NULL -- Move this condition to WHERE clause
ORDER BY u.team_id;
SELECT * FROM opportunities WHERE id = 20002609;
select * from teams where id = 1122; # Velatir, 29953 - [EMAIL]
select * from crm_configurations where id = 1060;
select * from crm_layouts where crm_configuration_id = 1060;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1122 and sa.provider = 'hubspot';
select * from opportunities where team_id = 1122 order by updated_at desc;
select * from crm_field_data where object_type = 'contact';
SELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 248 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS
SELECT * FROM users where id = 24115;
SELECT * FROM accounts where id = 4002896;
SELECT * FROM teams WHERE name LIKE '%adswerve%';
SELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN ("0069N000003GIQ9QAO","0061r000019yGP9AAM","0066900001S2KWlAAN","0066900001TDpj2AAD","0066900001b8uEwAAI","0069N000001rQi0QAE","006QF00000KD40mYAD","006QF00000LzpRJYAZ","0069N000002uomtQAA","0069N000002xlMLQAY","0066900001NV6ubAAD","0061r00001HJp45AAD","006QF00000uTlUoYAK","006QF00000v0bZqYAI");
SELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203
SELECT u.id, u.email, ac.name, a.* FROM activities a
JOIN users u ON a.user_id = u.id
JOIN accounts ac ON a.account_id = ac.id
WHERE
uuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or
uuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or
uuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;
select * from users where id = 5825;
SELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;
select * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;
19594, 862
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 862 and sa.provider = 'salesforce';
select * from automated_reports where id = 36;
select ar.frequency, r.*, ar.* from automated_report_results r
join automated_reports ar on r.report_id = ar.id
where ar.frequency != 'one_off';
select s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;
select * from nudges n where n.activity_search_id
select * from teams where created_at > '2026-03-09';
SELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;
select * from users where team_id = 1 and name like '%Lukas%'; # 7160
SELECT * FROM teams WHERE id = 575;
select * from opportunities where team_id = 575;
SELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,
select * from opportunities where team_id = 1126;
SELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,
select * from opportunities where team_id = 1125;
select * from contacts c
where c.team_id = 882;
SELECT * FROM activities WHERE id = 76822967;
SELECT * FROM crm_profiles WHERE user_id = 15440;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 555;
SELECT * FROM crm_configurations WHERE id = 555;
SELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 581 and sa.provider = 'salesforce';
SELECT * FROM automated_report_results order by id desc;
select * from features;
select * from team_features where feature_id = 40;
select * from teams where id = 556;
select * from automated_reports;
where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , ["pdf","podcast"]
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
select * from automated_report_results order by id desc;
SELECT * FROM automated_report_results WHERE id = 1919;
select * from automated_report_results WHERE report_id = 54;
select * from opportunities where id = 7594349;
SELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - [EMAIL]
select * from playbooks where team_id = 711; # event 226147
SELECT * FROM playbook_categories WHERE playbook_id = 5515;
SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';
SELECT * FROM crm_fields WHERE id = 226147;
SELECT * FROM crm_field_values WHERE crm_field_id = 226147;
SELECT * FROM crm_configurations WHERE id = 692;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 711 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;
select * from leads;
select * from calendars;
SELECT
t.id AS team_id,
t.name,
LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain
FROM teams t
JOIN users u ON u.team_id = t.id
JOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'
LEFT JOIN team_domains td
ON td.team_id = t.id
AND td.deleted_at IS NULL
AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))
GROUP BY t.id, t.name, calendar_domain
ORDER BY t.name, calendar_domain;
select * from users u join calendars c on c.user_id = u.id
where u.team_id = 882;
select * from activities where id = 74049485; # team 563 crm 537
select * from activities where id = 73272382; # team 563 crm 537
select * from activities where id = 64400389; # team 563 crm 537
select * from activities where id = 58081273; # team 563 crm 537
select * from activities where id = 54520297; # team 563 crm 537
select * from participants where activity_id = 58081273;
select * from activities where crm_configuration_id = 537 and provider = 'aircall'
and account_id = 19003658 order by updated_at desc;
select * from contacts where crm_configuration_id = 537 and id = 35957759;
select * from accounts where crm_configuration_id = 537 and id = 19003658;
select * from automated_report_results where id = 1976;
select * from automated_reports where id = 583;
select * from activity_searches where id = 87714;
select * from activity_search_filters where activity_search_id = 87714;
SELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid
or uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;
SELECT * FROM crm_configurations WHERE provider = 'hubspot';
select * from rate_limits;
select * from automated_report_results where media_type = 'pdf' and status = 2
and id IN (18, 1872);
select * from automated_reports where id = 54;
SELECT * FROM users WHERE id IN (24623,29443,29613);
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app, folder
.circleci, folder
.cursor, folder
.github
.sonarlint, folder
.vscode, folder
.windsurf, folder
app, sources root
Actions
InviteUserToTeamAction.php, class
MarkUserAsOnboardableAction.php, class
SyncRecordingFlagsAction.php, class
UpdateTeamMemberAction.php, class
UpdateUserRolesAction.php, class
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
32906
|
1256
|
20
|
2026-05-13T09:45:06.184202+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-13/1778 /Users/lukas/.screenpipe/data/data/2026-05-13/1778665506184_m1.jpg...
|
PhpStorm
|
faVsco.js – UserInvitationDTO.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
4
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\DTO\Invitation;
use Jiminny\DTO\UserEmail;
use Jiminny\Http\Requests\Settings\Teams\CreateInvitationRequest;
use Jiminny\Http\Requests\Settings\Teams\CreateTeamRequest;
use Jiminny\Http\Requests\Settings\Teams\EditTeamRequest;
use Jiminny\Models\Group;
use Jiminny\Models\Invitation;
use Jiminny\Models\Role;
use Jiminny\Models\Team;
use Jiminny\Models\User;
class UserInvitationDTO
{
use UserEmail;
public string $email;
public ?string $secondaryEmail;
public ?int $groupId;
public int $teamId;
public bool $crmRequired;
public array $roleIds;
public bool $isOwner;
public ?User $currentUser = null;
/**
* @param array{
* email: string,
* secondaryEmail: string|null,
* groupId: int|null,
* teamId: int|string,
* crmRequired: bool,
* roleIds: int[],
* isOwner: bool,
* user?: User
* } $attributes
*/
private function __construct(array $attributes)
{
$this->email = mb_strtolower($attributes['email']);
$this->secondaryEmail = $this->normalizeNullable($attributes['secondaryEmail']);
$this->groupId = $attributes['groupId'];
$this->teamId = (int) $attributes['teamId'];
$this->crmRequired = (bool) $attributes['crmRequired'];
$this->roleIds = $attributes['roleIds'];
$this->isOwner = $attributes['isOwner'];
$this->currentUser = $attributes['user'] ?? null;
}
public static function forOwner(CreateTeamRequest|EditTeamRequest $request, Team $team): self
{
$roleIds = Role::whereIn('name', [
User::ROLE_ADMIN,
User::ROLE_RECORDER,
])->pluck('id')->toArray();
/** @var User $currentUser */
$currentUser = $request->user();
return new self([
'email' => $request->getOwnerEmail(),
'secondaryEmail' => null,
'groupId' => null,
'teamId' => $team->getId(),
'crmRequired' => true,
'roleIds' => $roleIds,
'user' => $currentUser,
'isOwner' => true,
]);
}
public static function fromRequest(CreateInvitationRequest $request): self
{
$data = $request->validated();
$groupId = isset($data['group_id']) ? Group::uuid($request->input('group_id'))->getId() : null;
$teamId = Team::uuid($data['team_id'])->getId();
/** @var User $currentUser */
$currentUser = $request->user();
return new self([
'email' => mb_strtolower($data['email']),
'secondaryEmail' => $data['secondary_email'] ?? null,
'groupId' => $groupId,
'teamId' => $teamId,
'crmRequired' => $data['crm_required'],
'roleIds' => $data['roles'],
'user' => $currentUser,
'isOwner' => false,
]);
}
public static function fromInvitation(Invitation $invitation, User $currentUser): self
{
$roles = $invitation->roles()->get();
$isOwner = $invitation->isOwner();
return new self([
'email' => $invitation->email,
'secondaryEmail' => $invitation->getSecondaryEmail(),
'groupId' => $invitation->group_id,
'teamId' => $invitation->team_id,
'crmRequired' => $invitation->crm_required,
'roleIds' => $roles->pluck('id')->toArray(),
'user' => $currentUser,
'isOwner' => $isOwner,
]);
}
}
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
40
1
40
64
Previous Highlighted Error
Next Highlighted Error
SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993
SELECT * FROM users WHERE id = 25061;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 994;
SELECT * FROM crm_profiles WHERE user_id = 25061;
select * from crm_configurations where id = 834;
SELECT * FROM teams WHERE id = 882;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;
SELECT * FROM contacts where crm_configuration_id = 834;
SELECT * FROM opportunities WHERE team_id = 933
# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');
AND id IN (8482561,18352941,19042734,19232139,19445140,19472541);
SELECT * FROM opportunity_contacts
WHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 485; #
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
select crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id
where crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')
# and l.converted_at IS NOT NULL
;
# [PASSWORD_DOTS]
SELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')
and opportunity_id IS NULL
order by id desc;
SELECT * FROM teams WHERE id = 604; # 598
SELECT * FROM activities WHERE id = 74410828; # [EMAIL]
SELECT * FROM accounts WHERE id = 20068382;
SELECT * FROM accounts WHERE id = 35186038;
SELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 559 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;
select * from sidekick_settings where team_id = 781;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100
SELECT * FROM crm_layouts WHERE crm_configuration_id = 711;
SELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL
and is_internal = 0 and status = 'completed'
order by id desc;
SELECT * FROM crm_layout_entities
WHERE crm_layout_id IN (2352, 2353);
;
SELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 556 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;
SELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;
select * from contacts
where crm_configuration_id = 530
and crm_provider_id = 872252;
select * from activities where crm_configuration_id = 530
and user_id = 14343 and type like '%softphone%'
and created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);
SELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t
JOIN crm_configurations c ON t.id = c.team_id
WHERE t.status = 'active';
SELECT * FROM teams where id = 1091;
SELECT * FROM crm_configurations where team_id = 1091;
SELECT * FROM activity_providers where team_id = 1091;
SELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT * FROM teams WHERE name LIKE '%Leadventure%';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1091 and sa.provider = 'salesforce';
SELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812
SELECT * FROM teams where id = 862;
SELECT * FROM crm_configurations where team_id = 862;
SELECT * FROM activity_providers where team_id = 862;
SELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT t.id, crm.id, crm.provider, ap.* FROM teams t
join crm_configurations crm on t.id = crm.team_id
join activity_providers ap on t.id = ap.team_id
where t.status = 'active' and ap.is_enabled = 1
and crm.provider = 'hubspot'
and ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',
'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');
SELECT * FROM teams where id = 1068;
SELECT * FROM crm_configurations where team_id = 1068;
SELECT * FROM activity_providers where team_id = 1068;
SELECT * FROM activities a
where crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')
and a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'
)
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by a.id desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1068 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262
SELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
select * from crm_layouts where crm_configuration_id = 834;
select * from crm_layout_entities where crm_layout_id = 2780;
select * from crm_fields where id IN (321153,321192,321193,321194);
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1057 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8
SELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20
SELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10
SELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #
SELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;
select * from users where team_id = 51; # 7783
SELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130
select * from activity_searches where user_id = 7783;
select * from activity_search_filters where activity_search_id IN (32291, 32292);
SELECT asf.activity_search_id, asf.id, asf.value
FROM activity_search_filters asf
WHERE asf.filter = 'group_id'
AND asf.value IN (
SELECT CONCAT(
HEX(SUBSTR(uuid, 5, 4)), '-',
HEX(SUBSTR(uuid, 3, 2)), '-',
HEX(SUBSTR(uuid, 1, 2)), '-',
HEX(SUBSTR(uuid, 9, 2)), '-',
HEX(SUBSTR(uuid, 11))
)
FROM groups
WHERE deleted_at IS NOT NULL
);
SELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where provider = 'hubspot';
SELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133
SELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null
# [PASSWORD_DOTS]
select * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';
select
cp.*
# DISTINCT t.id
# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields
FROM crm_profiles cp
JOIN crm_configurations crm on crm.id = cp.crm_configuration_id
JOIN users u on u.id = cp.user_id
JOIN teams t ON t.id = crm.team_id
WHERE crm.provider = 'salesforce' and t.status = 'active'
and cp.archived_at IS NULL and u.deleted_at IS NULL
and t.id NOT IN (1093)
and t.id = 2
and cp.contact_fields IS NULL;
# and c.crm_provider_id = '003Uu00000ojD4NIAU';
SELECT * FROM users WHERE id = 26484;
SELECT * FROM crm_profiles WHERE user_id = 26484;
SELECT * FROM social_accounts WHERE sociable_id = 26484;
SELECT * FROM crm_configurations where provider = 'salesforce';
select * from users where id IN (10022, 10403);
select * from users where team_id IN (526);
select * from teams where id IN (526, 532);
select * from crm_configurations where id IN (500, 516);
select * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);
select * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 526 and sa.provider = 'salesforce';
select * from team_settings where team_id IN (526, 532);
select * from users where id IN (22824);
select * from crm_profiles where crm_configuration_id IN (1026);
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1093 and sa.provider = 'salesforce';
select * from teams where id = 1099;
select * from users where id = 29643
select * from activity_processing_states;
SELECT * FROM teams where name LIKE '%Fare%'; # 233
SELECT * FROM opportunities where crm_configuration_id = 215
# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'
;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1088 and sa.provider = 'hubspot';
SELECT * FROM teams order by updated_at DESC
SELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account
select * from crm_configurations where provider = 'pipedrive';
select * from teams where id = 957;
select * from crm_configurations where id = 957;
SELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743
SELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;
select * from users where team_id = 1; # 26726 - Gabriela Dureva
SELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific
select * from activities where user_id = 26726 order by id desc;
select * from contacts where crm_configuration_id = 1
and email IN ('[EMAIL]', '[EMAIL]'); # 2094416, 2093620
SELECT * FROM contacts WHERE id = 6284931;
SELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id
WHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;
select * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);
select * from crm_configurations where id = 1;
43801692-1aeb-32ce-acba-5b80a479701a
44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b
405975c0-b3d0-7aaa-821f-09d59cae6dd1
4caf848d-4bed-2299-b248-7788d41f9fca
49bedc3f-f196-eef3-89c3-dea6a3b4aa63
43420989-a09d-b8f8-9806-c8bbf7a02aac
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
SELECT * FROM activities WHERE id = 75461988;
SELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;
select * from contacts where id = 17900517;
select * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id
where crm.provider != 'salesforce';
select * from users where id = 21047;
SELECT * FROM crm_configurations WHERE id = 892;
SELECT * FROM teams WHERE id = 942;
select * from opportunities where team_id = 942 order by updated_at desc;
select * from contacts where team_id = 942 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 942 and sa.provider = 'hubspot';
SELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430
SELECT * FROM crm_configurations WHERE id = 1;
SELECT * FROM teams WHERE crm_id = 1;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
select id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1
SELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430
select * from teams where id = 852;
select * from groups where id = 2286;
select * from sidekick_settings where team_id = 852;
select * from default_activity_types where team_id = 852;
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1 AND u.deleted_at IS NULL
AND u.crm_required = 1
AND u.team_id = 1
ORDER BY u.team_id;
SELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (
18481
);
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1
AND u.deleted_at IS NULL
AND u.crm_required = 1
# AND u.team_id = 1
AND p.id IS NULL -- Move this condition to WHERE clause
ORDER BY u.team_id;
SELECT * FROM opportunities WHERE id = 20002609;
select * from teams where id = 1122; # Velatir, 29953 - [EMAIL]
select * from crm_configurations where id = 1060;
select * from crm_layouts where crm_configuration_id = 1060;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1122 and sa.provider = 'hubspot';
select * from opportunities where team_id = 1122 order by updated_at desc;
select * from crm_field_data where object_type = 'contact';
SELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 248 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS
SELECT * FROM users where id = 24115;
SELECT * FROM accounts where id = 4002896;
SELECT * FROM teams WHERE name LIKE '%adswerve%';
SELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN ("0069N000003GIQ9QAO","0061r000019yGP9AAM","0066900001S2KWlAAN","0066900001TDpj2AAD","0066900001b8uEwAAI","0069N000001rQi0QAE","006QF00000KD40mYAD","006QF00000LzpRJYAZ","0069N000002uomtQAA","0069N000002xlMLQAY","0066900001NV6ubAAD","0061r00001HJp45AAD","006QF00000uTlUoYAK","006QF00000v0bZqYAI");
SELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203
SELECT u.id, u.email, ac.name, a.* FROM activities a
JOIN users u ON a.user_id = u.id
JOIN accounts ac ON a.account_id = ac.id
WHERE
uuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or
uuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or
uuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;
select * from users where id = 5825;
SELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;
select * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;
19594, 862
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 862 and sa.provider = 'salesforce';
select * from automated_reports where id = 36;
select ar.frequency, r.*, ar.* from automated_report_results r
join automated_reports ar on r.report_id = ar.id
where ar.frequency != 'one_off';
select s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;
select * from nudges n where n.activity_search_id
select * from teams where created_at > '2026-03-09';
SELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;
select * from users where team_id = 1 and name like '%Lukas%'; # 7160
SELECT * FROM teams WHERE id = 575;
select * from opportunities where team_id = 575;
SELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,
select * from opportunities where team_id = 1126;
SELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,
select * from opportunities where team_id = 1125;
select * from contacts c
where c.team_id = 882;
SELECT * FROM activities WHERE id = 76822967;
SELECT * FROM crm_profiles WHERE user_id = 15440;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 555;
SELECT * FROM crm_configurations WHERE id = 555;
SELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 581 and sa.provider = 'salesforce';
SELECT * FROM automated_report_results order by id desc;
select * from features;
select * from team_features where feature_id = 40;
select * from teams where id = 556;
select * from automated_reports;
where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , ["pdf","podcast"]
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
select * from automated_report_results order by id desc;
SELECT * FROM automated_report_results WHERE id = 1919;
select * from automated_report_results WHERE report_id = 54;
select * from opportunities where id = 7594349;
SELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - [EMAIL]
select * from playbooks where team_id = 711; # event 226147
SELECT * FROM playbook_categories WHERE playbook_id = 5515;
SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';
SELECT * FROM crm_fields WHERE id = 226147;
SELECT * FROM crm_field_values WHERE crm_field_id = 226147;
SELECT * FROM crm_configurations WHERE id = 692;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 711 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;
select * from leads;
select * from calendars;
SELECT
t.id AS team_id,
t.name,
LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain
FROM teams t
JOIN users u ON u.team_id = t.id
JOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'
LEFT JOIN team_domains td
ON td.team_id = t.id
AND td.deleted_at IS NULL
AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))
GROUP BY t.id, t.name, calendar_domain
ORDER BY t.name, calendar_domain;
select * from users u join calendars c on c.user_id = u.id
where u.team_id = 882;
select * from activities where id = 74049485; # team 563 crm 537
select * from activities where id = 73272382; # team 563 crm 537
select * from activities where id = 64400389; # team 563 crm 537
select * from activities where id = 58081273; # team 563 crm 537
select * from activities where id = 54520297; # team 563 crm 537
select * from participants where activity_id = 58081273;
select * from activities where crm_configuration_id = 537 and provider = 'aircall'
and account_id = 19003658 order by updated_at desc;
select * from contacts where crm_configuration_id = 537 and id = 35957759;
select * from accounts where crm_configuration_id = 537 and id = 19003658;
select * from automated_report_results where id = 1976;
select * from automated_reports where id = 583;
select * from activity_searches where id = 87714;
select * from activity_search_filters where activity_search_id = 87714;
SELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid
or uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;
SELECT * FROM crm_configurations WHERE provider = 'hubspot';
select * from rate_limits;
select * from automated_report_results where media_type = 'pdf' and status = 2
and id IN (18, 1872);
select * from automated_reports where id = 54;
SELECT * FROM users WHERE id IN (24623,29443,29613);
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app, folder
.circleci, folder
.cursor, folder
.github
.sonarlint, folder
.vscode, folder
.windsurf, folder
app, sources root
Actions
InviteUserToTeamAction.php, class
MarkUserAsOnboardableAction.php, class
SyncRecordingFlagsAction.php, class
UpdateTeamMemberAction.php, class
UpdateUserRolesAction.php, class
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags
FFMpeg
FileSystem
Gecko
Gong
GuzzleHttp
KeyPoints
Kiosk
LanguageDetection
LiveFeed
Locks
Math
MediaPipeline...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"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\\DTO\\Invitation;\n\nuse Jiminny\\DTO\\UserEmail;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\CreateInvitationRequest;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\CreateTeamRequest;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\EditTeamRequest;\nuse Jiminny\\Models\\Group;\nuse Jiminny\\Models\\Invitation;\nuse Jiminny\\Models\\Role;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\n\nclass UserInvitationDTO\n{\n use UserEmail;\n\n public string $email;\n public ?string $secondaryEmail;\n public ?int $groupId;\n public int $teamId;\n public bool $crmRequired;\n public array $roleIds;\n public bool $isOwner;\n public ?User $currentUser = null;\n\n /**\n * @param array{\n * email: string,\n * secondaryEmail: string|null,\n * groupId: int|null,\n * teamId: int|string,\n * crmRequired: bool,\n * roleIds: int[],\n * isOwner: bool,\n * user?: User\n * } $attributes\n */\n private function __construct(array $attributes)\n {\n $this->email = mb_strtolower($attributes['email']);\n $this->secondaryEmail = $this->normalizeNullable($attributes['secondaryEmail']);\n $this->groupId = $attributes['groupId'];\n $this->teamId = (int) $attributes['teamId'];\n $this->crmRequired = (bool) $attributes['crmRequired'];\n $this->roleIds = $attributes['roleIds'];\n $this->isOwner = $attributes['isOwner'];\n $this->currentUser = $attributes['user'] ?? null;\n }\n\n public static function forOwner(CreateTeamRequest|EditTeamRequest $request, Team $team): self\n {\n $roleIds = Role::whereIn('name', [\n User::ROLE_ADMIN,\n User::ROLE_RECORDER,\n ])->pluck('id')->toArray();\n\n /** @var User $currentUser */\n $currentUser = $request->user();\n\n return new self([\n 'email' => $request->getOwnerEmail(),\n 'secondaryEmail' => null,\n 'groupId' => null,\n 'teamId' => $team->getId(),\n 'crmRequired' => true,\n 'roleIds' => $roleIds,\n 'user' => $currentUser,\n 'isOwner' => true,\n ]);\n }\n\n public static function fromRequest(CreateInvitationRequest $request): self\n {\n $data = $request->validated();\n\n $groupId = isset($data['group_id']) ? Group::uuid($request->input('group_id'))->getId() : null;\n $teamId = Team::uuid($data['team_id'])->getId();\n\n /** @var User $currentUser */\n $currentUser = $request->user();\n\n return new self([\n 'email' => mb_strtolower($data['email']),\n 'secondaryEmail' => $data['secondary_email'] ?? null,\n 'groupId' => $groupId,\n 'teamId' => $teamId,\n 'crmRequired' => $data['crm_required'],\n 'roleIds' => $data['roles'],\n 'user' => $currentUser,\n 'isOwner' => false,\n ]);\n }\n\n public static function fromInvitation(Invitation $invitation, User $currentUser): self\n {\n $roles = $invitation->roles()->get();\n $isOwner = $invitation->isOwner();\n\n return new self([\n 'email' => $invitation->email,\n 'secondaryEmail' => $invitation->getSecondaryEmail(),\n 'groupId' => $invitation->group_id,\n 'teamId' => $invitation->team_id,\n 'crmRequired' => $invitation->crm_required,\n 'roleIds' => $roles->pluck('id')->toArray(),\n 'user' => $currentUser,\n 'isOwner' => $isOwner,\n ]);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\DTO\\Invitation;\n\nuse Jiminny\\DTO\\UserEmail;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\CreateInvitationRequest;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\CreateTeamRequest;\nuse Jiminny\\Http\\Requests\\Settings\\Teams\\EditTeamRequest;\nuse Jiminny\\Models\\Group;\nuse Jiminny\\Models\\Invitation;\nuse Jiminny\\Models\\Role;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\n\nclass UserInvitationDTO\n{\n use UserEmail;\n\n public string $email;\n public ?string $secondaryEmail;\n public ?int $groupId;\n public int $teamId;\n public bool $crmRequired;\n public array $roleIds;\n public bool $isOwner;\n public ?User $currentUser = null;\n\n /**\n * @param array{\n * email: string,\n * secondaryEmail: string|null,\n * groupId: int|null,\n * teamId: int|string,\n * crmRequired: bool,\n * roleIds: int[],\n * isOwner: bool,\n * user?: User\n * } $attributes\n */\n private function __construct(array $attributes)\n {\n $this->email = mb_strtolower($attributes['email']);\n $this->secondaryEmail = $this->normalizeNullable($attributes['secondaryEmail']);\n $this->groupId = $attributes['groupId'];\n $this->teamId = (int) $attributes['teamId'];\n $this->crmRequired = (bool) $attributes['crmRequired'];\n $this->roleIds = $attributes['roleIds'];\n $this->isOwner = $attributes['isOwner'];\n $this->currentUser = $attributes['user'] ?? null;\n }\n\n public static function forOwner(CreateTeamRequest|EditTeamRequest $request, Team $team): self\n {\n $roleIds = Role::whereIn('name', [\n User::ROLE_ADMIN,\n User::ROLE_RECORDER,\n ])->pluck('id')->toArray();\n\n /** @var User $currentUser */\n $currentUser = $request->user();\n\n return new self([\n 'email' => $request->getOwnerEmail(),\n 'secondaryEmail' => null,\n 'groupId' => null,\n 'teamId' => $team->getId(),\n 'crmRequired' => true,\n 'roleIds' => $roleIds,\n 'user' => $currentUser,\n 'isOwner' => true,\n ]);\n }\n\n public static function fromRequest(CreateInvitationRequest $request): self\n {\n $data = $request->validated();\n\n $groupId = isset($data['group_id']) ? Group::uuid($request->input('group_id'))->getId() : null;\n $teamId = Team::uuid($data['team_id'])->getId();\n\n /** @var User $currentUser */\n $currentUser = $request->user();\n\n return new self([\n 'email' => mb_strtolower($data['email']),\n 'secondaryEmail' => $data['secondary_email'] ?? null,\n 'groupId' => $groupId,\n 'teamId' => $teamId,\n 'crmRequired' => $data['crm_required'],\n 'roleIds' => $data['roles'],\n 'user' => $currentUser,\n 'isOwner' => false,\n ]);\n }\n\n public static function fromInvitation(Invitation $invitation, User $currentUser): self\n {\n $roles = $invitation->roles()->get();\n $isOwner = $invitation->isOwner();\n\n return new self([\n 'email' => $invitation->email,\n 'secondaryEmail' => $invitation->getSecondaryEmail(),\n 'groupId' => $invitation->group_id,\n 'teamId' => $invitation->team_id,\n 'crmRequired' => $invitation->crm_required,\n 'roleIds' => $roles->pluck('id')->toArray(),\n 'user' => $currentUser,\n 'isOwner' => $isOwner,\n ]);\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":"40","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"40","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"64","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","depth":4,"on_screen":true,"value":"SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993\nSELECT * FROM users WHERE id = 25061;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 994;\nSELECT * FROM crm_profiles WHERE user_id = 25061;\n\nselect * from crm_configurations where id = 834;\nSELECT * FROM teams WHERE id = 882;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;\n\nSELECT * FROM contacts where crm_configuration_id = 834;\nSELECT * FROM opportunities WHERE team_id = 933\n# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');\nAND id IN (8482561,18352941,19042734,19232139,19445140,19472541);\nSELECT * FROM opportunity_contacts\nWHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 485; #\nSELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\nselect crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id\nwhere crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')\n# and l.converted_at IS NOT NULL\n;\n\n# ********************************************************************\nSELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')\nand opportunity_id IS NULL\norder by id desc;\n\nSELECT * FROM teams WHERE id = 604; # 598\nSELECT * FROM activities WHERE id = 74410828; # chelseaw@allvoices.co\nSELECT * FROM accounts WHERE id = 20068382;\nSELECT * FROM accounts WHERE id = 35186038;\n\nSELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 559 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;\nselect * from sidekick_settings where team_id = 781;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100\n\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 711;\nSELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL\nand is_internal = 0 and status = 'completed'\norder by id desc;\n\nSELECT * FROM crm_layout_entities\nWHERE crm_layout_id IN (2352, 2353);\n;\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 556 and sa.provider = 'hubspot';\n\nSELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;\nSELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;\nselect * from contacts\nwhere crm_configuration_id = 530\nand crm_provider_id = 872252;\n\nselect * from activities where crm_configuration_id = 530\nand user_id = 14343 and type like '%softphone%'\nand created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';\n\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya\nSELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);\n\n\nSELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t\nJOIN crm_configurations c ON t.id = c.team_id\nWHERE t.status = 'active';\n\nSELECT * FROM teams where id = 1091;\nSELECT * FROM crm_configurations where team_id = 1091;\nSELECT * FROM activity_providers where team_id = 1091;\nSELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT * FROM teams WHERE name LIKE '%Leadventure%';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1091 and sa.provider = 'salesforce';\n\nSELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812\nSELECT * FROM teams where id = 862;\nSELECT * FROM crm_configurations where team_id = 862;\nSELECT * FROM activity_providers where team_id = 862;\nSELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')\nand provider NOT IN ('hubspot', 'aircall')\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by id desc;\n\n\nSELECT t.id, crm.id, crm.provider, ap.* FROM teams t\njoin crm_configurations crm on t.id = crm.team_id\njoin activity_providers ap on t.id = ap.team_id\nwhere t.status = 'active' and ap.is_enabled = 1\nand crm.provider = 'hubspot'\nand ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',\n 'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');\n\nSELECT * FROM teams where id = 1068;\nSELECT * FROM crm_configurations where team_id = 1068;\nSELECT * FROM activity_providers where team_id = 1068;\n\nSELECT * FROM activities a\nwhere crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')\nand a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'\n )\n# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'\norder by a.id desc;\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1068 and sa.provider = 'hubspot';\n\n# ********************************************************************\n# ********************************************************************\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 933 and sa.provider = 'hubspot';\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262\nSELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 882 and sa.provider = 'hubspot';\nselect * from crm_layouts where crm_configuration_id = 834;\nselect * from crm_layout_entities where crm_layout_id = 2780;\nselect * from crm_fields where id IN (321153,321192,321193,321194);\n\nSELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1057 and sa.provider = 'hubspot';\n\nSELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8\n\nSELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20\n\nSELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last\n\nSELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10\n\nSELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2\n\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;\n\nSELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th\n# ********************************************************************\nSELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #\n\nSELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;\nselect * from users where team_id = 51; # 7783\nSELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130\nselect * from activity_searches where user_id = 7783;\nselect * from activity_search_filters where activity_search_id IN (32291, 32292);\n\nSELECT asf.activity_search_id, asf.id, asf.value\nFROM activity_search_filters asf\nWHERE asf.filter = 'group_id'\nAND asf.value IN (\n SELECT CONCAT(\n HEX(SUBSTR(uuid, 5, 4)), '-',\n HEX(SUBSTR(uuid, 3, 2)), '-',\n HEX(SUBSTR(uuid, 1, 2)), '-',\n HEX(SUBSTR(uuid, 9, 2)), '-',\n HEX(SUBSTR(uuid, 11))\n )\n FROM groups\n WHERE deleted_at IS NOT NULL\n);\n\nSELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th\n# ********************************************************************\nSELECT * FROM crm_configurations where provider = 'hubspot';\nSELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133\nSELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;\nSELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null\n# ********************************************************************\n\nselect * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';\nselect\n cp.*\n# DISTINCT t.id\n# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields\nFROM crm_profiles cp\nJOIN crm_configurations crm on crm.id = cp.crm_configuration_id\nJOIN users u on u.id = cp.user_id\nJOIN teams t ON t.id = crm.team_id\nWHERE crm.provider = 'salesforce' and t.status = 'active'\n and cp.archived_at IS NULL and u.deleted_at IS NULL\n and t.id NOT IN (1093)\n and t.id = 2\n and cp.contact_fields IS NULL;\n# and c.crm_provider_id = '003Uu00000ojD4NIAU';\n\nSELECT * FROM users WHERE id = 26484;\nSELECT * FROM crm_profiles WHERE user_id = 26484;\nSELECT * FROM social_accounts WHERE sociable_id = 26484;\nSELECT * FROM crm_configurations where provider = 'salesforce';\nselect * from users where id IN (10022, 10403);\nselect * from users where team_id IN (526);\nselect * from teams where id IN (526, 532);\nselect * from crm_configurations where id IN (500, 516);\nselect * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);\nselect * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 526 and sa.provider = 'salesforce';\nselect * from team_settings where team_id IN (526, 532);\n\nselect * from users where id IN (22824);\nselect * from crm_profiles where crm_configuration_id IN (1026);\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1093 and sa.provider = 'salesforce';\n\nselect * from teams where id = 1099;\nselect * from users where id = 29643\n\nselect * from activity_processing_states;\n\nSELECT * FROM teams where name LIKE '%Fare%'; # 233\nSELECT * FROM opportunities where crm_configuration_id = 215\n# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'\n;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1088 and sa.provider = 'hubspot';\n\nSELECT * FROM teams order by updated_at DESC\nSELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account\n\nselect * from crm_configurations where provider = 'pipedrive';\n\nselect * from teams where id = 957;\nselect * from crm_configurations where id = 957;\n\nSELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743\nSELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;\n\nselect * from users where team_id = 1; # 26726 - Gabriela Dureva\nSELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific\nselect * from activities where user_id = 26726 order by id desc;\nselect * from contacts where crm_configuration_id = 1\nand email IN ('charlotte.ward@prolific.com', 'frankie.bryant@prolific.com'); # 2094416, 2093620\nSELECT * FROM contacts WHERE id = 6284931;\n\nSELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id\nWHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;\n\nselect * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);\nselect * from crm_configurations where id = 1;\n\n43801692-1aeb-32ce-acba-5b80a479701a\n44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b\n405975c0-b3d0-7aaa-821f-09d59cae6dd1\n4caf848d-4bed-2299-b248-7788d41f9fca\n49bedc3f-f196-eef3-89c3-dea6a3b4aa63\n43420989-a09d-b8f8-9806-c8bbf7a02aac\n\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nSELECT * FROM activities WHERE id = 75461988;\n\nSELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;\n\nselect * from contacts where id = 17900517;\n\nselect * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id\nwhere crm.provider != 'salesforce';\n\nselect * from users where id = 21047;\nSELECT * FROM crm_configurations WHERE id = 892;\nSELECT * FROM teams WHERE id = 942;\nselect * from opportunities where team_id = 942 order by updated_at desc;\nselect * from contacts where team_id = 942 order by updated_at desc;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 942 and sa.provider = 'hubspot';\n\nSELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430\nSELECT * FROM crm_configurations WHERE id = 1;\nSELECT * FROM teams WHERE crm_id = 1;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1 and sa.provider = 'salesforce';\n\nselect id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1\nSELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430\n\nselect * from teams where id = 852;\nselect * from groups where id = 2286;\nselect * from sidekick_settings where team_id = 852;\nselect * from default_activity_types where team_id = 852;\n\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1 AND u.deleted_at IS NULL\nAND u.crm_required = 1\nAND u.team_id = 1\nORDER BY u.team_id;\n\nSELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (\n18481\n );\n\nSELECT cc.provider, cc.id, p.id, u.*\nFROM users u\nLEFT JOIN crm_profiles p ON u.id = p.user_id\nINNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'\nINNER JOIN crm_configurations cc ON t.crm_id = cc.id\nWHERE u.status = 1\n AND u.deleted_at IS NULL\n AND u.crm_required = 1\n# AND u.team_id = 1\n AND p.id IS NULL -- Move this condition to WHERE clause\nORDER BY u.team_id;\n\nSELECT * FROM opportunities WHERE id = 20002609;\nselect * from teams where id = 1122; # Velatir, 29953 - christian@velatir.com\nselect * from crm_configurations where id = 1060;\nselect * from crm_layouts where crm_configuration_id = 1060;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 1122 and sa.provider = 'hubspot';\nselect * from opportunities where team_id = 1122 order by updated_at desc;\n\nselect * from crm_field_data where object_type = 'contact';\n\nSELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 248 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS\nSELECT * FROM users where id = 24115;\nSELECT * FROM accounts where id = 4002896;\nSELECT * FROM teams WHERE name LIKE '%adswerve%';\nSELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN (\"0069N000003GIQ9QAO\",\"0061r000019yGP9AAM\",\"0066900001S2KWlAAN\",\"0066900001TDpj2AAD\",\"0066900001b8uEwAAI\",\"0069N000001rQi0QAE\",\"006QF00000KD40mYAD\",\"006QF00000LzpRJYAZ\",\"0069N000002uomtQAA\",\"0069N000002xlMLQAY\",\"0066900001NV6ubAAD\",\"0061r00001HJp45AAD\",\"006QF00000uTlUoYAK\",\"006QF00000v0bZqYAI\");\nSELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203\n\nSELECT u.id, u.email, ac.name, a.* FROM activities a\nJOIN users u ON a.user_id = u.id\nJOIN accounts ac ON a.account_id = ac.id\nWHERE\nuuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or\nuuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or\nuuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;\n\nselect * from users where id = 5825;\nSELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;\n\nselect * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;\n19594, 862\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 862 and sa.provider = 'salesforce';\n\nselect * from automated_reports where id = 36;\nselect ar.frequency, r.*, ar.* from automated_report_results r\njoin automated_reports ar on r.report_id = ar.id\nwhere ar.frequency != 'one_off';\n\nselect s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;\nselect * from nudges n where n.activity_search_id\n\nselect * from teams where created_at > '2026-03-09';\nSELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;\n\nselect * from users where team_id = 1 and name like '%Lukas%'; # 7160\n\nSELECT * FROM teams WHERE id = 575;\nselect * from opportunities where team_id = 575;\nSELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,\nselect * from opportunities where team_id = 1126;\nSELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,\nselect * from opportunities where team_id = 1125;\nselect * from contacts c\nwhere c.team_id = 882;\n\nSELECT * FROM activities WHERE id = 76822967;\nSELECT * FROM crm_profiles WHERE user_id = 15440;\nSELECT * FROM crm_profiles WHERE crm_configuration_id = 555;\nSELECT * FROM crm_configurations WHERE id = 555;\nSELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 581 and sa.provider = 'salesforce';\n\nSELECT * FROM automated_report_results order by id desc;\n\nselect * from features;\nselect * from team_features where feature_id = 40;\n\nselect * from teams where id = 556;\n\nselect * from automated_reports;\nwhere id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , [\"pdf\",\"podcast\"]\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;\nselect * from automated_report_results order by id desc;\nSELECT * FROM automated_report_results WHERE id = 1919;\n\nselect * from automated_report_results WHERE report_id = 54;\n\nselect * from opportunities where id = 7594349;\n\nSELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - jiminnyintegration@lesmills.com\nselect * from playbooks where team_id = 711; # event 226147\nSELECT * FROM playbook_categories WHERE playbook_id = 5515;\nSELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';\nSELECT * FROM crm_fields WHERE id = 226147;\nSELECT * FROM crm_field_values WHERE crm_field_id = 226147;\n\nSELECT * FROM crm_configurations WHERE id = 692;\nSELECT\n CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,\n u.email,\n sa.*,\n t.owner_id FROM social_accounts sa\nJOIN users u on u.id = sa.sociable_id\nJOIN teams t on t.id = u.team_id\nWHERE u.team_id = 711 and sa.provider = 'salesforce';\n\nSELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;\n\nselect * from leads;\n\nselect * from calendars;\n\nSELECT\n t.id AS team_id,\n t.name,\n LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain\nFROM teams t\nJOIN users u ON u.team_id = t.id\nJOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'\nLEFT JOIN team_domains td\n ON td.team_id = t.id\n AND td.deleted_at IS NULL\n AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))\nGROUP BY t.id, t.name, calendar_domain\nORDER BY t.name, calendar_domain;\n\nselect * from users u join calendars c on c.user_id = u.id\nwhere u.team_id = 882;\n\n\nselect * from activities where id = 74049485; # team 563 crm 537\nselect * from activities where id = 73272382; # team 563 crm 537\nselect * from activities where id = 64400389; # team 563 crm 537\nselect * from activities where id = 58081273; # team 563 crm 537\nselect * from activities where id = 54520297; # team 563 crm 537\nselect * from participants where activity_id = 58081273;\n\nselect * from activities where crm_configuration_id = 537 and provider = 'aircall'\nand account_id = 19003658 order by updated_at desc;\n\nselect * from contacts where crm_configuration_id = 537 and id = 35957759;\nselect * from accounts where crm_configuration_id = 537 and id = 19003658;\n\nselect * from automated_report_results where id = 1976;\nselect * from automated_reports where id = 583;\nselect * from activity_searches where id = 87714;\nselect * from activity_search_filters where activity_search_id = 87714;\n\nSELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid\nor uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;\n\nSELECT * FROM crm_configurations WHERE provider = 'hubspot';\nselect * from rate_limits;\n\nselect * from automated_report_results where media_type = 'pdf' and status = 2\nand id IN (18, 1872);\nselect * from automated_reports where id = 54;\nSELECT * FROM users WHERE id IN (24623,29443,29613);\n\nSELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app, 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":".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","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"InviteUserToTeamAction.php, class","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MarkUserAsOnboardableAction.php, class","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncRecordingFlagsAction.php, class","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"UpdateTeamMemberAction.php, class","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"UpdateUserRolesAction.php, class","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dtos","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Events","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Country","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Database","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Datadog","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DateTime","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encoding","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encryption","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ES","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Faker","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlags","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FFMpeg","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FileSystem","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gecko","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gong","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GuzzleHttp","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"KeyPoints","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Kiosk","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LanguageDetection","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LiveFeed","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Locks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Math","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MediaPipeline","depth":9,"on_screen":false,"role_description":"text"}]...
|
-4446460660996976698
|
1065696262820869709
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
4
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\DTO\Invitation;
use Jiminny\DTO\UserEmail;
use Jiminny\Http\Requests\Settings\Teams\CreateInvitationRequest;
use Jiminny\Http\Requests\Settings\Teams\CreateTeamRequest;
use Jiminny\Http\Requests\Settings\Teams\EditTeamRequest;
use Jiminny\Models\Group;
use Jiminny\Models\Invitation;
use Jiminny\Models\Role;
use Jiminny\Models\Team;
use Jiminny\Models\User;
class UserInvitationDTO
{
use UserEmail;
public string $email;
public ?string $secondaryEmail;
public ?int $groupId;
public int $teamId;
public bool $crmRequired;
public array $roleIds;
public bool $isOwner;
public ?User $currentUser = null;
/**
* @param array{
* email: string,
* secondaryEmail: string|null,
* groupId: int|null,
* teamId: int|string,
* crmRequired: bool,
* roleIds: int[],
* isOwner: bool,
* user?: User
* } $attributes
*/
private function __construct(array $attributes)
{
$this->email = mb_strtolower($attributes['email']);
$this->secondaryEmail = $this->normalizeNullable($attributes['secondaryEmail']);
$this->groupId = $attributes['groupId'];
$this->teamId = (int) $attributes['teamId'];
$this->crmRequired = (bool) $attributes['crmRequired'];
$this->roleIds = $attributes['roleIds'];
$this->isOwner = $attributes['isOwner'];
$this->currentUser = $attributes['user'] ?? null;
}
public static function forOwner(CreateTeamRequest|EditTeamRequest $request, Team $team): self
{
$roleIds = Role::whereIn('name', [
User::ROLE_ADMIN,
User::ROLE_RECORDER,
])->pluck('id')->toArray();
/** @var User $currentUser */
$currentUser = $request->user();
return new self([
'email' => $request->getOwnerEmail(),
'secondaryEmail' => null,
'groupId' => null,
'teamId' => $team->getId(),
'crmRequired' => true,
'roleIds' => $roleIds,
'user' => $currentUser,
'isOwner' => true,
]);
}
public static function fromRequest(CreateInvitationRequest $request): self
{
$data = $request->validated();
$groupId = isset($data['group_id']) ? Group::uuid($request->input('group_id'))->getId() : null;
$teamId = Team::uuid($data['team_id'])->getId();
/** @var User $currentUser */
$currentUser = $request->user();
return new self([
'email' => mb_strtolower($data['email']),
'secondaryEmail' => $data['secondary_email'] ?? null,
'groupId' => $groupId,
'teamId' => $teamId,
'crmRequired' => $data['crm_required'],
'roleIds' => $data['roles'],
'user' => $currentUser,
'isOwner' => false,
]);
}
public static function fromInvitation(Invitation $invitation, User $currentUser): self
{
$roles = $invitation->roles()->get();
$isOwner = $invitation->isOwner();
return new self([
'email' => $invitation->email,
'secondaryEmail' => $invitation->getSecondaryEmail(),
'groupId' => $invitation->group_id,
'teamId' => $invitation->team_id,
'crmRequired' => $invitation->crm_required,
'roleIds' => $roles->pluck('id')->toArray(),
'user' => $currentUser,
'isOwner' => $isOwner,
]);
}
}
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
40
1
40
64
Previous Highlighted Error
Next Highlighted Error
SELECT * FROM teams WHERE name LIKE '%litify%'; # 1069, 994, 24993
SELECT * FROM users WHERE id = 25061;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 994;
SELECT * FROM crm_profiles WHERE user_id = 25061;
select * from crm_configurations where id = 834;
SELECT * FROM teams WHERE id = 882;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations WHERE provider = 'hubspot' and crm_provider_id = 7270388;
SELECT * FROM contacts where crm_configuration_id = 834;
SELECT * FROM opportunities WHERE team_id = 933
# AND crm_provider_id IN ('20131586060','46017317898','52543911090','53451356564','54101251892','54323768459');
AND id IN (8482561,18352941,19042734,19232139,19445140,19472541);
SELECT * FROM opportunity_contacts
WHERE opportunity_id IN (8482561,18352941,19042734,19232139,19445140,19472541);
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 485; #
SELECT * FROM opportunities WHERE team_id = 933 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
select crm.provider, l.* from leads l join crm_configurations crm on l.crm_configuration_id = crm.id
where crm.provider NOT IN ('salesforce', 'integration-app', 'bullhorn', 'copper')
# and l.converted_at IS NOT NULL
;
# [PASSWORD_DOTS]
SELECT * FROM activities a WHERE type IN ('email-inbound', 'email-outbound')
and opportunity_id IS NULL
order by id desc;
SELECT * FROM teams WHERE id = 604; # 598
SELECT * FROM activities WHERE id = 74410828; # [EMAIL]
SELECT * FROM accounts WHERE id = 20068382;
SELECT * FROM accounts WHERE id = 35186038;
SELECT * FROM contacts WHERE team_id = 852 and updated_at > '2026-01-23 12:30:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 559 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('cb6342b6-a183-401c-b0af-ede92b2ae763') = uuid;
select * from sidekick_settings where team_id = 781;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 26651871; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 7562435;
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8420347; # opflit 2100
SELECT * FROM crm_layouts WHERE crm_configuration_id = 711;
SELECT * FROM activities where crm_configuration_id = 711 and crm_provider_id IS NULL
and is_internal = 0 and status = 'completed'
order by id desc;
SELECT * FROM crm_layout_entities
WHERE crm_layout_id IN (2352, 2353);
;
SELECT * FROM crm_configurations where provider = 'hubspot' and id = 530;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 556 and sa.provider = 'hubspot';
SELECT * FROM activities WHERE uuid_to_bin('c6ca4b22-7738-4563-a95d-b8a9598924ae') = uuid;
SELECT * FROM activities WHERE uuid_to_bin('442abb2b-28bd-4be8-9c25-19e9bf02766d') = uuid;
select * from contacts
where crm_configuration_id = 530
and crm_provider_id = 872252;
select * from activities where crm_configuration_id = 530
and user_id = 14343 and type like '%softphone%'
and created_at between '2026-01-28 15:00:00' and '2026-01-28 15:10:00';
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 25666868; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id = 8646335; # Teya
SELECT * FROM crm_configurations where provider = 'hubspot' and crm_provider_id IN (5933397);
SELECT t.name, t.id, t.owner_id, c.id, c.provider, c.crm_base_url FROM teams t
JOIN crm_configurations c ON t.id = c.team_id
WHERE t.status = 'active';
SELECT * FROM teams where id = 1091;
SELECT * FROM crm_configurations where team_id = 1091;
SELECT * FROM activity_providers where team_id = 1091;
SELECT * FROM activities where crm_configuration_id = 1024 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT * FROM teams WHERE name LIKE '%Leadventure%';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1091 and sa.provider = 'salesforce';
SELECT * FROM teams WHERE name LIKE '%Wilson%'; # 862, 812
SELECT * FROM teams where id = 862;
SELECT * FROM crm_configurations where team_id = 862;
SELECT * FROM activity_providers where team_id = 862;
SELECT * FROM activities where crm_configuration_id = 812 and type IN ('softphone', 'softphone-outbound')
and provider NOT IN ('hubspot', 'aircall')
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by id desc;
SELECT t.id, crm.id, crm.provider, ap.* FROM teams t
join crm_configurations crm on t.id = crm.team_id
join activity_providers ap on t.id = ap.team_id
where t.status = 'active' and ap.is_enabled = 1
and crm.provider = 'hubspot'
and ap.provider NOT IN ('hubspot', 'aircall', 'uploader', 'gong', 'twilio', 'zoom-bot', 'google-meet', 'ms-teams',
'outreach', 'close', 'ringcentral', 'dialpad', 'zoom-phone');
SELECT * FROM teams where id = 1068;
SELECT * FROM crm_configurations where team_id = 1068;
SELECT * FROM activity_providers where team_id = 1068;
SELECT * FROM activities a
where crm_configuration_id = 993 and type IN ('softphone', 'softphone-outbound')
and a.provider NOT IN ('hubspot', 'uploader', 'gong', 'twilio', 'google-meet', 'ms-teams','close'
)
# and telephony_provider_id = '019c1131-a22f-4792-b9ea-20adf6a02ed0'
order by a.id desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1068 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 882; # 933 - GoGlobal , portalId: 6017093
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 933 and updated_at > '2026-02-06 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 933 and sa.provider = 'hubspot';
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 834; # 882 - AnyVan , portalId: 5468262
SELECT * FROM contacts WHERE crm_configuration_id = 834 and updated_at > '2026-03-30 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and updated_at > '2026-03-04 08:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 882 and sa.provider = 'hubspot';
select * from crm_layouts where crm_configuration_id = 834;
select * from crm_layout_entities where crm_layout_id = 2780;
select * from crm_fields where id IN (321153,321192,321193,321194);
SELECT * FROM opportunities WHERE crm_configuration_id = 834 and id = 10993426;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 988; # 1057 - Teya (543ce4f4-168c-4571-91ea-5b35c253f06f) , portalId: 26651871
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1057 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1057 and sa.provider = 'hubspot';
SELECT * FROM crm_configurations where id = 533; # 559 - Connectd , portalId: 6710988
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 559 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 801; # 852 - Rise Vision , portalId: 2700250
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 852 and updated_at > '2026-02-04 00:00:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 962; # 1034 - evergrowth.io , portalId: 143180990
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1034 and updated_at > '2026-02-04 00:00:00' order by updated_at desc;
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 1037; # 1102 - Jibble , portalId: 6649755
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1102 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 8
SELECT * FROM crm_configurations where id = 1015; # 1049 - Travefy , portalId: 48904401
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1049 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 20
SELECT * FROM crm_configurations where id = 64; # 70 - SalaryFinance , portalId: 3404115
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 70 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 6th last
SELECT * FROM crm_configurations where id = 802; # 853 - Street Group , portalId: 7658438
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 853 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 10
SELECT * FROM crm_configurations where id = 872; # 921 - In Professional Development , portalId: 9238273
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 921 and updated_at > '2026-02-04 12:30:00' order by updated_at desc; # 2
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 550; # 576 - SeedLegals , portalId: 3028661
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 576 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 989; # 1058 - rtaoutdoor.com , portalId: 22371204
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1058 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 896; # 946 - Mintago , portalId: 6621281
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 946 and updated_at > '2026-02-05 14:00:00' order by updated_at desc;
SELECT * FROM crm_configurations where id = 617; # 641 - PCS , portalId: 5244937
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 641 and updated_at > '2026-02-05 14:00:00' order by updated_at desc; # 7th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where id = 649; # 670 - Eventeny , portalId: 4492849
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-18 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 670 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; #
SELECT * FROM crm_configurations where id = 48; # 51 - CleanCloud , portalId: 4373137
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-03-04 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 51 and updated_at > '2026-02-09 08:00:00' order by updated_at desc;
select * from users where team_id = 51; # 7783
SELECT * FROM groups WHERE uuid_to_bin('8a8d2cb6-8b55-4fa3-8b5c-5f0e3d8de59a') = uuid; # 1130
select * from activity_searches where user_id = 7783;
select * from activity_search_filters where activity_search_id IN (32291, 32292);
SELECT asf.activity_search_id, asf.id, asf.value
FROM activity_search_filters asf
WHERE asf.filter = 'group_id'
AND asf.value IN (
SELECT CONCAT(
HEX(SUBSTR(uuid, 5, 4)), '-',
HEX(SUBSTR(uuid, 3, 2)), '-',
HEX(SUBSTR(uuid, 1, 2)), '-',
HEX(SUBSTR(uuid, 9, 2)), '-',
HEX(SUBSTR(uuid, 11))
)
FROM groups
WHERE deleted_at IS NOT NULL
);
SELECT * FROM crm_configurations where id = 272; # 290 - Bonham & Brook , portalId: 5705856
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-05 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 290 and updated_at > '2026-02-09 08:00:00' order by updated_at desc; # 6th
# [PASSWORD_DOTS]
SELECT * FROM crm_configurations where provider = 'hubspot';
SELECT * FROM crm_configurations where id = 1056; # 1119 - Chromatic , portalId: 45602133
SELECT * FROM opportunities WHERE team_id = 1119 and remotely_created_at > '2026-02-01 00:00:00' order by updated_at desc;
SELECT * FROM opportunities WHERE team_id = 1119 and updated_at > '2026-02-09 09:00:00' order by updated_at desc; # null
# [PASSWORD_DOTS]
select * from contacts where crm_provider_id = '003Uu00000ojD4NIAU';
select
cp.*
# DISTINCT t.id
# cp.id, cp.user_id, t.id, cp.crm_configuration_id, cp.contact_fields
FROM crm_profiles cp
JOIN crm_configurations crm on crm.id = cp.crm_configuration_id
JOIN users u on u.id = cp.user_id
JOIN teams t ON t.id = crm.team_id
WHERE crm.provider = 'salesforce' and t.status = 'active'
and cp.archived_at IS NULL and u.deleted_at IS NULL
and t.id NOT IN (1093)
and t.id = 2
and cp.contact_fields IS NULL;
# and c.crm_provider_id = '003Uu00000ojD4NIAU';
SELECT * FROM users WHERE id = 26484;
SELECT * FROM crm_profiles WHERE user_id = 26484;
SELECT * FROM social_accounts WHERE sociable_id = 26484;
SELECT * FROM crm_configurations where provider = 'salesforce';
select * from users where id IN (10022, 10403);
select * from users where team_id IN (526);
select * from teams where id IN (526, 532);
select * from crm_configurations where id IN (500, 516);
select * from crm_profiles where crm_configuration_id IN (500, 516) and user_id IN (10022, 10403);
select * from contacts where crm_configuration_id IN (500, 516) and crm_provider_id = '003Uu00000ojD4NIAU';
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 526 and sa.provider = 'salesforce';
select * from team_settings where team_id IN (526, 532);
select * from users where id IN (22824);
select * from crm_profiles where crm_configuration_id IN (1026);
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1093 and sa.provider = 'salesforce';
select * from teams where id = 1099;
select * from users where id = 29643
select * from activity_processing_states;
SELECT * FROM teams where name LIKE '%Fare%'; # 233
SELECT * FROM opportunities where crm_configuration_id = 215
# and crm_provider_id = 'oppo_ogESZf2P50nDrd1nGPvKDXeA6sSaTN5v51Lp4ayVzKR'
;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1088 and sa.provider = 'hubspot';
SELECT * FROM teams order by updated_at DESC
SELECT * FROM crm_configurations WHERE id = 1019; # SimpleConsign 1088 - no social account
select * from crm_configurations where provider = 'pipedrive';
select * from teams where id = 957;
select * from crm_configurations where id = 957;
SELECT * FROM teams WHERE name LIKE '%Prolific%'; # 544, 518, 10743
SELECT * FROM opportunities where crm_configuration_id = 518 order by id desc;
select * from users where team_id = 1; # 26726 - Gabriela Dureva
SELECT * FROM opportunities where user_id = 26726; # 16834447 - Prolific
select * from activities where user_id = 26726 order by id desc;
select * from contacts where crm_configuration_id = 1
and email IN ('[EMAIL]', '[EMAIL]'); # 2094416, 2093620
SELECT * FROM contacts WHERE id = 6284931;
SELECT p.* FROM activities a JOIN participants p ON a.id = p.activity_id
WHERE a.user_id = 26726 and p.lead_id IN (2094416, 2093620) and a.created_at > '2026-01-01 00:00:00' order by p.email;
select * from activities where id IN (75509259,75509261,75509261,75511034,75026464,75517602,75517605);
select * from crm_configurations where id = 1;
43801692-1aeb-32ce-acba-5b80a479701a
44c3c9cf-6f5e-75f3-8179-bc9f75dd2b1b
405975c0-b3d0-7aaa-821f-09d59cae6dd1
4caf848d-4bed-2299-b248-7788d41f9fca
49bedc3f-f196-eef3-89c3-dea6a3b4aa63
43420989-a09d-b8f8-9806-c8bbf7a02aac
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
SELECT * FROM activities WHERE id = 75461988;
SELECT * FROM activities WHERE uuid_to_bin('d6c5052e-e972-49e9-8912-26f2f7d6c5f6') = uuid;
select * from contacts where id = 17900517;
select * from contact_roles cr join crm_configurations crm on cr.crm_configuration_id = crm.id
where crm.provider != 'salesforce';
select * from users where id = 21047;
SELECT * FROM crm_configurations WHERE id = 892;
SELECT * FROM teams WHERE id = 942;
select * from opportunities where team_id = 942 order by updated_at desc;
select * from contacts where team_id = 942 order by updated_at desc;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 942 and sa.provider = 'hubspot';
SELECT * FROM opportunities where team_id = 1 and crm_provider_id IN ('006Pq00000NeH6XIAV', '006Pq000007z8kdIAA'); # 10697889, 6621430
SELECT * FROM crm_configurations WHERE id = 1;
SELECT * FROM teams WHERE crm_id = 1;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1 and sa.provider = 'salesforce';
select id, user_id, opportunity_fields from crm_profiles where crm_configuration_id = 1
SELECT * FROM opportunities where team_id = 1 order by updated_at desc; # 10697889, 6621430
select * from teams where id = 852;
select * from groups where id = 2286;
select * from sidekick_settings where team_id = 852;
select * from default_activity_types where team_id = 852;
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id AND p.id IS NULL -- no profile
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active' -- team is active
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1 AND u.deleted_at IS NULL
AND u.crm_required = 1
AND u.team_id = 1
ORDER BY u.team_id;
SELECT * FROM crm_profiles cp where cp.crm_configuration_id = 1 and cp.user_id IN (
18481
);
SELECT cc.provider, cc.id, p.id, u.*
FROM users u
LEFT JOIN crm_profiles p ON u.id = p.user_id
INNER JOIN teams t ON u.team_id = t.id AND t.status = 'active'
INNER JOIN crm_configurations cc ON t.crm_id = cc.id
WHERE u.status = 1
AND u.deleted_at IS NULL
AND u.crm_required = 1
# AND u.team_id = 1
AND p.id IS NULL -- Move this condition to WHERE clause
ORDER BY u.team_id;
SELECT * FROM opportunities WHERE id = 20002609;
select * from teams where id = 1122; # Velatir, 29953 - [EMAIL]
select * from crm_configurations where id = 1060;
select * from crm_layouts where crm_configuration_id = 1060;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3596;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 1122 and sa.provider = 'hubspot';
select * from opportunities where team_id = 1122 order by updated_at desc;
select * from crm_field_data where object_type = 'contact';
SELECT * FROM activities WHERE uuid_to_bin('374fc8ed-3315-4c9f-9b25-318b7fd2928f') = uuid; # 76584262
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 248 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles where user_id = 24115; # 005QF000002CswMYAS
SELECT * FROM users where id = 24115;
SELECT * FROM accounts where id = 4002896;
SELECT * FROM teams WHERE name LIKE '%adswerve%';
SELECT * FROM opportunities where crm_configuration_id = 230 AND crm_provider_id IN ("0069N000003GIQ9QAO","0061r000019yGP9AAM","0066900001S2KWlAAN","0066900001TDpj2AAD","0066900001b8uEwAAI","0069N000001rQi0QAE","006QF00000KD40mYAD","006QF00000LzpRJYAZ","0069N000002uomtQAA","0069N000002xlMLQAY","0066900001NV6ubAAD","0061r00001HJp45AAD","006QF00000uTlUoYAK","006QF00000v0bZqYAI");
SELECT * FROM opportunities WHERE crm_configuration_id = 230 AND crm_provider_id = '0069N000003GIQ9QAO'; # 6272203
SELECT u.id, u.email, ac.name, a.* FROM activities a
JOIN users u ON a.user_id = u.id
JOIN accounts ac ON a.account_id = ac.id
WHERE
uuid_to_bin('e3269598-b562-44fb-b5e9-9d2694dc63e0') = a.uuid or
uuid_to_bin('66ddc3ab-4e15-45aa-af0c-248c1eece593') = a.uuid or
uuid_to_bin('826bd328-e1cc-4213-b8d8-572454cacc07') = a.uuid;
select * from users where id = 5825;
SELECT * FROM activities WHERE uuid_to_bin('e56aa2e8-231a-421b-ab1f-cb38ed2bf573') = uuid;
select * from activities where uuid_to_bin('91e13b2f-2d1b-45f8-b1fd-1141b6563782') = uuid;
19594, 862
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 862 and sa.provider = 'salesforce';
select * from automated_reports where id = 36;
select ar.frequency, r.*, ar.* from automated_report_results r
join automated_reports ar on r.report_id = ar.id
where ar.frequency != 'one_off';
select s.* from activity_searches s join users u ON s.user_id = u.id where u.team_id = 882;
select * from nudges n where n.activity_search_id
select * from teams where created_at > '2026-03-09';
SELECT * FROM crm_layouts WHERE crm_configuration_id = 1065; # 1065
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 3617;
select * from users where team_id = 1 and name like '%Lukas%'; # 7160
SELECT * FROM teams WHERE id = 575;
select * from opportunities where team_id = 575;
SELECT * FROM teams WHERE name LIKE '%Integrum ESG%'; # 1126, 1065,
select * from opportunities where team_id = 1126;
SELECT * FROM teams WHERE name LIKE '%Base%'; # 1125, 1063,
select * from opportunities where team_id = 1125;
select * from contacts c
where c.team_id = 882;
SELECT * FROM activities WHERE id = 76822967;
SELECT * FROM crm_profiles WHERE user_id = 15440;
SELECT * FROM crm_profiles WHERE crm_configuration_id = 555;
SELECT * FROM crm_configurations WHERE id = 555;
SELECT * FROM users WHERE id = 15440; # team. 581, gr. 15440, pl. 3911, act. field 162182
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 581 and sa.provider = 'salesforce';
SELECT * FROM automated_report_results order by id desc;
select * from features;
select * from team_features where feature_id = 40;
select * from teams where id = 556;
select * from automated_reports;
where id = 54; # 4fdd41f6-dcf0-30d0-b339-7345381b6044 , ["pdf","podcast"]
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
select * from automated_report_results order by id desc;
SELECT * FROM automated_report_results WHERE id = 1919;
select * from automated_report_results WHERE report_id = 54;
select * from opportunities where id = 7594349;
SELECT * FROM teams WHERE name LIKE '%Les%'; # 711, 692, 16067 - [EMAIL]
select * from playbooks where team_id = 711; # event 226147
SELECT * FROM playbook_categories WHERE playbook_id = 5515;
SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event';
SELECT * FROM crm_fields WHERE id = 226147;
SELECT * FROM crm_field_values WHERE crm_field_id = 226147;
SELECT * FROM crm_configurations WHERE id = 692;
SELECT
CONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '' END) AS user_id,
u.email,
sa.*,
t.owner_id FROM social_accounts sa
JOIN users u on u.id = sa.sociable_id
JOIN teams t on t.id = u.team_id
WHERE u.team_id = 711 and sa.provider = 'salesforce';
SELECT * FROM crm_profiles cp JOIN users u on u.id = cp.user_id WHERE u.team_id = 711;
select * from leads;
select * from calendars;
SELECT
t.id AS team_id,
t.name,
LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1)) AS calendar_domain
FROM teams t
JOIN users u ON u.team_id = t.id
JOIN calendars c ON c.user_id = u.id AND c.status = 'active' AND c.calendar_provider_id LIKE '%@%'
LEFT JOIN team_domains td
ON td.team_id = t.id
AND td.deleted_at IS NULL
AND td.domain = LOWER(SUBSTRING_INDEX(c.calendar_provider_id, '@', -1))
GROUP BY t.id, t.name, calendar_domain
ORDER BY t.name, calendar_domain;
select * from users u join calendars c on c.user_id = u.id
where u.team_id = 882;
select * from activities where id = 74049485; # team 563 crm 537
select * from activities where id = 73272382; # team 563 crm 537
select * from activities where id = 64400389; # team 563 crm 537
select * from activities where id = 58081273; # team 563 crm 537
select * from activities where id = 54520297; # team 563 crm 537
select * from participants where activity_id = 58081273;
select * from activities where crm_configuration_id = 537 and provider = 'aircall'
and account_id = 19003658 order by updated_at desc;
select * from contacts where crm_configuration_id = 537 and id = 35957759;
select * from accounts where crm_configuration_id = 537 and id = 19003658;
select * from automated_report_results where id = 1976;
select * from automated_reports where id = 583;
select * from activity_searches where id = 87714;
select * from activity_search_filters where activity_search_id = 87714;
SELECT * FROM activities WHERE uuid_to_bin('8827f672-202d-4162-9d04-73ff5f0566a9') = uuid
or uuid_to_bin('47842446-af51-4bcb-854f-cc6560290101') = uuid;
SELECT * FROM crm_configurations WHERE provider = 'hubspot';
select * from rate_limits;
select * from automated_report_results where media_type = 'pdf' and status = 2
and id IN (18, 1872);
select * from automated_reports where id = 54;
SELECT * FROM users WHERE id IN (24623,29443,29613);
SELECT * FROM automated_report_results WHERE uuid_to_bin('822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app, folder
.circleci, folder
.cursor, folder
.github
.sonarlint, folder
.vscode, folder
.windsurf, folder
app, sources root
Actions
InviteUserToTeamAction.php, class
MarkUserAsOnboardableAction.php, class
SyncRecordingFlagsAction.php, class
UpdateTeamMemberAction.php, class
UpdateUserRolesAction.php, class
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags
FFMpeg
FileSystem
Gecko
Gong
GuzzleHttp
KeyPoints
Kiosk
LanguageDetection
LiveFeed
Locks
Math
MediaPipeline...
|
NULL
|
NULL
|
NULL
|
NULL
|