|
57491
|
NULL
|
0
|
2026-05-19T10:04:37.035994+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779185077035_m1.jpg...
|
PhpStorm
|
faVsco.js – AskJiminnyReportsController.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20676-delete-report-re Project: faVsco.js, menu
JY-20676-delete-report-related-objects, menu
Start Listening for PHP Debug Connections
AskAnythingPromptServiceTest
Run 'AskAnythingPromptServiceTest'
Debug 'AskAnythingPromptServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
9
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\API\V2;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Jiminny\Exceptions\InvalidArgumentException;
use Jiminny\Exceptions\ModelNotFoundException;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Response;
use Throwable;
class AskJiminnyReportsController extends Controller
{
public function __construct(
private readonly AutomatedReportsService $automatedReportsService,
private readonly LoggerInterface $logger,
) {
}
private function isNotOwnedByUser(AutomatedReport $report, User $user): bool
{
return $report->getTeamId() !== $user->getTeamId()
|| $report->getAttribute('created_by') !== $user->getId();
}
public function getFormData(Request $request, ?string $uuid = null): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $uuid ? $this->automatedReportsService->getReport($uuid) : null;
return new JsonResponse(
$this->automatedReportsService->getAskJiminnyReportFormData($user, $report)
);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to fetch Ask Jiminny report form data', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to fetch form data'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Create a new Ask Jiminny report.
*/
public function create(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$data = $this->automatedReportsService->createAskJiminnyReport($request->all(), $user);
return new JsonResponse($data);
} catch (InvalidArgumentException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);
} catch (Throwable $e) {
$this->logger->error('Failed to create Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse(
['error' => 'Failed to create report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Update an existing Ask Jiminny report.
*/
public function update(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$data = $this->automatedReportsService->updateAskJiminnyReport($report, $request->all(), $user);
return new JsonResponse($data);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (InvalidArgumentException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);
} catch (Throwable $e) {
$this->logger->error('Failed to update Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to update report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Toggle Ask Jiminny report status (enable/disable).
*/
public function toggleStatus(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$enabled = (bool) $request->input('enabled');
if ($enabled && $report->isAskJiminnyReport() && ! $report->canExecute()) {
return new JsonResponse(
['error' => 'Report is missing a saved search or prompt. Complete the setup before enabling it.'],
Response::HTTP_UNPROCESSABLE_ENTITY
);
}
$data = $this->automatedReportsService->updateAskJiminnyReportStatus(
$report,
$enabled,
);
return new JsonResponse($data);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to toggle Ask Jiminny report status', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to toggle report status'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* List all Ask Jiminny reports.
*/
public function list(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$sortColumn = $request->input('sort_column', 'created_at');
$sortDirection = $request->input('sort_direction', 'desc');
$data = $this->automatedReportsService->listAskJiminnyReports($user, $sortColumn, $sortDirection);
return new JsonResponse($data);
} catch (Throwable $e) {
$this->logger->error('Failed to list Ask Jiminny reports', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse(
['error' => 'Failed to fetch reports'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Get a single Ask Jiminny report.
*/
public function get(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
return new JsonResponse($this->automatedReportsService->get($uuid));
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to get Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to fetch report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
public function getReportsCount(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$resultsCount = $this->automatedReportsService->getReportResults($report)->count();
return new JsonResponse(['count' => $resultsCount]);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to count report results', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'report_uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to count report results'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Delete an Ask Jiminny report.
*/
public function delete(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
if ($request->boolean('delete_generated_reports')) {
$this->automatedReportsService->deleteReportResults($uuid);
}
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$this->automatedReportsService->delete($uuid);
return new JsonResponse(null, Response::HTTP_NO_CONTENT);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to delete Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to delete report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
public function getFilters(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$filters = $this->automatedReportsService->getAskJiminnyReportFilters($user);
return new JsonResponse(['filters' => $filters]);
} catch (Throwable $e) {
$this->logger->error('Failed to fetch Ask Jiminny report filters', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse(
['error' => 'Failed to fetch filters'],
Response::HTTP_INTERNAL_SERVER_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":"JY-20676-delete-report-related-objects, menu","depth":5,"on_screen":true,"help_text":"Git Branch: JY-20676-delete-report-related-objects","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":"AskAnythingPromptServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskAnythingPromptServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskAnythingPromptServiceTest'","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":"9","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.016666668,"height":0.02111111},"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.025555555},"on_screen":false,"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.0,"top":0.0,"width":0.014583333,"height":0.025555555},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Http\\Controllers\\API\\V2;\n\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Controller;\nuse Jiminny\\Exceptions\\InvalidArgumentException;\nuse Jiminny\\Exceptions\\ModelNotFoundException;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Psr\\Log\\LoggerInterface;\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Throwable;\n\nclass AskJiminnyReportsController extends Controller\n{\n public function __construct(\n private readonly AutomatedReportsService $automatedReportsService,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n private function isNotOwnedByUser(AutomatedReport $report, User $user): bool\n {\n return $report->getTeamId() !== $user->getTeamId()\n || $report->getAttribute('created_by') !== $user->getId();\n }\n\n public function getFormData(Request $request, ?string $uuid = null): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $uuid ? $this->automatedReportsService->getReport($uuid) : null;\n\n return new JsonResponse(\n $this->automatedReportsService->getAskJiminnyReportFormData($user, $report)\n );\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to fetch Ask Jiminny report form data', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch form data'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Create a new Ask Jiminny report.\n */\n public function create(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $data = $this->automatedReportsService->createAskJiminnyReport($request->all(), $user);\n\n return new JsonResponse($data);\n } catch (InvalidArgumentException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);\n } catch (Throwable $e) {\n $this->logger->error('Failed to create Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to create report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Update an existing Ask Jiminny report.\n */\n public function update(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $data = $this->automatedReportsService->updateAskJiminnyReport($report, $request->all(), $user);\n\n return new JsonResponse($data);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (InvalidArgumentException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);\n } catch (Throwable $e) {\n $this->logger->error('Failed to update Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to update report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Toggle Ask Jiminny report status (enable/disable).\n */\n public function toggleStatus(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $enabled = (bool) $request->input('enabled');\n\n if ($enabled && $report->isAskJiminnyReport() && ! $report->canExecute()) {\n return new JsonResponse(\n ['error' => 'Report is missing a saved search or prompt. Complete the setup before enabling it.'],\n Response::HTTP_UNPROCESSABLE_ENTITY\n );\n }\n\n $data = $this->automatedReportsService->updateAskJiminnyReportStatus(\n $report,\n $enabled,\n );\n\n return new JsonResponse($data);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to toggle Ask Jiminny report status', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to toggle report status'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * List all Ask Jiminny reports.\n */\n public function list(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $sortColumn = $request->input('sort_column', 'created_at');\n $sortDirection = $request->input('sort_direction', 'desc');\n\n $data = $this->automatedReportsService->listAskJiminnyReports($user, $sortColumn, $sortDirection);\n\n return new JsonResponse($data);\n } catch (Throwable $e) {\n $this->logger->error('Failed to list Ask Jiminny reports', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch reports'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Get a single Ask Jiminny report.\n */\n public function get(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n return new JsonResponse($this->automatedReportsService->get($uuid));\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to get Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n public function getReportsCount(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $resultsCount = $this->automatedReportsService->getReportResults($report)->count();\n\n return new JsonResponse(['count' => $resultsCount]);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to count report results', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'report_uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to count report results'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Delete an Ask Jiminny report.\n */\n public function delete(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n if ($request->boolean('delete_generated_reports')) {\n $this->automatedReportsService->deleteReportResults($uuid);\n }\n\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $this->automatedReportsService->delete($uuid);\n\n return new JsonResponse(null, Response::HTTP_NO_CONTENT);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to delete Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to delete report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n public function getFilters(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $filters = $this->automatedReportsService->getAskJiminnyReportFilters($user);\n\n return new JsonResponse(['filters' => $filters]);\n } catch (Throwable $e) {\n $this->logger->error('Failed to fetch Ask Jiminny report filters', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch filters'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Http\\Controllers\\API\\V2;\n\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Controller;\nuse Jiminny\\Exceptions\\InvalidArgumentException;\nuse Jiminny\\Exceptions\\ModelNotFoundException;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Psr\\Log\\LoggerInterface;\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Throwable;\n\nclass AskJiminnyReportsController extends Controller\n{\n public function __construct(\n private readonly AutomatedReportsService $automatedReportsService,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n private function isNotOwnedByUser(AutomatedReport $report, User $user): bool\n {\n return $report->getTeamId() !== $user->getTeamId()\n || $report->getAttribute('created_by') !== $user->getId();\n }\n\n public function getFormData(Request $request, ?string $uuid = null): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $uuid ? $this->automatedReportsService->getReport($uuid) : null;\n\n return new JsonResponse(\n $this->automatedReportsService->getAskJiminnyReportFormData($user, $report)\n );\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to fetch Ask Jiminny report form data', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch form data'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Create a new Ask Jiminny report.\n */\n public function create(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $data = $this->automatedReportsService->createAskJiminnyReport($request->all(), $user);\n\n return new JsonResponse($data);\n } catch (InvalidArgumentException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);\n } catch (Throwable $e) {\n $this->logger->error('Failed to create Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to create report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Update an existing Ask Jiminny report.\n */\n public function update(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $data = $this->automatedReportsService->updateAskJiminnyReport($report, $request->all(), $user);\n\n return new JsonResponse($data);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (InvalidArgumentException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);\n } catch (Throwable $e) {\n $this->logger->error('Failed to update Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to update report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Toggle Ask Jiminny report status (enable/disable).\n */\n public function toggleStatus(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $enabled = (bool) $request->input('enabled');\n\n if ($enabled && $report->isAskJiminnyReport() && ! $report->canExecute()) {\n return new JsonResponse(\n ['error' => 'Report is missing a saved search or prompt. Complete the setup before enabling it.'],\n Response::HTTP_UNPROCESSABLE_ENTITY\n );\n }\n\n $data = $this->automatedReportsService->updateAskJiminnyReportStatus(\n $report,\n $enabled,\n );\n\n return new JsonResponse($data);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to toggle Ask Jiminny report status', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to toggle report status'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * List all Ask Jiminny reports.\n */\n public function list(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $sortColumn = $request->input('sort_column', 'created_at');\n $sortDirection = $request->input('sort_direction', 'desc');\n\n $data = $this->automatedReportsService->listAskJiminnyReports($user, $sortColumn, $sortDirection);\n\n return new JsonResponse($data);\n } catch (Throwable $e) {\n $this->logger->error('Failed to list Ask Jiminny reports', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch reports'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Get a single Ask Jiminny report.\n */\n public function get(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n return new JsonResponse($this->automatedReportsService->get($uuid));\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to get Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n public function getReportsCount(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $resultsCount = $this->automatedReportsService->getReportResults($report)->count();\n\n return new JsonResponse(['count' => $resultsCount]);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to count report results', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'report_uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to count report results'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Delete an Ask Jiminny report.\n */\n public function delete(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n if ($request->boolean('delete_generated_reports')) {\n $this->automatedReportsService->deleteReportResults($uuid);\n }\n\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $this->automatedReportsService->delete($uuid);\n\n return new JsonResponse(null, Response::HTTP_NO_CONTENT);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to delete Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to delete report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n public function getFilters(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $filters = $this->automatedReportsService->getAskJiminnyReportFilters($user);\n\n return new JsonResponse(['filters' => $filters]);\n } catch (Throwable $e) {\n $this->logger->error('Failed to fetch Ask Jiminny report filters', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch filters'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false}]...
|
2944069830662135629
|
-8210832956340721081
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20676-delete-report-re Project: faVsco.js, menu
JY-20676-delete-report-related-objects, menu
Start Listening for PHP Debug Connections
AskAnythingPromptServiceTest
Run 'AskAnythingPromptServiceTest'
Debug 'AskAnythingPromptServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
9
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\API\V2;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Jiminny\Exceptions\InvalidArgumentException;
use Jiminny\Exceptions\ModelNotFoundException;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Response;
use Throwable;
class AskJiminnyReportsController extends Controller
{
public function __construct(
private readonly AutomatedReportsService $automatedReportsService,
private readonly LoggerInterface $logger,
) {
}
private function isNotOwnedByUser(AutomatedReport $report, User $user): bool
{
return $report->getTeamId() !== $user->getTeamId()
|| $report->getAttribute('created_by') !== $user->getId();
}
public function getFormData(Request $request, ?string $uuid = null): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $uuid ? $this->automatedReportsService->getReport($uuid) : null;
return new JsonResponse(
$this->automatedReportsService->getAskJiminnyReportFormData($user, $report)
);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to fetch Ask Jiminny report form data', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to fetch form data'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Create a new Ask Jiminny report.
*/
public function create(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$data = $this->automatedReportsService->createAskJiminnyReport($request->all(), $user);
return new JsonResponse($data);
} catch (InvalidArgumentException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);
} catch (Throwable $e) {
$this->logger->error('Failed to create Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse(
['error' => 'Failed to create report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Update an existing Ask Jiminny report.
*/
public function update(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$data = $this->automatedReportsService->updateAskJiminnyReport($report, $request->all(), $user);
return new JsonResponse($data);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (InvalidArgumentException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);
} catch (Throwable $e) {
$this->logger->error('Failed to update Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to update report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Toggle Ask Jiminny report status (enable/disable).
*/
public function toggleStatus(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$enabled = (bool) $request->input('enabled');
if ($enabled && $report->isAskJiminnyReport() && ! $report->canExecute()) {
return new JsonResponse(
['error' => 'Report is missing a saved search or prompt. Complete the setup before enabling it.'],
Response::HTTP_UNPROCESSABLE_ENTITY
);
}
$data = $this->automatedReportsService->updateAskJiminnyReportStatus(
$report,
$enabled,
);
return new JsonResponse($data);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to toggle Ask Jiminny report status', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to toggle report status'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* List all Ask Jiminny reports.
*/
public function list(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$sortColumn = $request->input('sort_column', 'created_at');
$sortDirection = $request->input('sort_direction', 'desc');
$data = $this->automatedReportsService->listAskJiminnyReports($user, $sortColumn, $sortDirection);
return new JsonResponse($data);
} catch (Throwable $e) {
$this->logger->error('Failed to list Ask Jiminny reports', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse(
['error' => 'Failed to fetch reports'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Get a single Ask Jiminny report.
*/
public function get(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
return new JsonResponse($this->automatedReportsService->get($uuid));
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to get Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to fetch report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
public function getReportsCount(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$resultsCount = $this->automatedReportsService->getReportResults($report)->count();
return new JsonResponse(['count' => $resultsCount]);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to count report results', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'report_uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to count report results'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Delete an Ask Jiminny report.
*/
public function delete(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
if ($request->boolean('delete_generated_reports')) {
$this->automatedReportsService->deleteReportResults($uuid);
}
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$this->automatedReportsService->delete($uuid);
return new JsonResponse(null, Response::HTTP_NO_CONTENT);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to delete Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to delete report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
public function getFilters(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$filters = $this->automatedReportsService->getAskJiminnyReportFilters($user);
return new JsonResponse(['filters' => $filters]);
} catch (Throwable $e) {
$this->logger->error('Failed to fetch Ask Jiminny report filters', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse(
['error' => 'Failed to fetch filters'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
}...
|
57490
|
NULL
|
NULL
|
NULL
|
|
57422
|
NULL
|
0
|
2026-05-19T09:59:22.500690+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779184762500_m1.jpg...
|
Firefox
|
Електронно банкиране ДСК Директ от Банка ДСК — Per Електронно банкиране ДСК Директ от Банка ДСК — Personal...
|
1
|
www.dskdirect.bg/page/default.aspx?user_id=1130906 www.dskdirect.bg/page/default.aspx?user_id=11309067&session_id=ba8bf9f8536711f19bee005056b06f6fIBtc-CT9adxNOghuRcFgEUAPLud7ys3OMSqp7BD6PWKcph04%2fN-PP4efrkCO7ke8P8JNFLl99q1rgLIAXWznbg%3d%3dU&xml_id=/bg-BG/01Individuals/05Transfers/01PaymentOrders/05Internal/...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
Getting Started DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
Getting Started · AFFiNE
Getting Started · AFFiNE
Screenpipe — Archive
Screenpipe — Archive
Download screenpipe — get started in minutes
Download screenpipe — get started in minutes
Self-Hosted Software and Apps
Self-Hosted Software and Apps
New Tab
New Tab
Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - [EMAIL] - Gmail
Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - [EMAIL] - Gmail
Завеждане на щета онлайн | Euroins
Завеждане на щета онлайн | Euroins
Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii
Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii
Nginx Proxy Manager
Nginx Proxy Manager
Location Logger
Location Logger
Providers - Admin - authentik
Providers - Admin - authentik
Booking.com: My Booking.com. Book your hotel now!
Booking.com: My Booking.com. Book your hotel now!
secure.booking.com/mybooking_archivedsummary.en-us.html?label=en-bg-booking-desktop-MtC3OoaoU_ML6gxkUZ2GoAS652796015943%3Apl%3Ata%3Ap1%3Ap2%3Aac%3Aap%3Aneg%3Afi%3Atikwd-65526620%3Alp9217204%3Ali%3Adec%3Adm&sid=6f757849d9e7c593112207a735846f8c&aid=2311236&a
secure.booking.com/mybooking_archivedsummary.en-us.html?label=en-bg-booking-desktop-MtC3OoaoU_ML6gxkUZ2GoAS652796015943%3Apl%3Ata%3Ap1%3Ap2%3Aac%3Aap%3Aneg%3Afi%3Atikwd-65526620%3Alp9217204%3Ali%3Adec%3Adm&sid=6f757849d9e7c593112207a735846f8c&aid=2311236&a
Hotel Bellisimo, Lozenets (updated prices 2026)
Hotel Bellisimo, Lozenets (updated prices 2026)
Hotel Bellisimo, Lozenets (updated prices 2026)
Hotel Bellisimo, Lozenets (updated prices 2026)
Електронно банкиране ДСК Директ от Банка ДСК
Електронно банкиране ДСК Директ от Банка ДСК
Close tab...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"DXP4800PLUS-B5F8","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"DXP4800PLUS-B5F8","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Getting Started · AFFiNE","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Getting Started · AFFiNE","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe — Archive","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Screenpipe — Archive","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Download screenpipe — get started in minutes","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Download screenpipe — get started in minutes","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Self-Hosted Software and Apps","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Self-Hosted Software and Apps","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - kovaliklukas@gmail.com - Gmail","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - kovaliklukas@gmail.com - Gmail","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Завеждане на щета онлайн | Euroins","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Завеждане на щета онлайн | Euroins","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Nginx Proxy Manager","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Nginx Proxy Manager","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Location Logger","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Location Logger","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Providers - Admin - authentik","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Providers - Admin - authentik","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Booking.com: My Booking.com. Book your hotel now!","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Booking.com: My Booking.com. Book your hotel now!","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"secure.booking.com/mybooking_archivedsummary.en-us.html?label=en-bg-booking-desktop-MtC3OoaoU_ML6gxkUZ2GoAS652796015943%3Apl%3Ata%3Ap1%3Ap2%3Aac%3Aap%3Aneg%3Afi%3Atikwd-65526620%3Alp9217204%3Ali%3Adec%3Adm&sid=6f757849d9e7c593112207a735846f8c&aid=2311236&a","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"secure.booking.com/mybooking_archivedsummary.en-us.html?label=en-bg-booking-desktop-MtC3OoaoU_ML6gxkUZ2GoAS652796015943%3Apl%3Ata%3Ap1%3Ap2%3Aac%3Aap%3Aneg%3Afi%3Atikwd-65526620%3Alp9217204%3Ali%3Adec%3Adm&sid=6f757849d9e7c593112207a735846f8c&aid=2311236&a","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Hotel Bellisimo, Lozenets (updated prices 2026)","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Hotel Bellisimo, Lozenets (updated prices 2026)","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Hotel Bellisimo, Lozenets (updated prices 2026)","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Hotel Bellisimo, Lozenets (updated prices 2026)","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Електронно банкиране ДСК Директ от Банка ДСК","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Електронно банкиране ДСК Директ от Банка ДСК","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
-9144790018432624409
|
-1300189889076010998
|
visual_change
|
accessibility
|
NULL
|
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
Getting Started DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
Getting Started · AFFiNE
Getting Started · AFFiNE
Screenpipe — Archive
Screenpipe — Archive
Download screenpipe — get started in minutes
Download screenpipe — get started in minutes
Self-Hosted Software and Apps
Self-Hosted Software and Apps
New Tab
New Tab
Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - [EMAIL] - Gmail
Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - [EMAIL] - Gmail
Завеждане на щета онлайн | Euroins
Завеждане на щета онлайн | Euroins
Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii
Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii
Nginx Proxy Manager
Nginx Proxy Manager
Location Logger
Location Logger
Providers - Admin - authentik
Providers - Admin - authentik
Booking.com: My Booking.com. Book your hotel now!
Booking.com: My Booking.com. Book your hotel now!
secure.booking.com/mybooking_archivedsummary.en-us.html?label=en-bg-booking-desktop-MtC3OoaoU_ML6gxkUZ2GoAS652796015943%3Apl%3Ata%3Ap1%3Ap2%3Aac%3Aap%3Aneg%3Afi%3Atikwd-65526620%3Alp9217204%3Ali%3Adec%3Adm&sid=6f757849d9e7c593112207a735846f8c&aid=2311236&a
secure.booking.com/mybooking_archivedsummary.en-us.html?label=en-bg-booking-desktop-MtC3OoaoU_ML6gxkUZ2GoAS652796015943%3Apl%3Ata%3Ap1%3Ap2%3Aac%3Aap%3Aneg%3Afi%3Atikwd-65526620%3Alp9217204%3Ali%3Adec%3Adm&sid=6f757849d9e7c593112207a735846f8c&aid=2311236&a
Hotel Bellisimo, Lozenets (updated prices 2026)
Hotel Bellisimo, Lozenets (updated prices 2026)
Hotel Bellisimo, Lozenets (updated prices 2026)
Hotel Bellisimo, Lozenets (updated prices 2026)
Електронно банкиране ДСК Директ от Банка ДСК
Електронно банкиране ДСК Директ от Банка ДСК
Close tab...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
57421
|
NULL
|
0
|
2026-05-19T09:59:20.295220+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779184760295_m2.jpg...
|
Firefox
|
Електронно банкиране ДСК Директ от Банка ДСК — Per Електронно банкиране ДСК Директ от Банка ДСК — Personal...
|
1
|
www.dskdirect.bg/page/default.aspx?user_id=1130906 www.dskdirect.bg/page/default.aspx?user_id=11309067&session_id=ba8bf9f8536711f19bee005056b06f6fIBtc-CT9adxNOghuRcFgEUAPLud7ys3OMSqp7BD6PWKcph04%2fN-PP4efrkCO7ke8P8JNFLl99q1rgLIAXWznbg%3d%3dU&xml_id=/bg-BG/01Individuals/05Transfers/01PaymentOrders/05Internal/...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
Getting Started DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
Getting Started · AFFiNE
Getting Started · AFFiNE
Screenpipe — Archive
Screenpipe — Archive
Download screenpipe — get started in minutes
Download screenpipe — get started in minutes
Self-Hosted Software and Apps
Self-Hosted Software and Apps
New Tab
New Tab
Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - [EMAIL] - Gmail
Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - [EMAIL] - Gmail
Завеждане на щета онлайн | Euroins
Завеждане на щета онлайн | Euroins
Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii
Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii
Nginx Proxy Manager
Nginx Proxy Manager
Location Logger
Location Logger
Providers - Admin - authentik
Providers - Admin - authentik
Booking.com: My Booking.com. Book your hotel now!
Booking.com: My Booking.com. Book your hotel now!
secure.booking.com/mybooking_archivedsummary.en-us.html?label=en-bg-booking-desktop-MtC3OoaoU_ML6gxkUZ2GoAS652796015943%3Apl%3Ata%3Ap1%3Ap2%3Aac%3Aap%3Aneg%3Afi%3Atikwd-65526620%3Alp9217204%3Ali%3Adec%3Adm&sid=6f757849d9e7c593112207a735846f8c&aid=2311236&a
secure.booking.com/mybooking_archivedsummary.en-us.html?label=en-bg-booking-desktop-MtC3OoaoU_ML6gxkUZ2GoAS652796015943%3Apl%3Ata%3Ap1%3Ap2%3Aac%3Aap%3Aneg%3Afi%3Atikwd-65526620%3Alp9217204%3Ali%3Adec%3Adm&sid=6f757849d9e7c593112207a735846f8c&aid=2311236&a
Hotel Bellisimo, Lozenets (updated prices 2026)
Hotel Bellisimo, Lozenets (updated prices 2026)
Hotel Bellisimo, Lozenets (updated prices 2026)
Hotel Bellisimo, Lozenets (updated prices 2026)
Електронно банкиране ДСК Директ от Банка ДСК
Електронно банкиране ДСК Директ от Банка ДСК
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
LUKAS KOVALIK
1 Входяща поща
1
Входяща поща
Обратна връзка
Обратна връзка
English
English
Изход
Изход
СРЕДСТВА
СРЕДСТВА
КРЕДИТИ
КРЕДИТИ
КАРТИ
КАРТИ
БИТОВИ СМЕТКИ
БИТОВИ СМЕТКИ
ПРЕВОДИ
ПРЕВОДИ
СПЕСТЯВАНЕ
СПЕСТЯВАНЕ
ФОНДОВЕ
ФОНДОВЕ
ЗАЯВКИ
ЗАЯВКИ
ИЗВЕСТИЯ
ИЗВЕСТИЯ
СМАРТ ПРИЛОЖЕНИЯ
СМАРТ ПРИЛОЖЕНИЯ
НАСТРОЙКИ
НАСТРОЙКИ
Нов превод
Нов превод
Неизпратени
Неизпратени
Архив
Архив
PDF Авиза
PDF Авиза
Автоматични
Автоматични
Получатели
Получатели
Готови бланки
Готови бланки
Валутни курсове
Валутни курсове
Договорени курсове
Договорени курсове
Създаване/редактиране
Създаване/редактиране
Управление на бърз достъп до менюта.
Създай нов превод
Нареждането за EUR 200.00 е изпратено за обработка. Моля проследете статуса му от меню
Архив
Архив
*Фиксиран курс за целите на двойно обозначение 1 EUR = 1.95583 BGN
Потребителско ръководство - граждани
Потребителско ръководство - граждани
Общи условия за граждани
Общи условия за граждани
Тарифа за граждани
Тарифа за граждани
Call center:
*2375
0700 10 375
Потребителско ръководство - фирми
Потребителско ръководство - фирми
Общи условия за фирми
Общи условия за фирми
Тарифа за фирми
Тарифа за фирми
BIC/SWIFT на Банка ДСК: STSABGSF ©
2026 on DAIS eBank .NET
dskbank.bg/docs/default-source/интернет-банкиране-бизнес/потребителско-ръководство-дск-директ---бизнес-клиенти.pdf...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"DXP4800PLUS-B5F8","depth":4,"bounds":{"left":0.5,"top":0.0518755,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"DXP4800PLUS-B5F8","depth":5,"bounds":{"left":0.51329786,"top":0.06304868,"width":0.036901597,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Getting Started · AFFiNE","depth":4,"bounds":{"left":0.5,"top":0.08459697,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Getting Started · AFFiNE","depth":5,"bounds":{"left":0.51329786,"top":0.09577015,"width":0.04255319,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe — Archive","depth":4,"bounds":{"left":0.5,"top":0.11731844,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Screenpipe — Archive","depth":5,"bounds":{"left":0.51329786,"top":0.12849163,"width":0.037898935,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Download screenpipe — get started in minutes","depth":4,"bounds":{"left":0.5,"top":0.15003991,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Download screenpipe — get started in minutes","depth":5,"bounds":{"left":0.51329786,"top":0.16121309,"width":0.0809508,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Self-Hosted Software and Apps","depth":4,"bounds":{"left":0.5,"top":0.18276137,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Self-Hosted Software and Apps","depth":5,"bounds":{"left":0.51329786,"top":0.19393456,"width":0.054853722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.5,"top":0.21548285,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"bounds":{"left":0.51329786,"top":0.22665602,"width":0.014960106,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - kovaliklukas@gmail.com - Gmail","depth":4,"bounds":{"left":0.5,"top":0.2482043,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - kovaliklukas@gmail.com - Gmail","depth":5,"bounds":{"left":0.51329786,"top":0.25937748,"width":0.18118352,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Завеждане на щета онлайн | Euroins","depth":4,"bounds":{"left":0.5,"top":0.28092578,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Завеждане на щета онлайн | Euroins","depth":5,"bounds":{"left":0.51329786,"top":0.29209897,"width":0.0653258,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii","depth":4,"bounds":{"left":0.5,"top":0.31364724,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii","depth":5,"bounds":{"left":0.51329786,"top":0.32482043,"width":0.091090426,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Nginx Proxy Manager","depth":4,"bounds":{"left":0.5,"top":0.3463687,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Nginx Proxy Manager","depth":5,"bounds":{"left":0.51329786,"top":0.3575419,"width":0.036901597,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Location Logger","depth":4,"bounds":{"left":0.5,"top":0.3790902,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Location Logger","depth":5,"bounds":{"left":0.51329786,"top":0.39026338,"width":0.028091755,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Providers - Admin - authentik","depth":4,"bounds":{"left":0.5,"top":0.41181165,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Providers - Admin - authentik","depth":5,"bounds":{"left":0.51329786,"top":0.42298484,"width":0.05119681,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Booking.com: My Booking.com. Book your hotel now!","depth":4,"bounds":{"left":0.5,"top":0.4445331,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Booking.com: My Booking.com. Book your hotel now!","depth":5,"bounds":{"left":0.51329786,"top":0.4557063,"width":0.09225399,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"secure.booking.com/mybooking_archivedsummary.en-us.html?label=en-bg-booking-desktop-MtC3OoaoU_ML6gxkUZ2GoAS652796015943%3Apl%3Ata%3Ap1%3Ap2%3Aac%3Aap%3Aneg%3Afi%3Atikwd-65526620%3Alp9217204%3Ali%3Adec%3Adm&sid=6f757849d9e7c593112207a735846f8c&aid=2311236&a","depth":4,"bounds":{"left":0.5,"top":0.4772546,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"secure.booking.com/mybooking_archivedsummary.en-us.html?label=en-bg-booking-desktop-MtC3OoaoU_ML6gxkUZ2GoAS652796015943%3Apl%3Ata%3Ap1%3Ap2%3Aac%3Aap%3Aneg%3Afi%3Atikwd-65526620%3Alp9217204%3Ali%3Adec%3Adm&sid=6f757849d9e7c593112207a735846f8c&aid=2311236&a","depth":5,"bounds":{"left":0.51329786,"top":0.4884278,"width":0.48670214,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Hotel Bellisimo, Lozenets (updated prices 2026)","depth":4,"bounds":{"left":0.5,"top":0.509976,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Hotel Bellisimo, Lozenets (updated prices 2026)","depth":5,"bounds":{"left":0.51329786,"top":0.5211492,"width":0.08377659,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Hotel Bellisimo, Lozenets (updated prices 2026)","depth":4,"bounds":{"left":0.5,"top":0.54269755,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Hotel Bellisimo, Lozenets (updated prices 2026)","depth":5,"bounds":{"left":0.51329786,"top":0.55387074,"width":0.08377659,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Електронно банкиране ДСК Директ от Банка ДСК","depth":4,"bounds":{"left":0.5,"top":0.575419,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Електронно банкиране ДСК Директ от Банка ДСК","depth":5,"bounds":{"left":0.51329786,"top":0.5865922,"width":0.09059176,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.55651593,"top":0.5826017,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.5028258,"top":0.6097366,"width":0.06333112,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.5028258,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.51379657,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.5249335,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.53607047,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Bitwarden","depth":6,"bounds":{"left":0.5472075,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LUKAS KOVALIK","depth":14,"bounds":{"left":0.7915558,"top":0.06743815,"width":0.02825798,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 Входяща поща","depth":12,"bounds":{"left":0.8224734,"top":0.0518755,"width":0.051695477,"height":0.044692736},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":14,"bounds":{"left":0.8367686,"top":0.06943336,"width":0.0023271276,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Входяща поща","depth":13,"bounds":{"left":0.84375,"top":0.06743815,"width":0.027759308,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Обратна връзка","depth":12,"bounds":{"left":0.8741689,"top":0.0518755,"width":0.04537899,"height":0.044692736},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Обратна връзка","depth":14,"bounds":{"left":0.8864694,"top":0.06743815,"width":0.030418882,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"English","depth":12,"bounds":{"left":0.91954786,"top":0.0518755,"width":0.028091755,"height":0.044692736},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"English","depth":14,"bounds":{"left":0.9318484,"top":0.06743815,"width":0.013131649,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Изход","depth":12,"bounds":{"left":0.94763964,"top":0.0518755,"width":0.026263298,"height":0.044692736},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Изход","depth":14,"bounds":{"left":0.95994014,"top":0.06743815,"width":0.011303191,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"СРЕДСТВА","depth":14,"bounds":{"left":0.6540891,"top":0.096568234,"width":0.026263298,"height":0.044692736},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"СРЕДСТВА","depth":15,"bounds":{"left":0.65674865,"top":0.11173184,"width":0.020944148,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"КРЕДИТИ","depth":14,"bounds":{"left":0.68168217,"top":0.096568234,"width":0.024767287,"height":0.044692736},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"КРЕДИТИ","depth":15,"bounds":{"left":0.6843417,"top":0.11173184,"width":0.019448139,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"КАРТИ","depth":14,"bounds":{"left":0.7077792,"top":0.096568234,"width":0.01861702,"height":0.044692736},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"КАРТИ","depth":15,"bounds":{"left":0.71043885,"top":0.11173184,"width":0.013297873,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"БИТОВИ СМЕТКИ","depth":14,"bounds":{"left":0.72772604,"top":0.096568234,"width":0.039893616,"height":0.044692736},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"БИТОВИ СМЕТКИ","depth":15,"bounds":{"left":0.73038566,"top":0.11173184,"width":0.034574468,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ПРЕВОДИ","depth":14,"bounds":{"left":0.76894945,"top":0.08858739,"width":0.025930852,"height":0.054269753},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ПРЕВОДИ","depth":15,"bounds":{"left":0.77160907,"top":0.10853951,"width":0.020611702,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"СПЕСТЯВАНЕ","depth":14,"bounds":{"left":0.7962101,"top":0.096568234,"width":0.031914894,"height":0.044692736},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"СПЕСТЯВАНЕ","depth":15,"bounds":{"left":0.79886967,"top":0.11173184,"width":0.026595745,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ФОНДОВЕ","depth":14,"bounds":{"left":0.8294548,"top":0.096568234,"width":0.026097074,"height":0.044692736},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ФОНДОВЕ","depth":15,"bounds":{"left":0.83211434,"top":0.11173184,"width":0.020777926,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ЗАЯВКИ","depth":14,"bounds":{"left":0.8568817,"top":0.096568234,"width":0.021609042,"height":0.044692736},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ЗАЯВКИ","depth":15,"bounds":{"left":0.85954124,"top":0.11173184,"width":0.016289894,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ИЗВЕСТИЯ","depth":14,"bounds":{"left":0.87982047,"top":0.096568234,"width":0.026928192,"height":0.044692736},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ИЗВЕСТИЯ","depth":15,"bounds":{"left":0.88248,"top":0.11173184,"width":0.021609042,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"СМАРТ ПРИЛОЖЕНИЯ","depth":14,"bounds":{"left":0.90807843,"top":0.096568234,"width":0.049534574,"height":0.044692736},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"СМАРТ ПРИЛОЖЕНИЯ","depth":15,"bounds":{"left":0.91073805,"top":0.11173184,"width":0.044215426,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"НАСТРОЙКИ","depth":14,"bounds":{"left":0.95894283,"top":0.096568234,"width":0.030418882,"height":0.044692736},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"НАСТРОЙКИ","depth":15,"bounds":{"left":0.9616024,"top":0.11173184,"width":0.025099734,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Нов превод","depth":14,"bounds":{"left":0.59491354,"top":0.16121309,"width":0.03174867,"height":0.030327214},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Нов превод","depth":15,"bounds":{"left":0.59890294,"top":0.16919394,"width":0.023769947,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Неизпратени","depth":14,"bounds":{"left":0.6286569,"top":0.16121309,"width":0.03507314,"height":0.030327214},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Неизпратени","depth":15,"bounds":{"left":0.63264626,"top":0.16919394,"width":0.027094414,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Архив","depth":14,"bounds":{"left":0.66572475,"top":0.16121309,"width":0.019946808,"height":0.030327214},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Архив","depth":15,"bounds":{"left":0.6697141,"top":0.16919394,"width":0.011968086,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"PDF Авиза","depth":14,"bounds":{"left":0.68766624,"top":0.16121309,"width":0.028756648,"height":0.030327214},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"PDF Авиза","depth":15,"bounds":{"left":0.6916556,"top":0.16919394,"width":0.020777926,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Автоматични","depth":14,"bounds":{"left":0.7184175,"top":0.16121309,"width":0.03507314,"height":0.030327214},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Автоматични","depth":15,"bounds":{"left":0.7224069,"top":0.16919394,"width":0.027094414,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Получатели","depth":14,"bounds":{"left":0.75548536,"top":0.16121309,"width":0.032247342,"height":0.030327214},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Получатели","depth":15,"bounds":{"left":0.75947475,"top":0.16919394,"width":0.024268618,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Готови бланки","depth":14,"bounds":{"left":0.7897274,"top":0.16121309,"width":0.03756649,"height":0.030327214},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Готови бланки","depth":15,"bounds":{"left":0.7937167,"top":0.16919394,"width":0.029587766,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Валутни курсове","depth":14,"bounds":{"left":0.82928854,"top":0.16121309,"width":0.042386968,"height":0.030327214},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Валутни курсове","depth":15,"bounds":{"left":0.83327794,"top":0.16919394,"width":0.034408245,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Договорени курсове","depth":14,"bounds":{"left":0.8736702,"top":0.16121309,"width":0.049867023,"height":0.030327214},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Договорени курсове","depth":15,"bounds":{"left":0.87765956,"top":0.16919394,"width":0.041888297,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Създаване/редактиране","depth":12,"bounds":{"left":0.59491354,"top":0.21548285,"width":0.06565824,"height":0.035913806},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Създаване/редактиране","depth":13,"bounds":{"left":0.59491354,"top":0.22226655,"width":0.06565824,"height":0.018355945},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Управление на бърз достъп до менюта.","depth":13,"bounds":{"left":0.6605718,"top":0.21747805,"width":0.021276595,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Създай нов превод","depth":12,"bounds":{"left":0.9155585,"top":0.22027135,"width":0.058011968,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Нареждането за EUR 200.00 е изпратено за обработка. Моля проследете статуса му от меню","depth":13,"bounds":{"left":0.60920876,"top":0.31444532,"width":0.21492687,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Архив","depth":13,"bounds":{"left":0.82413566,"top":0.31444532,"width":0.013796543,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Архив","depth":14,"bounds":{"left":0.82413566,"top":0.31444532,"width":0.013796543,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"*Фиксиран курс за целите на двойно обозначение 1 EUR = 1.95583 BGN","depth":12,"bounds":{"left":0.6022274,"top":0.4114126,"width":0.16456117,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Потребителско ръководство - граждани","depth":13,"bounds":{"left":0.609375,"top":0.88268155,"width":0.09391622,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Потребителско ръководство - граждани","depth":14,"bounds":{"left":0.609375,"top":0.88268155,"width":0.09391622,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Общи условия за граждани","depth":13,"bounds":{"left":0.6243351,"top":0.905427,"width":0.06382979,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Общи условия за граждани","depth":14,"bounds":{"left":0.6243351,"top":0.905427,"width":0.06382979,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Тарифа за граждани","depth":13,"bounds":{"left":0.63231385,"top":0.9281724,"width":0.047872342,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Тарифа за граждани","depth":14,"bounds":{"left":0.63231385,"top":0.9281724,"width":0.047872342,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Call center:","depth":13,"bounds":{"left":0.74617684,"top":0.88268155,"width":0.025930852,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"*2375","depth":13,"bounds":{"left":0.77642953,"top":0.88268155,"width":0.014960106,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0700 10 375","depth":13,"bounds":{"left":0.79571146,"top":0.88268155,"width":0.027094414,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Потребителско ръководство - фирми","depth":13,"bounds":{"left":0.86884975,"top":0.88268155,"width":0.08726729,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Потребителско ръководство - фирми","depth":14,"bounds":{"left":0.86884975,"top":0.88268155,"width":0.08726729,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Общи условия за фирми","depth":13,"bounds":{"left":0.88397604,"top":0.905427,"width":0.05701463,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Общи условия за фирми","depth":14,"bounds":{"left":0.88397604,"top":0.905427,"width":0.05701463,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Тарифа за фирми","depth":13,"bounds":{"left":0.8919548,"top":0.9281724,"width":0.04105718,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Тарифа за фирми","depth":14,"bounds":{"left":0.8919548,"top":0.9281724,"width":0.04105718,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BIC/SWIFT на Банка ДСК: STSABGSF ©","depth":12,"bounds":{"left":0.7302194,"top":0.9596967,"width":0.066821806,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026 on DAIS eBank .NET","depth":12,"bounds":{"left":0.79704124,"top":0.9596967,"width":0.04155585,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dskbank.bg/docs/default-source/интернет-банкиране-бизнес/потребителско-ръководство-дск-директ---бизнес-клиенти.pdf","depth":5,"bounds":{"left":0.57014626,"top":0.9876297,"width":0.2278923,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
3516299693390683647
|
-2476755231592570862
|
visual_change
|
accessibility
|
NULL
|
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
Getting Started DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
Getting Started · AFFiNE
Getting Started · AFFiNE
Screenpipe — Archive
Screenpipe — Archive
Download screenpipe — get started in minutes
Download screenpipe — get started in minutes
Self-Hosted Software and Apps
Self-Hosted Software and Apps
New Tab
New Tab
Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - [EMAIL] - Gmail
Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - [EMAIL] - Gmail
Завеждане на щета онлайн | Euroins
Завеждане на щета онлайн | Euroins
Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii
Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii
Nginx Proxy Manager
Nginx Proxy Manager
Location Logger
Location Logger
Providers - Admin - authentik
Providers - Admin - authentik
Booking.com: My Booking.com. Book your hotel now!
Booking.com: My Booking.com. Book your hotel now!
secure.booking.com/mybooking_archivedsummary.en-us.html?label=en-bg-booking-desktop-MtC3OoaoU_ML6gxkUZ2GoAS652796015943%3Apl%3Ata%3Ap1%3Ap2%3Aac%3Aap%3Aneg%3Afi%3Atikwd-65526620%3Alp9217204%3Ali%3Adec%3Adm&sid=6f757849d9e7c593112207a735846f8c&aid=2311236&a
secure.booking.com/mybooking_archivedsummary.en-us.html?label=en-bg-booking-desktop-MtC3OoaoU_ML6gxkUZ2GoAS652796015943%3Apl%3Ata%3Ap1%3Ap2%3Aac%3Aap%3Aneg%3Afi%3Atikwd-65526620%3Alp9217204%3Ali%3Adec%3Adm&sid=6f757849d9e7c593112207a735846f8c&aid=2311236&a
Hotel Bellisimo, Lozenets (updated prices 2026)
Hotel Bellisimo, Lozenets (updated prices 2026)
Hotel Bellisimo, Lozenets (updated prices 2026)
Hotel Bellisimo, Lozenets (updated prices 2026)
Електронно банкиране ДСК Директ от Банка ДСК
Електронно банкиране ДСК Директ от Банка ДСК
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
LUKAS KOVALIK
1 Входяща поща
1
Входяща поща
Обратна връзка
Обратна връзка
English
English
Изход
Изход
СРЕДСТВА
СРЕДСТВА
КРЕДИТИ
КРЕДИТИ
КАРТИ
КАРТИ
БИТОВИ СМЕТКИ
БИТОВИ СМЕТКИ
ПРЕВОДИ
ПРЕВОДИ
СПЕСТЯВАНЕ
СПЕСТЯВАНЕ
ФОНДОВЕ
ФОНДОВЕ
ЗАЯВКИ
ЗАЯВКИ
ИЗВЕСТИЯ
ИЗВЕСТИЯ
СМАРТ ПРИЛОЖЕНИЯ
СМАРТ ПРИЛОЖЕНИЯ
НАСТРОЙКИ
НАСТРОЙКИ
Нов превод
Нов превод
Неизпратени
Неизпратени
Архив
Архив
PDF Авиза
PDF Авиза
Автоматични
Автоматични
Получатели
Получатели
Готови бланки
Готови бланки
Валутни курсове
Валутни курсове
Договорени курсове
Договорени курсове
Създаване/редактиране
Създаване/редактиране
Управление на бърз достъп до менюта.
Създай нов превод
Нареждането за EUR 200.00 е изпратено за обработка. Моля проследете статуса му от меню
Архив
Архив
*Фиксиран курс за целите на двойно обозначение 1 EUR = 1.95583 BGN
Потребителско ръководство - граждани
Потребителско ръководство - граждани
Общи условия за граждани
Общи условия за граждани
Тарифа за граждани
Тарифа за граждани
Call center:
*2375
0700 10 375
Потребителско ръководство - фирми
Потребителско ръководство - фирми
Общи условия за фирми
Общи условия за фирми
Тарифа за фирми
Тарифа за фирми
BIC/SWIFT на Банка ДСК: STSABGSF ©
2026 on DAIS eBank .NET
dskbank.bg/docs/default-source/интернет-банкиране-бизнес/потребителско-ръководство-дск-директ---бизнес-клиенти.pdf...
|
57420
|
NULL
|
NULL
|
NULL
|
|
57368
|
NULL
|
0
|
2026-05-19T09:54:16.532891+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779184456532_m2.jpg...
|
Firefox
|
Електронно банкиране ДСК Директ от Банка ДСК — Per Електронно банкиране ДСК Директ от Банка ДСК — Personal...
|
1
|
www.dskdirect.bg/page/default.aspx?user_id=1130906 www.dskdirect.bg/page/default.aspx?user_id=11309067&session_id=ba8bf9f8536711f19bee005056b06f6fIBtc-CT9adxNOghuRcFgEUAPLud7ys3OMSqp7BD6PWKcph04%2fN-PP4efrkCO7ke8P8JNFLl99q1rgLIAXWznbg%3d%3dU&xml_id=/bg-BG/01Individuals/05Transfers/01PaymentOrders/05Internal/...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
Getting Started DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
Getting Started · AFFiNE
Getting Started · AFFiNE
Screenpipe — Archive
Screenpipe — Archive
Download screenpipe — get started in minutes
Download screenpipe — get started in minutes
Self-Hosted Software and Apps
Self-Hosted Software and Apps
New Tab
New Tab
Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - [EMAIL] - Gmail
Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - [EMAIL] - Gmail
Завеждане на щета онлайн | Euroins
Завеждане на щета онлайн | Euroins
Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii
Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii
Nginx Proxy Manager
Nginx Proxy Manager
Location Logger
Location Logger
Providers - Admin - authentik
Providers - Admin - authentik
Booking.com: My Booking.com. Book your hotel now!
Booking.com: My Booking.com. Book your hotel now!
secure.booking.com/mybooking_archivedsummary.en-us.html?label=en-bg-booking-desktop-MtC3OoaoU_ML6gxkUZ2GoAS652796015943%3Apl%3Ata%3Ap1%3Ap2%3Aac%3Aap%3Aneg%3Afi%3Atikwd-65526620%3Alp9217204%3Ali%3Adec%3Adm&sid=6f757849d9e7c593112207a735846f8c&aid=2311236&a
secure.booking.com/mybooking_archivedsummary.en-us.html?label=en-bg-booking-desktop-MtC3OoaoU_ML6gxkUZ2GoAS652796015943%3Apl%3Ata%3Ap1%3Ap2%3Aac%3Aap%3Aneg%3Afi%3Atikwd-65526620%3Alp9217204%3Ali%3Adec%3Adm&sid=6f757849d9e7c593112207a735846f8c&aid=2311236&a
Hotel Bellisimo, Lozenets (updated prices 2026)
Hotel Bellisimo, Lozenets (updated prices 2026)
Hotel Bellisimo, Lozenets (updated prices 2026)
Hotel Bellisimo, Lozenets (updated prices 2026)
Електронно банкиране ДСК Директ от Банка ДСК
Електронно банкиране ДСК Директ от Банка ДСК
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
LUKAS KOVALIK
1 Входяща поща
1
Входяща поща
Обратна връзка
Обратна връзка
English
English
Изход
Изход
СРЕДСТВА
СРЕДСТВА
КРЕДИТИ
КРЕДИТИ
КАРТИ
КАРТИ
БИТОВИ СМЕТКИ
БИТОВИ СМЕТКИ
ПРЕВОДИ
ПРЕВОДИ
СПЕСТЯВАНЕ
СПЕСТЯВАНЕ
ФОНДОВЕ
ФОНДОВЕ
ЗАЯВКИ
ЗАЯВКИ
ИЗВЕСТИЯ
ИЗВЕСТИЯ
СМАРТ ПРИЛОЖЕНИЯ
СМАРТ ПРИЛОЖЕНИЯ
НАСТРОЙКИ
НАСТРОЙКИ
Нов превод
Нов превод
Неизпратени
Неизпратени
Архив
Архив
PDF Авиза
PDF Авиза
Автоматични
Автоматични
Получатели
Получатели
Готови бланки
Готови бланки
Валутни курсове
Валутни курсове
Договорени курсове
Договорени курсове
Създаване/редактиране
Създаване/редактиране
Управление на бърз достъп до менюта.
Създай нов превод
Зареди готова бланка
Нареждане за превод по сметка в Банка ДСК
Нареждане за превод по сметка в Банка ДСК
От сметка
Show All Items
Име на получател
Show All Items
IBAN / Валута на превода
Сума
/ Валута
0.00
EUR
Основание
Основание
Още пояснения
Още пояснения
Преводът се изпълнява незабавно. В периода между 22:00 и 04:00 часа е възможно забавяне при приемане на преводите.
Преведи сега
Преведи сега
Заяви дата на изпълнение
Заяви дата на изпълнение
Заяви периодично изпълнение
Заяви периодично изпълнение
ЗАПАЗИ КАТО готова бланка
ЗАПАЗИ КАТО
готова бланка
Видимa за всички пълномощници
Видимa за всички пълномощници
ЗАПАЗИ КАТО получател
ЗАПАЗИ КАТО
получател
Видим за всички пълномощници
Видим за всички пълномощници
Преведи
Запази
*Фиксиран курс за целите на двойно обозначение 1 EUR = 1.95583 BGN
Потребителско ръководство - граждани
Потребителско ръководство - граждани
Общи условия за граждани
Общи условия за граждани
Тарифа за граждани
Тарифа за граждани
Call center:
*2375
0700 10 375
Потребителско ръководство - фирми
Потребителско ръководство - фирми
Общи условия за фирми
Общи условия за фирми
Тарифа за фирми
Тарифа за фирми
BIC/SWIFT на Банка ДСК: STSABGSF ©
2026 on DAIS eBank .NET...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"DXP4800PLUS-B5F8","depth":4,"bounds":{"left":0.5,"top":0.0518755,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"DXP4800PLUS-B5F8","depth":5,"bounds":{"left":0.51329786,"top":0.06304868,"width":0.036901597,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Getting Started · AFFiNE","depth":4,"bounds":{"left":0.5,"top":0.08459697,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Getting Started · AFFiNE","depth":5,"bounds":{"left":0.51329786,"top":0.09577015,"width":0.04255319,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe — Archive","depth":4,"bounds":{"left":0.5,"top":0.11731844,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Screenpipe — Archive","depth":5,"bounds":{"left":0.51329786,"top":0.12849163,"width":0.037898935,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Download screenpipe — get started in minutes","depth":4,"bounds":{"left":0.5,"top":0.15003991,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Download screenpipe — get started in minutes","depth":5,"bounds":{"left":0.51329786,"top":0.16121309,"width":0.0809508,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Self-Hosted Software and Apps","depth":4,"bounds":{"left":0.5,"top":0.18276137,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Self-Hosted Software and Apps","depth":5,"bounds":{"left":0.51329786,"top":0.19393456,"width":0.054853722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.5,"top":0.21548285,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"bounds":{"left":0.51329786,"top":0.22665602,"width":0.014960106,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - kovaliklukas@gmail.com - Gmail","depth":4,"bounds":{"left":0.5,"top":0.2482043,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - kovaliklukas@gmail.com - Gmail","depth":5,"bounds":{"left":0.51329786,"top":0.25937748,"width":0.18118352,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Завеждане на щета онлайн | Euroins","depth":4,"bounds":{"left":0.5,"top":0.28092578,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Завеждане на щета онлайн | Euroins","depth":5,"bounds":{"left":0.51329786,"top":0.29209897,"width":0.0653258,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii","depth":4,"bounds":{"left":0.5,"top":0.31364724,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii","depth":5,"bounds":{"left":0.51329786,"top":0.32482043,"width":0.091090426,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Nginx Proxy Manager","depth":4,"bounds":{"left":0.5,"top":0.3463687,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Nginx Proxy Manager","depth":5,"bounds":{"left":0.51329786,"top":0.3575419,"width":0.036901597,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Location Logger","depth":4,"bounds":{"left":0.5,"top":0.3790902,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Location Logger","depth":5,"bounds":{"left":0.51329786,"top":0.39026338,"width":0.028091755,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Providers - Admin - authentik","depth":4,"bounds":{"left":0.5,"top":0.41181165,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Providers - Admin - authentik","depth":5,"bounds":{"left":0.51329786,"top":0.42298484,"width":0.05119681,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Booking.com: My Booking.com. Book your hotel now!","depth":4,"bounds":{"left":0.5,"top":0.4445331,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Booking.com: My Booking.com. Book your hotel now!","depth":5,"bounds":{"left":0.51329786,"top":0.4557063,"width":0.09225399,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"secure.booking.com/mybooking_archivedsummary.en-us.html?label=en-bg-booking-desktop-MtC3OoaoU_ML6gxkUZ2GoAS652796015943%3Apl%3Ata%3Ap1%3Ap2%3Aac%3Aap%3Aneg%3Afi%3Atikwd-65526620%3Alp9217204%3Ali%3Adec%3Adm&sid=6f757849d9e7c593112207a735846f8c&aid=2311236&a","depth":4,"bounds":{"left":0.5,"top":0.4772546,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"secure.booking.com/mybooking_archivedsummary.en-us.html?label=en-bg-booking-desktop-MtC3OoaoU_ML6gxkUZ2GoAS652796015943%3Apl%3Ata%3Ap1%3Ap2%3Aac%3Aap%3Aneg%3Afi%3Atikwd-65526620%3Alp9217204%3Ali%3Adec%3Adm&sid=6f757849d9e7c593112207a735846f8c&aid=2311236&a","depth":5,"bounds":{"left":0.51329786,"top":0.4884278,"width":0.48670214,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Hotel Bellisimo, Lozenets (updated prices 2026)","depth":4,"bounds":{"left":0.5,"top":0.509976,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Hotel Bellisimo, Lozenets (updated prices 2026)","depth":5,"bounds":{"left":0.51329786,"top":0.5211492,"width":0.08377659,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Hotel Bellisimo, Lozenets (updated prices 2026)","depth":4,"bounds":{"left":0.5,"top":0.54269755,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Hotel Bellisimo, Lozenets (updated prices 2026)","depth":5,"bounds":{"left":0.51329786,"top":0.55387074,"width":0.08377659,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Електронно банкиране ДСК Директ от Банка ДСК","depth":4,"bounds":{"left":0.5,"top":0.575419,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Електронно банкиране ДСК Директ от Банка ДСК","depth":5,"bounds":{"left":0.51329786,"top":0.5865922,"width":0.09059176,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.55651593,"top":0.5826017,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.5028258,"top":0.6097366,"width":0.06333112,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.5028258,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.51379657,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.5249335,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.53607047,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Bitwarden","depth":6,"bounds":{"left":0.5472075,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LUKAS KOVALIK","depth":14,"bounds":{"left":0.7915558,"top":0.0650439,"width":0.02825798,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 Входяща поща","depth":12,"bounds":{"left":0.8224734,"top":0.049481247,"width":0.051695477,"height":0.044692736},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":14,"bounds":{"left":0.8367686,"top":0.06703911,"width":0.0023271276,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Входяща поща","depth":13,"bounds":{"left":0.84375,"top":0.0650439,"width":0.027759308,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Обратна връзка","depth":12,"bounds":{"left":0.8741689,"top":0.049481247,"width":0.04537899,"height":0.044692736},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Обратна връзка","depth":14,"bounds":{"left":0.8864694,"top":0.0650439,"width":0.030418882,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"English","depth":12,"bounds":{"left":0.91954786,"top":0.049481247,"width":0.028091755,"height":0.044692736},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"English","depth":14,"bounds":{"left":0.9318484,"top":0.0650439,"width":0.013131649,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Изход","depth":12,"bounds":{"left":0.94763964,"top":0.049481247,"width":0.026263298,"height":0.044692736},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Изход","depth":14,"bounds":{"left":0.95994014,"top":0.0650439,"width":0.011303191,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"СРЕДСТВА","depth":14,"bounds":{"left":0.6540891,"top":0.09417398,"width":0.026263298,"height":0.044692736},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"СРЕДСТВА","depth":15,"bounds":{"left":0.65674865,"top":0.10933759,"width":0.020944148,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"КРЕДИТИ","depth":14,"bounds":{"left":0.68168217,"top":0.09417398,"width":0.024767287,"height":0.044692736},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"КРЕДИТИ","depth":15,"bounds":{"left":0.6843417,"top":0.10933759,"width":0.019448139,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"КАРТИ","depth":14,"bounds":{"left":0.7077792,"top":0.09417398,"width":0.01861702,"height":0.044692736},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"КАРТИ","depth":15,"bounds":{"left":0.71043885,"top":0.10933759,"width":0.013297873,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"БИТОВИ СМЕТКИ","depth":14,"bounds":{"left":0.72772604,"top":0.09417398,"width":0.039893616,"height":0.044692736},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"БИТОВИ СМЕТКИ","depth":15,"bounds":{"left":0.73038566,"top":0.10933759,"width":0.034574468,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ПРЕВОДИ","depth":14,"bounds":{"left":0.76894945,"top":0.08619314,"width":0.025930852,"height":0.054269753},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ПРЕВОДИ","depth":15,"bounds":{"left":0.77160907,"top":0.10614525,"width":0.020611702,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"СПЕСТЯВАНЕ","depth":14,"bounds":{"left":0.7962101,"top":0.09417398,"width":0.031914894,"height":0.044692736},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"СПЕСТЯВАНЕ","depth":15,"bounds":{"left":0.79886967,"top":0.10933759,"width":0.026595745,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ФОНДОВЕ","depth":14,"bounds":{"left":0.8294548,"top":0.09417398,"width":0.026097074,"height":0.044692736},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ФОНДОВЕ","depth":15,"bounds":{"left":0.83211434,"top":0.10933759,"width":0.020777926,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ЗАЯВКИ","depth":14,"bounds":{"left":0.8568817,"top":0.09417398,"width":0.021609042,"height":0.044692736},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ЗАЯВКИ","depth":15,"bounds":{"left":0.85954124,"top":0.10933759,"width":0.016289894,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ИЗВЕСТИЯ","depth":14,"bounds":{"left":0.87982047,"top":0.09417398,"width":0.026928192,"height":0.044692736},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ИЗВЕСТИЯ","depth":15,"bounds":{"left":0.88248,"top":0.10933759,"width":0.021609042,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"СМАРТ ПРИЛОЖЕНИЯ","depth":14,"bounds":{"left":0.90807843,"top":0.09417398,"width":0.049534574,"height":0.044692736},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"СМАРТ ПРИЛОЖЕНИЯ","depth":15,"bounds":{"left":0.91073805,"top":0.10933759,"width":0.044215426,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"НАСТРОЙКИ","depth":14,"bounds":{"left":0.95894283,"top":0.09417398,"width":0.030418882,"height":0.044692736},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"НАСТРОЙКИ","depth":15,"bounds":{"left":0.9616024,"top":0.10933759,"width":0.025099734,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Нов превод","depth":14,"bounds":{"left":0.59491354,"top":0.15881884,"width":0.03174867,"height":0.030327214},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Нов превод","depth":15,"bounds":{"left":0.59890294,"top":0.16679968,"width":0.023769947,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Неизпратени","depth":14,"bounds":{"left":0.6286569,"top":0.15881884,"width":0.03507314,"height":0.030327214},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Неизпратени","depth":15,"bounds":{"left":0.63264626,"top":0.16679968,"width":0.027094414,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Архив","depth":14,"bounds":{"left":0.66572475,"top":0.15881884,"width":0.019946808,"height":0.030327214},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Архив","depth":15,"bounds":{"left":0.6697141,"top":0.16679968,"width":0.011968086,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"PDF Авиза","depth":14,"bounds":{"left":0.68766624,"top":0.15881884,"width":0.028756648,"height":0.030327214},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"PDF Авиза","depth":15,"bounds":{"left":0.6916556,"top":0.16679968,"width":0.020777926,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Автоматични","depth":14,"bounds":{"left":0.7184175,"top":0.15881884,"width":0.03507314,"height":0.030327214},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Автоматични","depth":15,"bounds":{"left":0.7224069,"top":0.16679968,"width":0.027094414,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Получатели","depth":14,"bounds":{"left":0.75548536,"top":0.15881884,"width":0.032247342,"height":0.030327214},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Получатели","depth":15,"bounds":{"left":0.75947475,"top":0.16679968,"width":0.024268618,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Готови бланки","depth":14,"bounds":{"left":0.7897274,"top":0.15881884,"width":0.03756649,"height":0.030327214},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Готови бланки","depth":15,"bounds":{"left":0.7937167,"top":0.16679968,"width":0.029587766,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Валутни курсове","depth":14,"bounds":{"left":0.82928854,"top":0.15881884,"width":0.042386968,"height":0.030327214},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Валутни курсове","depth":15,"bounds":{"left":0.83327794,"top":0.16679968,"width":0.034408245,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Договорени курсове","depth":14,"bounds":{"left":0.8736702,"top":0.15881884,"width":0.049867023,"height":0.030327214},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Договорени курсове","depth":15,"bounds":{"left":0.87765956,"top":0.16679968,"width":0.041888297,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Създаване/редактиране","depth":12,"bounds":{"left":0.59491354,"top":0.21308859,"width":0.06565824,"height":0.035913806},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Създаване/редактиране","depth":13,"bounds":{"left":0.59491354,"top":0.21987231,"width":0.06565824,"height":0.018355945},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Управление на бърз достъп до менюта.","depth":13,"bounds":{"left":0.6605718,"top":0.2150838,"width":0.021276595,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Създай нов превод","depth":12,"bounds":{"left":0.9155585,"top":0.21787709,"width":0.058011968,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Зареди готова бланка","depth":12,"bounds":{"left":0.8444149,"top":0.21787709,"width":0.06582447,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Нареждане за превод по сметка в Банка ДСК","depth":12,"bounds":{"left":0.601895,"top":0.2897047,"width":0.3650266,"height":0.018355945},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Нареждане за превод по сметка в Банка ДСК","depth":13,"bounds":{"left":0.601895,"top":0.2897047,"width":0.1200133,"height":0.018355945},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"От сметка","depth":15,"bounds":{"left":0.6072141,"top":0.34317636,"width":0.020279255,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Show All Items","depth":15,"bounds":{"left":0.8395944,"top":0.33838788,"width":0.015292553,"height":0.023942538},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Име на получател","depth":15,"bounds":{"left":0.6072141,"top":0.37031126,"width":0.036402926,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Show All Items","depth":15,"bounds":{"left":0.8395944,"top":0.36552274,"width":0.015292553,"height":0.023942538},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"IBAN / Валута на превода","depth":15,"bounds":{"left":0.6072141,"top":0.39744613,"width":0.05119681,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Сума","depth":16,"bounds":{"left":0.6072141,"top":0.424581,"width":0.010139627,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/ Валута","depth":16,"bounds":{"left":0.61735374,"top":0.424581,"width":0.017453458,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"0.00","depth":17,"bounds":{"left":0.66373,"top":0.4197925,"width":0.043550532,"height":0.023942538},"on_screen":true,"value":"0.00","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXTextField","text":"EUR","depth":17,"bounds":{"left":0.70894283,"top":0.4197925,"width":0.019448139,"height":0.023942538},"on_screen":true,"value":"EUR","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Основание","depth":16,"bounds":{"left":0.6072141,"top":0.4517159,"width":0.022606382,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Основание","depth":16,"bounds":{"left":0.66373,"top":0.44692737,"width":0.10638298,"height":0.023942538},"on_screen":true,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Още пояснения","depth":16,"bounds":{"left":0.6072141,"top":0.47885075,"width":0.032081116,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Още пояснения","depth":15,"bounds":{"left":0.66373,"top":0.47406226,"width":0.10638298,"height":0.023942538},"on_screen":true,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Преводът се изпълнява незабавно. В периода между 22:00 и 04:00 часа е възможно забавяне при приемане на преводите.","depth":13,"bounds":{"left":0.60920876,"top":0.53790903,"width":0.2847407,"height":0.016360734},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Преведи сега","depth":16,"bounds":{"left":0.6072141,"top":0.60614526,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"radio button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Преведи сега","depth":16,"bounds":{"left":0.6135306,"top":0.603751,"width":0.027925532,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Заяви дата на изпълнение","depth":16,"bounds":{"left":0.6072141,"top":0.63168395,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"radio button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Заяви дата на изпълнение","depth":16,"bounds":{"left":0.6135306,"top":0.6292897,"width":0.05518617,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Заяви периодично изпълнение","depth":16,"bounds":{"left":0.6072141,"top":0.6572227,"width":0.004654255,"height":0.011173184},"on_screen":true,"help_text":"","role_description":"radio button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Заяви периодично изпълнение","depth":16,"bounds":{"left":0.6135306,"top":0.6548284,"width":0.06549202,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"ЗАПАЗИ КАТО готова бланка","depth":18,"bounds":{"left":0.7943817,"top":0.6069433,"width":0.005984043,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ЗАПАЗИ КАТО","depth":18,"bounds":{"left":0.79305184,"top":0.62649643,"width":0.029587766,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"готова бланка","depth":18,"bounds":{"left":0.82263964,"top":0.62649643,"width":0.029089095,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Видимa за всички пълномощници","depth":17,"bounds":{"left":0.7943817,"top":0.68914604,"width":0.005984043,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Видимa за всички пълномощници","depth":18,"bounds":{"left":0.80369014,"top":0.68914604,"width":0.06981383,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"ЗАПАЗИ КАТО получател","depth":17,"bounds":{"left":0.7943817,"top":0.74022347,"width":0.005984043,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ЗАПАЗИ КАТО","depth":17,"bounds":{"left":0.79305184,"top":0.75977653,"width":0.028424202,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"получател","depth":17,"bounds":{"left":0.82147604,"top":0.75977653,"width":0.021276595,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Видим за всички пълномощници","depth":16,"bounds":{"left":0.7943817,"top":0.8224262,"width":0.005984043,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Видим за всички пълномощници","depth":17,"bounds":{"left":0.80369014,"top":0.8224262,"width":0.0674867,"height":0.014365523},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Преведи","depth":12,"bounds":{"left":0.93351066,"top":0.90782124,"width":0.033410903,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Запази","depth":12,"bounds":{"left":0.8971077,"top":0.90782124,"width":0.031416222,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"*Фиксиран курс за целите на двойно обозначение 1 EUR = 1.95583 BGN","depth":12,"bounds":{"left":0.6022274,"top":1.0,"width":0.16456117,"height":-0.021947384},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Потребителско ръководство - граждани","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Потребителско ръководство - граждани","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Общи условия за граждани","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Общи условия за граждани","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Тарифа за граждани","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Тарифа за граждани","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Call center:","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"*2375","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0700 10 375","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Потребителско ръководство - фирми","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Потребителско ръководство - фирми","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Общи условия за фирми","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Общи условия за фирми","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Тарифа за фирми","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Тарифа за фирми","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BIC/SWIFT на Банка ДСК: STSABGSF ©","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026 on DAIS eBank .NET","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
145653397252272928
|
-3628515709902544750
|
idle
|
accessibility
|
NULL
|
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
Getting Started DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
Getting Started · AFFiNE
Getting Started · AFFiNE
Screenpipe — Archive
Screenpipe — Archive
Download screenpipe — get started in minutes
Download screenpipe — get started in minutes
Self-Hosted Software and Apps
Self-Hosted Software and Apps
New Tab
New Tab
Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - [EMAIL] - Gmail
Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - [EMAIL] - Gmail
Завеждане на щета онлайн | Euroins
Завеждане на щета онлайн | Euroins
Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii
Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii
Nginx Proxy Manager
Nginx Proxy Manager
Location Logger
Location Logger
Providers - Admin - authentik
Providers - Admin - authentik
Booking.com: My Booking.com. Book your hotel now!
Booking.com: My Booking.com. Book your hotel now!
secure.booking.com/mybooking_archivedsummary.en-us.html?label=en-bg-booking-desktop-MtC3OoaoU_ML6gxkUZ2GoAS652796015943%3Apl%3Ata%3Ap1%3Ap2%3Aac%3Aap%3Aneg%3Afi%3Atikwd-65526620%3Alp9217204%3Ali%3Adec%3Adm&sid=6f757849d9e7c593112207a735846f8c&aid=2311236&a
secure.booking.com/mybooking_archivedsummary.en-us.html?label=en-bg-booking-desktop-MtC3OoaoU_ML6gxkUZ2GoAS652796015943%3Apl%3Ata%3Ap1%3Ap2%3Aac%3Aap%3Aneg%3Afi%3Atikwd-65526620%3Alp9217204%3Ali%3Adec%3Adm&sid=6f757849d9e7c593112207a735846f8c&aid=2311236&a
Hotel Bellisimo, Lozenets (updated prices 2026)
Hotel Bellisimo, Lozenets (updated prices 2026)
Hotel Bellisimo, Lozenets (updated prices 2026)
Hotel Bellisimo, Lozenets (updated prices 2026)
Електронно банкиране ДСК Директ от Банка ДСК
Електронно банкиране ДСК Директ от Банка ДСК
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
LUKAS KOVALIK
1 Входяща поща
1
Входяща поща
Обратна връзка
Обратна връзка
English
English
Изход
Изход
СРЕДСТВА
СРЕДСТВА
КРЕДИТИ
КРЕДИТИ
КАРТИ
КАРТИ
БИТОВИ СМЕТКИ
БИТОВИ СМЕТКИ
ПРЕВОДИ
ПРЕВОДИ
СПЕСТЯВАНЕ
СПЕСТЯВАНЕ
ФОНДОВЕ
ФОНДОВЕ
ЗАЯВКИ
ЗАЯВКИ
ИЗВЕСТИЯ
ИЗВЕСТИЯ
СМАРТ ПРИЛОЖЕНИЯ
СМАРТ ПРИЛОЖЕНИЯ
НАСТРОЙКИ
НАСТРОЙКИ
Нов превод
Нов превод
Неизпратени
Неизпратени
Архив
Архив
PDF Авиза
PDF Авиза
Автоматични
Автоматични
Получатели
Получатели
Готови бланки
Готови бланки
Валутни курсове
Валутни курсове
Договорени курсове
Договорени курсове
Създаване/редактиране
Създаване/редактиране
Управление на бърз достъп до менюта.
Създай нов превод
Зареди готова бланка
Нареждане за превод по сметка в Банка ДСК
Нареждане за превод по сметка в Банка ДСК
От сметка
Show All Items
Име на получател
Show All Items
IBAN / Валута на превода
Сума
/ Валута
0.00
EUR
Основание
Основание
Още пояснения
Още пояснения
Преводът се изпълнява незабавно. В периода между 22:00 и 04:00 часа е възможно забавяне при приемане на преводите.
Преведи сега
Преведи сега
Заяви дата на изпълнение
Заяви дата на изпълнение
Заяви периодично изпълнение
Заяви периодично изпълнение
ЗАПАЗИ КАТО готова бланка
ЗАПАЗИ КАТО
готова бланка
Видимa за всички пълномощници
Видимa за всички пълномощници
ЗАПАЗИ КАТО получател
ЗАПАЗИ КАТО
получател
Видим за всички пълномощници
Видим за всички пълномощници
Преведи
Запази
*Фиксиран курс за целите на двойно обозначение 1 EUR = 1.95583 BGN
Потребителско ръководство - граждани
Потребителско ръководство - граждани
Общи условия за граждани
Общи условия за граждани
Тарифа за граждани
Тарифа за граждани
Call center:
*2375
0700 10 375
Потребителско ръководство - фирми
Потребителско ръководство - фирми
Общи условия за фирми
Общи условия за фирми
Тарифа за фирми
Тарифа за фирми
BIC/SWIFT на Банка ДСК: STSABGSF ©
2026 on DAIS eBank .NET...
|
57365
|
NULL
|
NULL
|
NULL
|
|
57367
|
NULL
|
0
|
2026-05-19T09:54:09.138328+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779184449138_m1.jpg...
|
Firefox
|
Електронно банкиране ДСК Директ от Банка ДСК — Per Електронно банкиране ДСК Директ от Банка ДСК — Personal...
|
1
|
www.dskdirect.bg/page/default.aspx?user_id=1130906 www.dskdirect.bg/page/default.aspx?user_id=11309067&session_id=ba8bf9f8536711f19bee005056b06f6fIBtc-CT9adxNOghuRcFgEUAPLud7ys3OMSqp7BD6PWKcph04%2fN-PP4efrkCO7ke8P8JNFLl99q1rgLIAXWznbg%3d%3dU&xml_id=/bg-BG/01Individuals/05Transfers/01PaymentOrders/05Internal/...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
Getting Started DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
Getting Started · AFFiNE
Getting Started · AFFiNE
Screenpipe — Archive
Screenpipe — Archive
Download screenpipe — get started in minutes
Download screenpipe — get started in minutes
Self-Hosted Software and Apps
Self-Hosted Software and Apps
New Tab
New Tab
Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - [EMAIL] - Gmail
Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - [EMAIL] - Gmail
Завеждане на щета онлайн | Euroins
Завеждане на щета онлайн | Euroins
Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii
Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii
Nginx Proxy Manager
Nginx Proxy Manager
Location Logger
Location Logger
Providers - Admin - authentik
Providers - Admin - authentik
Booking.com: My Booking.com. Book your hotel now!
Booking.com: My Booking.com. Book your hotel now!
secure.booking.com/mybooking_archivedsummary.en-us.html?label=en-bg-booking-desktop-MtC3OoaoU_ML6gxkUZ2GoAS652796015943%3Apl%3Ata%3Ap1%3Ap2%3Aac%3Aap%3Aneg%3Afi%3Atikwd-65526620%3Alp9217204%3Ali%3Adec%3Adm&sid=6f757849d9e7c593112207a735846f8c&aid=2311236&a
secure.booking.com/mybooking_archivedsummary.en-us.html?label=en-bg-booking-desktop-MtC3OoaoU_ML6gxkUZ2GoAS652796015943%3Apl%3Ata%3Ap1%3Ap2%3Aac%3Aap%3Aneg%3Afi%3Atikwd-65526620%3Alp9217204%3Ali%3Adec%3Adm&sid=6f757849d9e7c593112207a735846f8c&aid=2311236&a
Hotel Bellisimo, Lozenets (updated prices 2026)
Hotel Bellisimo, Lozenets (updated prices 2026)
Hotel Bellisimo, Lozenets (updated prices 2026)
Hotel Bellisimo, Lozenets (updated prices 2026)
Електронно банкиране ДСК Директ от Банка ДСК
Електронно банкиране ДСК Директ от Банка ДСК
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
LUKAS KOVALIK
1 Входяща поща
1
Входяща поща
Обратна връзка
Обратна връзка
English
English
Изход
Изход
СРЕДСТВА
СРЕДСТВА
КРЕДИТИ
КРЕДИТИ
КАРТИ
КАРТИ
БИТОВИ СМЕТКИ
БИТОВИ СМЕТКИ
ПРЕВОДИ
ПРЕВОДИ
СПЕСТЯВАНЕ
СПЕСТЯВАНЕ
ФОНДОВЕ
ФОНДОВЕ
ЗАЯВКИ
ЗАЯВКИ
ИЗВЕСТИЯ
ИЗВЕСТИЯ
СМАРТ ПРИЛОЖЕНИЯ
СМАРТ ПРИЛОЖЕНИЯ
НАСТРОЙКИ
НАСТРОЙКИ
Нов превод
Нов превод
Неизпратени
Неизпратени
Архив
Архив
PDF Авиза
PDF Авиза
Автоматични
Автоматични
Получатели
Получатели
Готови бланки
Готови бланки
Валутни курсове
Валутни курсове
Договорени курсове
Договорени курсове
Създаване/редактиране
Създаване/редактиране
Управление на бърз достъп до менюта.
Създай нов превод
Зареди готова бланка
Нареждане за превод по сметка в Банка ДСК
Нареждане за превод по сметка в Банка ДСК
От сметка
Show All Items
Име на получател
Show All Items
IBAN / Валута на превода
Сума
/ Валута
0.00
EUR
Основание
Основание
Още пояснения
Още пояснения
Преводът се изпълнява незабавно. В периода между 22:00 и 04:00 часа е възможно забавяне при приемане на преводите.
Преведи сега
Преведи сега
Заяви дата на изпълнение
Заяви дата на изпълнение
Заяви периодично изпълнение
Заяви периодично изпълнение
ЗАПАЗИ КАТО готова бланка
ЗАПАЗИ КАТО
готова бланка
Видимa за всички пълномощници
Видимa за всички пълномощници
ЗАПАЗИ КАТО получател
ЗАПАЗИ КАТО
получател
Видим за всички пълномощници
Видим за всички пълномощници
Преведи
Запази
*Фиксиран курс за целите на двойно обозначение 1 EUR = 1.95583 BGN
Потребителско ръководство - граждани
Потребителско ръководство - граждани
Общи условия за граждани
Общи условия за граждани
Тарифа за граждани
Тарифа за граждани
Call center:
*2375
0700 10 375
Потребителско ръководство - фирми
Потребителско ръководство - фирми
Общи условия за фирми
Общи условия за фирми
Тарифа за фирми
Тарифа за фирми
BIC/SWIFT на Банка ДСК: STSABGSF ©
2026 on DAIS eBank .NET...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"DXP4800PLUS-B5F8","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"DXP4800PLUS-B5F8","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Getting Started · AFFiNE","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Getting Started · AFFiNE","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe — Archive","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Screenpipe — Archive","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Download screenpipe — get started in minutes","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Download screenpipe — get started in minutes","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Self-Hosted Software and Apps","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Self-Hosted Software and Apps","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - kovaliklukas@gmail.com - Gmail","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - kovaliklukas@gmail.com - Gmail","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Завеждане на щета онлайн | Euroins","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Завеждане на щета онлайн | Euroins","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Nginx Proxy Manager","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Nginx Proxy Manager","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Location Logger","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Location Logger","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Providers - Admin - authentik","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Providers - Admin - authentik","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Booking.com: My Booking.com. Book your hotel now!","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Booking.com: My Booking.com. Book your hotel now!","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"secure.booking.com/mybooking_archivedsummary.en-us.html?label=en-bg-booking-desktop-MtC3OoaoU_ML6gxkUZ2GoAS652796015943%3Apl%3Ata%3Ap1%3Ap2%3Aac%3Aap%3Aneg%3Afi%3Atikwd-65526620%3Alp9217204%3Ali%3Adec%3Adm&sid=6f757849d9e7c593112207a735846f8c&aid=2311236&a","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"secure.booking.com/mybooking_archivedsummary.en-us.html?label=en-bg-booking-desktop-MtC3OoaoU_ML6gxkUZ2GoAS652796015943%3Apl%3Ata%3Ap1%3Ap2%3Aac%3Aap%3Aneg%3Afi%3Atikwd-65526620%3Alp9217204%3Ali%3Adec%3Adm&sid=6f757849d9e7c593112207a735846f8c&aid=2311236&a","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Hotel Bellisimo, Lozenets (updated prices 2026)","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Hotel Bellisimo, Lozenets (updated prices 2026)","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Hotel Bellisimo, Lozenets (updated prices 2026)","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Hotel Bellisimo, Lozenets (updated prices 2026)","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Електронно банкиране ДСК Директ от Банка ДСК","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Електронно банкиране ДСК Директ от Банка ДСК","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.48576388,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.5086806,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.53194445,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.5552083,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Bitwarden","depth":6,"bounds":{"left":0.5784722,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LUKAS KOVALIK","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 Входяща поща","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Входяща поща","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Обратна връзка","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Обратна връзка","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"English","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"English","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Изход","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Изход","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"СРЕДСТВА","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"СРЕДСТВА","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"КРЕДИТИ","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"КРЕДИТИ","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"КАРТИ","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"КАРТИ","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"БИТОВИ СМЕТКИ","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"БИТОВИ СМЕТКИ","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ПРЕВОДИ","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ПРЕВОДИ","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"СПЕСТЯВАНЕ","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"СПЕСТЯВАНЕ","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ФОНДОВЕ","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ФОНДОВЕ","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ЗАЯВКИ","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ЗАЯВКИ","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ИЗВЕСТИЯ","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ИЗВЕСТИЯ","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"СМАРТ ПРИЛОЖЕНИЯ","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"СМАРТ ПРИЛОЖЕНИЯ","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"НАСТРОЙКИ","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"НАСТРОЙКИ","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Нов превод","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Нов превод","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Неизпратени","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Неизпратени","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Архив","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Архив","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"PDF Авиза","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"PDF Авиза","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Автоматични","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Автоматични","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Получатели","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Получатели","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Готови бланки","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Готови бланки","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Валутни курсове","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Валутни курсове","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Договорени курсове","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Договорени курсове","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Създаване/редактиране","depth":12,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Създаване/редактиране","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Управление на бърз достъп до менюта.","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Създай нов превод","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Зареди готова бланка","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Нареждане за превод по сметка в Банка ДСК","depth":12,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Нареждане за превод по сметка в Банка ДСК","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"От сметка","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Show All Items","depth":15,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Име на получател","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Show All Items","depth":15,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"IBAN / Валута на превода","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Сума","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/ Валута","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"0.00","depth":17,"on_screen":true,"value":"0.00","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXTextField","text":"EUR","depth":17,"on_screen":true,"value":"EUR","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Основание","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Основание","depth":16,"on_screen":true,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Още пояснения","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Още пояснения","depth":15,"on_screen":true,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Преводът се изпълнява незабавно. В периода между 22:00 и 04:00 часа е възможно забавяне при приемане на преводите.","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Преведи сега","depth":16,"on_screen":true,"help_text":"","role_description":"radio button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Преведи сега","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Заяви дата на изпълнение","depth":16,"on_screen":true,"help_text":"","role_description":"radio button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Заяви дата на изпълнение","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Заяви периодично изпълнение","depth":16,"on_screen":true,"help_text":"","role_description":"radio button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Заяви периодично изпълнение","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"ЗАПАЗИ КАТО готова бланка","depth":18,"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ЗАПАЗИ КАТО","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"готова бланка","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Видимa за всички пълномощници","depth":17,"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Видимa за всички пълномощници","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"ЗАПАЗИ КАТО получател","depth":17,"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ЗАПАЗИ КАТО","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"получател","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Видим за всички пълномощници","depth":16,"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Видим за всички пълномощници","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Преведи","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Запази","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"*Фиксиран курс за целите на двойно обозначение 1 EUR = 1.95583 BGN","depth":12,"bounds":{"left":0.69340277,"top":0.030555556,"width":0.30659723,"height":0.022777777},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Потребителско ръководство - граждани","depth":13,"bounds":{"left":0.7083333,"top":0.24333334,"width":0.19618055,"height":0.022777777},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Потребителско ръководство - граждани","depth":14,"bounds":{"left":0.7083333,"top":0.24333334,"width":0.19618055,"height":0.022777777},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Общи условия за граждани","depth":13,"bounds":{"left":0.7395833,"top":0.275,"width":0.13333334,"height":0.022777777},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Общи условия за граждани","depth":14,"bounds":{"left":0.7395833,"top":0.275,"width":0.13333334,"height":0.022777777},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Тарифа за граждани","depth":13,"bounds":{"left":0.75625,"top":0.30666667,"width":0.1,"height":0.022777777},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Тарифа за граждани","depth":14,"bounds":{"left":0.75625,"top":0.30666667,"width":0.1,"height":0.022777777},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Call center:","depth":13,"bounds":{"left":0.99409723,"top":0.24333334,"width":0.005902767,"height":0.022777777},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"*2375","depth":13,"bounds":{"left":1.0,"top":0.24333334,"width":-0.057291627,"height":0.022777777},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0700 10 375","depth":13,"bounds":{"left":1.0,"top":0.24333334,"width":-0.097569466,"height":0.022777777},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Потребителско ръководство - фирми","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Потребителско ръководство - фирми","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Общи условия за фирми","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Общи условия за фирми","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Тарифа за фирми","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Тарифа за фирми","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BIC/SWIFT на Банка ДСК: STSABGSF ©","depth":12,"bounds":{"left":0.9607639,"top":0.35055557,"width":0.03923613,"height":0.017222222},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026 on DAIS eBank .NET","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
145653397252272928
|
-3628515709902544750
|
idle
|
accessibility
|
NULL
|
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
Getting Started DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
Getting Started · AFFiNE
Getting Started · AFFiNE
Screenpipe — Archive
Screenpipe — Archive
Download screenpipe — get started in minutes
Download screenpipe — get started in minutes
Self-Hosted Software and Apps
Self-Hosted Software and Apps
New Tab
New Tab
Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - [EMAIL] - Gmail
Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - [EMAIL] - Gmail
Завеждане на щета онлайн | Euroins
Завеждане на щета онлайн | Euroins
Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii
Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii
Nginx Proxy Manager
Nginx Proxy Manager
Location Logger
Location Logger
Providers - Admin - authentik
Providers - Admin - authentik
Booking.com: My Booking.com. Book your hotel now!
Booking.com: My Booking.com. Book your hotel now!
secure.booking.com/mybooking_archivedsummary.en-us.html?label=en-bg-booking-desktop-MtC3OoaoU_ML6gxkUZ2GoAS652796015943%3Apl%3Ata%3Ap1%3Ap2%3Aac%3Aap%3Aneg%3Afi%3Atikwd-65526620%3Alp9217204%3Ali%3Adec%3Adm&sid=6f757849d9e7c593112207a735846f8c&aid=2311236&a
secure.booking.com/mybooking_archivedsummary.en-us.html?label=en-bg-booking-desktop-MtC3OoaoU_ML6gxkUZ2GoAS652796015943%3Apl%3Ata%3Ap1%3Ap2%3Aac%3Aap%3Aneg%3Afi%3Atikwd-65526620%3Alp9217204%3Ali%3Adec%3Adm&sid=6f757849d9e7c593112207a735846f8c&aid=2311236&a
Hotel Bellisimo, Lozenets (updated prices 2026)
Hotel Bellisimo, Lozenets (updated prices 2026)
Hotel Bellisimo, Lozenets (updated prices 2026)
Hotel Bellisimo, Lozenets (updated prices 2026)
Електронно банкиране ДСК Директ от Банка ДСК
Електронно банкиране ДСК Директ от Банка ДСК
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
LUKAS KOVALIK
1 Входяща поща
1
Входяща поща
Обратна връзка
Обратна връзка
English
English
Изход
Изход
СРЕДСТВА
СРЕДСТВА
КРЕДИТИ
КРЕДИТИ
КАРТИ
КАРТИ
БИТОВИ СМЕТКИ
БИТОВИ СМЕТКИ
ПРЕВОДИ
ПРЕВОДИ
СПЕСТЯВАНЕ
СПЕСТЯВАНЕ
ФОНДОВЕ
ФОНДОВЕ
ЗАЯВКИ
ЗАЯВКИ
ИЗВЕСТИЯ
ИЗВЕСТИЯ
СМАРТ ПРИЛОЖЕНИЯ
СМАРТ ПРИЛОЖЕНИЯ
НАСТРОЙКИ
НАСТРОЙКИ
Нов превод
Нов превод
Неизпратени
Неизпратени
Архив
Архив
PDF Авиза
PDF Авиза
Автоматични
Автоматични
Получатели
Получатели
Готови бланки
Готови бланки
Валутни курсове
Валутни курсове
Договорени курсове
Договорени курсове
Създаване/редактиране
Създаване/редактиране
Управление на бърз достъп до менюта.
Създай нов превод
Зареди готова бланка
Нареждане за превод по сметка в Банка ДСК
Нареждане за превод по сметка в Банка ДСК
От сметка
Show All Items
Име на получател
Show All Items
IBAN / Валута на превода
Сума
/ Валута
0.00
EUR
Основание
Основание
Още пояснения
Още пояснения
Преводът се изпълнява незабавно. В периода между 22:00 и 04:00 часа е възможно забавяне при приемане на преводите.
Преведи сега
Преведи сега
Заяви дата на изпълнение
Заяви дата на изпълнение
Заяви периодично изпълнение
Заяви периодично изпълнение
ЗАПАЗИ КАТО готова бланка
ЗАПАЗИ КАТО
готова бланка
Видимa за всички пълномощници
Видимa за всички пълномощници
ЗАПАЗИ КАТО получател
ЗАПАЗИ КАТО
получател
Видим за всички пълномощници
Видим за всички пълномощници
Преведи
Запази
*Фиксиран курс за целите на двойно обозначение 1 EUR = 1.95583 BGN
Потребителско ръководство - граждани
Потребителско ръководство - граждани
Общи условия за граждани
Общи условия за граждани
Тарифа за граждани
Тарифа за граждани
Call center:
*2375
0700 10 375
Потребителско ръководство - фирми
Потребителско ръководство - фирми
Общи условия за фирми
Общи условия за фирми
Тарифа за фирми
Тарифа за фирми
BIC/SWIFT на Банка ДСК: STSABGSF ©
2026 on DAIS eBank .NET...
|
57366
|
NULL
|
NULL
|
NULL
|
|
57317
|
NULL
|
0
|
2026-05-19T09:49:20.848079+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779184160848_m2.jpg...
|
Firefox
|
Електронно банкиране ДСК Директ от Банка ДСК — Per Електронно банкиране ДСК Директ от Банка ДСК — Personal...
|
1
|
www.dskdirect.bg/page/?session_id=ba8bf9f8536711f1 www.dskdirect.bg/page/?session_id=ba8bf9f8536711f19bee005056b06f6fIBtc-CT9adxNOghuRcFgEUAPLud7ys3OMSqp7BD6PWKcph04/N-PP4efrkCO7ke8P8JNFLl99q1rgLIAXWznbg==U&user_id=11309067&xml_id=/bg-BG/01Individuals/06myDSK/02Profile/02Password/.expiredPassword...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
rireroFV faVsco.js~%9 JY-20676-delete-report-relat rireroFV faVsco.js~%9 JY-20676-delete-report-related-objectsroledey© AskAnythingPromptDto.php® ActivityController.php© AskAnythingPromptService.php xAsKAnywingPromptoto.orgAskAnythingController.php© AskAnythingPrompt.phppip aplyr.onp( EventsAsKAnytningPromptservice.ongc) Automateakeport.pnpc Historyservice.ongD AskJiminnyAiWAWSBillingManagementu cachew countryDatabaseDatadogDatettime• DeallnsightsN DealRisks1N GlasticSearchM EloquentEncoding• EncryptionDESD Faker• FeatureFlagsD FFMpeg• FileSystem• Gong_ cuzzienutou reyPolntsKIOSK_ LanquageDetectionW LOCKSW Math_Mediapioeline2 MobileSettinasNudaeIM ParagranhBreaker1 PartitionedCookieM PlavbackPade• PlaylistProphetM PronhetAfD ProsperWorksM Auonc© AskAnythingPromptServiceTest.php) search.phpclass AskAnythingPromptService233public function editaAskAnythingPrompt $prompt,User suserstring $title,string $content,array $shareUsersUvids,array $shareGroupsUuids): AskAnythingPromptDto {...}public function delete(AskAnythingPrompt $prompt,User $user): AskAnythingPrompt {..}public function reorder(User suserarray spromptuulds,): void {...}* doaram AskAnuthinaPromor Soromot* dreturn arraul arrau<strina>. arrau<string>1 usageprivate function getReceiverUuids(AskAnythingPrompt $prompt): array{...}nrivate function deletePromntTfNoRelations(AskAnvthi.naPromot Soromot: void212if (Sthis->askAnythingRepository-›findSharedUsersAndGroupsByPromptId(Sprompt->getId())->isEmpty 214// Disable and orphan any AutomatedReports that use this prompt$prompt->automatedReports() ->withTrashed() -›update(['ask_anything_prompt_id' => null,216217'status' = false,// Delete only if there are no other relations to it.Sthis->askAnythingRepository->deletePrompt(Sprompt);private function recreatePromptsForEachRelation(AskAnythingPrompt $prompt): voidf...,E custom.logA console [STAGING]E laravel.logYC) CoachTx: AUA2X2 ^ v 182183—185SELECT ar.id, ar.uuiFROM automated_reporJOIN automated_reporWHERE a.tYRe = 'askLIMIT 10;188SELECT * FROM automaSELECT * FROM automaUPDATE automated_repSELECT * FROM automaSELECT * FROM automasELEl x rkuM aUcomdselect * from activiselect * trom ask aiSELECTINNEk JUIN automateWHERETEAND JSON CONTAINSSELECT * FROM automSELECT * FROM automSELECT * FROM usersselect * from teamsselect * from eom coselect * from usersCELECT * CPOM cocialselect * from activiano recording staceand status = 'compleCCICAT & CO0M ontiniselect * from leads:SELECT * FROM activiSELECT * FROM activiSFLFCT * FROM activ:Socket fail to connect to host:addr(I) DXP4800PLUS-B5F8Gettina Started • AFFiNE® Screenpipe - ArchiveDownload screenpipe - ge*• Self-Hosted Software and A* New Tabи Помогнете ни ла развивалDARow nahe Ha mora ohnau*Kontakt " Velvyslanectvo SioNginx Proxy ManagerA Location Logge:• Providers - Admin - authentB. Booking.com: My Booking.coB. secure.booking.com/mybocB. Hotel Bellisimo. Lozenets (ulB. Hotel Bellisimo, Lozenets (UFЕлектронно банкиране— New Tab50 lihl 1 Support Daily - in 2h 11m100% L28• Tue 19 May 12:49:20www.askalrect.og/page//session_lo)05056b06f6fIBtc-CT9adxNOghuRcFgEUAPLud7LUKAS KOVALIK X 1 Входяща поща ) Обратна връзка@ English IИзходС одскдиректСРЕДСТВАКРЕДИТИкартиБИТОВИ СМЕТкИ преводи спестяванЕ фондовЕ•зАявКИ•извЕстиясмарт приложенияНАСТРОЙКИОбщи•ПотребителскиСигурност)ТехническиSMs код с цифровіKEП T•ТоукьнDSKIУправление насертификат |mlokenПрепоръчителна смяна на паролаМоля, сменете Вашата парола!От съображения за сигурност банка дск препорьчва периодична смяна на вашата парола. Това предупреждение ще оьде показвано винаги, когатоизтече препоръчителният срок на валидност на Вашата парола.можете па поолължите, като напоавите изооо чоез оитоните в коая на съоошението.Ако желаете да смените веднага своята парола изберете бутон „Промени";Ако желаете да продължите използването на настоящата Ви парола за още един период, изберете бутон „Продължи".Продължи със старата паролаі ромени сега*Фиксиран курс за целите на двойно обозначение 1 EUR = 1.95583 BGN|Телефон и E-mail+259877****18 АКТИВЕНVivacomKovaliklukas@gmail.comС банкадскotp groupCall center: D *2375 € 0700 10 375Потребителско рьководство - гражданиОбщи условия за гражданиПотребителско ръководство - фирмиОбщи условия за фирми...
|
NULL
|
-7589514472160766731
|
NULL
|
click
|
ocr
|
NULL
|
rireroFV faVsco.js~%9 JY-20676-delete-report-relat rireroFV faVsco.js~%9 JY-20676-delete-report-related-objectsroledey© AskAnythingPromptDto.php® ActivityController.php© AskAnythingPromptService.php xAsKAnywingPromptoto.orgAskAnythingController.php© AskAnythingPrompt.phppip aplyr.onp( EventsAsKAnytningPromptservice.ongc) Automateakeport.pnpc Historyservice.ongD AskJiminnyAiWAWSBillingManagementu cachew countryDatabaseDatadogDatettime• DeallnsightsN DealRisks1N GlasticSearchM EloquentEncoding• EncryptionDESD Faker• FeatureFlagsD FFMpeg• FileSystem• Gong_ cuzzienutou reyPolntsKIOSK_ LanquageDetectionW LOCKSW Math_Mediapioeline2 MobileSettinasNudaeIM ParagranhBreaker1 PartitionedCookieM PlavbackPade• PlaylistProphetM PronhetAfD ProsperWorksM Auonc© AskAnythingPromptServiceTest.php) search.phpclass AskAnythingPromptService233public function editaAskAnythingPrompt $prompt,User suserstring $title,string $content,array $shareUsersUvids,array $shareGroupsUuids): AskAnythingPromptDto {...}public function delete(AskAnythingPrompt $prompt,User $user): AskAnythingPrompt {..}public function reorder(User suserarray spromptuulds,): void {...}* doaram AskAnuthinaPromor Soromot* dreturn arraul arrau<strina>. arrau<string>1 usageprivate function getReceiverUuids(AskAnythingPrompt $prompt): array{...}nrivate function deletePromntTfNoRelations(AskAnvthi.naPromot Soromot: void212if (Sthis->askAnythingRepository-›findSharedUsersAndGroupsByPromptId(Sprompt->getId())->isEmpty 214// Disable and orphan any AutomatedReports that use this prompt$prompt->automatedReports() ->withTrashed() -›update(['ask_anything_prompt_id' => null,216217'status' = false,// Delete only if there are no other relations to it.Sthis->askAnythingRepository->deletePrompt(Sprompt);private function recreatePromptsForEachRelation(AskAnythingPrompt $prompt): voidf...,E custom.logA console [STAGING]E laravel.logYC) CoachTx: AUA2X2 ^ v 182183—185SELECT ar.id, ar.uuiFROM automated_reporJOIN automated_reporWHERE a.tYRe = 'askLIMIT 10;188SELECT * FROM automaSELECT * FROM automaUPDATE automated_repSELECT * FROM automaSELECT * FROM automasELEl x rkuM aUcomdselect * from activiselect * trom ask aiSELECTINNEk JUIN automateWHERETEAND JSON CONTAINSSELECT * FROM automSELECT * FROM automSELECT * FROM usersselect * from teamsselect * from eom coselect * from usersCELECT * CPOM cocialselect * from activiano recording staceand status = 'compleCCICAT & CO0M ontiniselect * from leads:SELECT * FROM activiSELECT * FROM activiSFLFCT * FROM activ:Socket fail to connect to host:addr(I) DXP4800PLUS-B5F8Gettina Started • AFFiNE® Screenpipe - ArchiveDownload screenpipe - ge*• Self-Hosted Software and A* New Tabи Помогнете ни ла развивалDARow nahe Ha mora ohnau*Kontakt " Velvyslanectvo SioNginx Proxy ManagerA Location Logge:• Providers - Admin - authentB. Booking.com: My Booking.coB. secure.booking.com/mybocB. Hotel Bellisimo. Lozenets (ulB. Hotel Bellisimo, Lozenets (UFЕлектронно банкиране— New Tab50 lihl 1 Support Daily - in 2h 11m100% L28• Tue 19 May 12:49:20www.askalrect.og/page//session_lo)05056b06f6fIBtc-CT9adxNOghuRcFgEUAPLud7LUKAS KOVALIK X 1 Входяща поща ) Обратна връзка@ English IИзходС одскдиректСРЕДСТВАКРЕДИТИкартиБИТОВИ СМЕТкИ преводи спестяванЕ фондовЕ•зАявКИ•извЕстиясмарт приложенияНАСТРОЙКИОбщи•ПотребителскиСигурност)ТехническиSMs код с цифровіKEП T•ТоукьнDSKIУправление насертификат |mlokenПрепоръчителна смяна на паролаМоля, сменете Вашата парола!От съображения за сигурност банка дск препорьчва периодична смяна на вашата парола. Това предупреждение ще оьде показвано винаги, когатоизтече препоръчителният срок на валидност на Вашата парола.можете па поолължите, като напоавите изооо чоез оитоните в коая на съоошението.Ако желаете да смените веднага своята парола изберете бутон „Промени";Ако желаете да продължите използването на настоящата Ви парола за още един период, изберете бутон „Продължи".Продължи със старата паролаі ромени сега*Фиксиран курс за целите на двойно обозначение 1 EUR = 1.95583 BGN|Телефон и E-mail+259877****18 АКТИВЕНVivacomKovaliklukas@gmail.comС банкадскotp groupCall center: D *2375 € 0700 10 375Потребителско рьководство - гражданиОбщи условия за гражданиПотребителско ръководство - фирмиОбщи условия за фирми...
|
57315
|
NULL
|
NULL
|
NULL
|
|
57316
|
NULL
|
0
|
2026-05-19T09:48:59.406425+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779184139406_m1.jpg...
|
Slack
|
Galya Dimitrova (DM) - Jiminny Inc - 5 new items - Galya Dimitrova (DM) - Jiminny Inc - 5 new items - Slack...
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
jiminny-x-integration-app
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
curiosity_lab
engineering
general
jiminny-bg
platform-tickets
product_launches
random
releases
sofia-office
support
thank-yous
the_people_of_jiminny
Galya Dimitrova
Nikolay Yankov
Vasil Vasilev
Aneliya Angelova
Stefka Stoyanova
Stoyan Tomov
Todor Stamatov
Mario Georgiev
Nikolay Ivanov
James Graham
Stoyan Tanev
Lukas Kovalik
you
Jira Cloud
Toast
Messages
Messages
Files
Files
Untitled
Untitled
Add and Edit Channel Tabs
Canvas
List
Folder
Jump to date
Yesterday at 6:50:16 PM
6:50
утре на дейлито виж с Ники Я дали ще те отблокира по сторитата за триене на Saved Search и промптове. Ако няма да може тогава докато го чакаш може да отметнем това от следващия спринт -
https://jiminny.atlassian.net/browse/JY-20912
https://jiminny.atlassian.net/browse/JY-20912
Jira Cloud
Jira Cloud
Jira Cloud Story JY-20912 Fallback mechanism for users with active SF tokens for CRM Matching Story JY-20912 in Jira Cloud Preview in Slack Status Backlog Priority Medium Medium Assignee Unassigned Unassigned As of yesterday at 6:50 PM Refresh Open in Jira ✨ Summarise
Fallback mechanism for users with active SF tokens for CRM Matching
Story JY-20912 in Jira Cloud
Preview in Slack
Status
Backlog
Priority
Medium
Assignee
Unassigned
As of yesterday at 6:50 PM
Refresh
Open in Jira
✨ Summarise
Open in browser
Share Story JY-20912
View conversations
More actions
Lukas Kovalik
Yesterday at 6:50:58 PM
6:50 PM
добре, ще го видя
Galya Dimitrova
Yesterday at 6:51:23 PM
6:51 PM
аз няма да успея да вляза че сигурно ще спя
Lukas Kovalik...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":14,"bounds":{"left":0.51180553,"top":0.08111111,"width":0.025,"height":0.04},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":14,"bounds":{"left":0.50625,"top":0.14,"width":0.036111113,"height":0.075555556},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":16,"bounds":{"left":0.5138889,"top":0.19222222,"width":0.020833334,"height":0.015555556},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":14,"bounds":{"left":0.50625,"top":0.21555555,"width":0.036111113,"height":0.075555556},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":16,"bounds":{"left":0.5159722,"top":0.26777777,"width":0.016666668,"height":0.015555556},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":14,"bounds":{"left":0.50625,"top":0.2911111,"width":0.036111113,"height":0.075555556},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":16,"bounds":{"left":0.51111114,"top":0.34333333,"width":0.027083334,"height":0.015555556},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.51111114,"top":0.34333333,"width":0.0055555557,"height":0.015555556}},{"char_start":1,"char_count":7,"bounds":{"left":0.5159722,"top":0.34333333,"width":0.022222223,"height":0.015555556}}],"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":14,"bounds":{"left":0.50625,"top":0.36666667,"width":0.036111113,"height":0.075555556},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":16,"bounds":{"left":0.51666665,"top":0.4188889,"width":0.015972223,"height":0.015555556},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.51666665,"top":0.4188889,"width":0.004166667,"height":0.015555556}},{"char_start":1,"char_count":4,"bounds":{"left":0.5208333,"top":0.4188889,"width":0.011805556,"height":0.015555556}}],"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":14,"bounds":{"left":0.50625,"top":0.4422222,"width":0.036111113,"height":0.075555556},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":16,"bounds":{"left":0.5152778,"top":0.49444443,"width":0.018055556,"height":0.015555556},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":14,"bounds":{"left":0.50625,"top":0.5177778,"width":0.036111113,"height":0.075555556},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":16,"bounds":{"left":0.5152778,"top":0.57,"width":0.01875,"height":0.015555556},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":21,"bounds":{"left":0.57708335,"top":0.12777779,"width":0.039583333,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":21,"bounds":{"left":0.57708335,"top":0.12777779,"width":0.036805555,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":21,"bounds":{"left":0.57708335,"top":0.12777779,"width":0.038194444,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":21,"bounds":{"left":0.57708335,"top":0.12777779,"width":0.06111111,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":21,"bounds":{"left":0.68472224,"top":0.12777779,"width":0.0055555557,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":21,"bounds":{"left":0.57708335,"top":0.12777779,"width":0.050694443,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"jiminny-x-integration-app","depth":23,"bounds":{"left":0.58819443,"top":0.12777779,"width":0.09166667,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":23,"bounds":{"left":0.58819443,"top":0.12777779,"width":0.093055554,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":23,"bounds":{"left":0.58819443,"top":0.12777779,"width":0.046527777,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":23,"bounds":{"left":0.58819443,"top":0.12777779,"width":0.025694445,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":23,"bounds":{"left":0.58819443,"top":0.12777779,"width":0.038194444,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"bugs","depth":23,"bounds":{"left":0.58819443,"top":0.12777779,"width":0.022222223,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"confusion-clinic","depth":23,"bounds":{"left":0.58819443,"top":0.12777779,"width":0.072222225,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"curiosity_lab","depth":23,"bounds":{"left":0.58819443,"top":0.12777779,"width":0.057638887,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"engineering","depth":23,"bounds":{"left":0.58819443,"top":0.12777779,"width":0.054166667,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"general","depth":23,"bounds":{"left":0.58819443,"top":0.12777779,"width":0.034027778,"height":0.007777778},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"jiminny-bg","depth":23,"bounds":{"left":0.58819443,"top":0.14666666,"width":0.048611112,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"platform-tickets","depth":23,"bounds":{"left":0.58819443,"top":0.17777778,"width":0.072916664,"height":0.02},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.58819443,"top":0.17777778,"width":0.00625,"height":0.02}},{"char_start":1,"char_count":15,"bounds":{"left":0.59444445,"top":0.17777778,"width":0.06666667,"height":0.02}}],"role_description":"text"},{"role":"AXStaticText","text":"product_launches","depth":23,"bounds":{"left":0.58819443,"top":0.20888889,"width":0.08055556,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"random","depth":23,"bounds":{"left":0.58819443,"top":0.24,"width":0.035416666,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"releases","depth":23,"bounds":{"left":0.58819443,"top":0.2711111,"width":0.038194444,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"sofia-office","depth":23,"bounds":{"left":0.58819443,"top":0.30222222,"width":0.05138889,"height":0.02},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.58819443,"top":0.30222222,"width":0.0048611113,"height":0.02}},{"char_start":1,"char_count":11,"bounds":{"left":0.59305555,"top":0.30222222,"width":0.045833334,"height":0.02}}],"role_description":"text"},{"role":"AXStaticText","text":"support","depth":23,"bounds":{"left":0.58819443,"top":0.33333334,"width":0.036111113,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"thank-yous","depth":23,"bounds":{"left":0.58819443,"top":0.36444443,"width":0.05138889,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"the_people_of_jiminny","depth":23,"bounds":{"left":0.58819443,"top":0.39555556,"width":0.094444446,"height":0.02},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.58819443,"top":0.39555556,"width":0.004166667,"height":0.02}},{"char_start":1,"char_count":20,"bounds":{"left":0.5923611,"top":0.39555556,"width":0.09861111,"height":0.02}}],"role_description":"text"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":23,"bounds":{"left":0.58819443,"top":0.46888888,"width":0.07361111,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":23,"bounds":{"left":0.58819443,"top":0.5,"width":0.06875,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Vasil Vasilev","depth":23,"bounds":{"left":0.58819443,"top":0.5311111,"width":0.055555556,"height":0.02},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.58819443,"top":0.5311111,"width":0.00625,"height":0.02}},{"char_start":1,"char_count":12,"bounds":{"left":0.59444445,"top":0.5311111,"width":0.048611112,"height":0.02}}],"role_description":"text"},{"role":"AXStaticText","text":"Aneliya Angelova","depth":23,"bounds":{"left":0.58819443,"top":0.56222224,"width":0.07847222,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Stefka Stoyanova","depth":23,"bounds":{"left":0.58819443,"top":0.5933333,"width":0.079166666,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Stoyan Tomov","depth":23,"bounds":{"left":0.58819443,"top":0.6244444,"width":0.06458333,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Todor Stamatov","depth":23,"bounds":{"left":0.58819443,"top":0.65555555,"width":0.072222225,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Mario Georgiev","depth":23,"bounds":{"left":0.58819443,"top":0.68666667,"width":0.07152778,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Ivanov","depth":23,"bounds":{"left":0.58819443,"top":0.7177778,"width":0.06736111,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"James Graham","depth":23,"bounds":{"left":0.58819443,"top":0.7488889,"width":0.06666667,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Stoyan Tanev","depth":23,"bounds":{"left":0.58819443,"top":0.78,"width":0.060416665,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":23,"bounds":{"left":0.58819443,"top":0.8111111,"width":0.061805554,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"you","depth":23,"bounds":{"left":0.65555555,"top":0.8111111,"width":0.013194445,"height":0.02},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.65555555,"top":0.8111111,"width":0.0048611113,"height":0.02}},{"char_start":1,"char_count":2,"bounds":{"left":0.66041666,"top":0.8111111,"width":0.011805556,"height":0.02}}],"role_description":"text"},{"role":"AXStaticText","text":"Jira Cloud","depth":23,"bounds":{"left":0.58819443,"top":0.8844444,"width":0.046527777,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Toast","depth":23,"bounds":{"left":0.58819443,"top":0.91555554,"width":0.025694445,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Messages","depth":17,"bounds":{"left":0.71319443,"top":0.12777779,"width":0.06458333,"height":0.04222222},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Messages","depth":19,"bounds":{"left":0.7326389,"top":0.14,"width":0.039583333,"height":0.017777778},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":17,"bounds":{"left":0.7798611,"top":0.12777779,"width":0.04375,"height":0.04222222},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":19,"bounds":{"left":0.79930556,"top":0.14,"width":0.01875,"height":0.017777778},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.79930556,"top":0.14,"width":0.0055555557,"height":0.017777778}},{"char_start":1,"char_count":4,"bounds":{"left":0.8048611,"top":0.14,"width":0.013194445,"height":0.017777778}}],"role_description":"text"},{"role":"AXRadioButton","text":"Untitled","depth":17,"bounds":{"left":0.8263889,"top":0.12777779,"width":0.06111111,"height":0.04222222},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Untitled","depth":19,"bounds":{"left":0.84583336,"top":0.14,"width":0.033333335,"height":0.017777778},"on_screen":true,"role_description":"text"},{"role":"AXPopUpButton","text":"Add and Edit Channel Tabs","depth":17,"bounds":{"left":0.88958335,"top":0.12777779,"width":0.022916667,"height":0.04222222},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Canvas","depth":17,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"List","depth":17,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Folder","depth":17,"on_screen":false,"role_description":"text"},{"role":"AXPopUpButton","text":"Jump to date","depth":23,"bounds":{"left":0.81527776,"top":0.17666666,"width":0.068055555,"height":0.031111112},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Yesterday at 6:50:16 PM","depth":25,"bounds":{"left":0.72430557,"top":0.16111112,"width":0.016666668,"height":0.0011111111},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6:50","depth":26,"bounds":{"left":0.72430557,"top":0.16111112,"width":0.016666668,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"утре на дейлито виж с Ники Я дали ще те отблокира по сторитата за триене на Saved Search и промптове. Ако няма да може тогава докато го чакаш може да отметнем това от следващия спринт -","depth":25,"bounds":{"left":0.7465278,"top":0.16111112,"width":0.22083333,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"https://jiminny.atlassian.net/browse/JY-20912","depth":25,"bounds":{"left":0.7465278,"top":0.16111112,"width":0.21111111,"height":0.0011111111},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"https://jiminny.atlassian.net/browse/JY-20912","depth":26,"bounds":{"left":0.7465278,"top":0.16111112,"width":0.21111111,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Jira Cloud","depth":24,"bounds":{"left":0.7465278,"top":0.16111112,"width":0.039583333,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Jira Cloud","depth":24,"bounds":{"left":0.7888889,"top":0.16111112,"width":0.011111111,"height":0.0011111111},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXButton","text":"Jira Cloud Story JY-20912 Fallback mechanism for users with active SF tokens for CRM Matching Story JY-20912 in Jira Cloud Preview in Slack Status Backlog Priority Medium Medium Assignee Unassigned Unassigned As of yesterday at 6:50 PM Refresh Open in Jira ✨ Summarise","depth":26,"bounds":{"left":0.7465278,"top":0.16111112,"width":0.2361111,"height":0.0011111111},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Fallback mechanism for users with active SF tokens for CRM Matching","depth":27,"bounds":{"left":0.7888889,"top":0.16111112,"width":0.17916666,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Story JY-20912 in Jira Cloud","depth":28,"bounds":{"left":0.7888889,"top":0.16111112,"width":0.11319444,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Preview in Slack","depth":28,"bounds":{"left":0.7888889,"top":0.16111112,"width":0.06527778,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Status","depth":27,"bounds":{"left":0.7888889,"top":0.16111112,"width":0.025,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Backlog","depth":27,"bounds":{"left":0.7916667,"top":0.16111112,"width":0.036111113,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Priority","depth":27,"bounds":{"left":0.8472222,"top":0.16111112,"width":0.029166667,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Medium","depth":27,"bounds":{"left":0.86388886,"top":0.16111112,"width":0.0375,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Assignee","depth":27,"bounds":{"left":0.7888889,"top":0.16111112,"width":0.035416666,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Unassigned","depth":27,"bounds":{"left":0.8055556,"top":0.16111112,"width":0.05277778,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"As of yesterday at 6:50 PM","depth":28,"bounds":{"left":0.75555557,"top":0.16111112,"width":0.10763889,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Refresh","depth":28,"bounds":{"left":0.86527777,"top":0.16111112,"width":0.030555556,"height":0.0011111111},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open in Jira","depth":28,"bounds":{"left":0.75555557,"top":0.16111112,"width":0.06458333,"height":0.0011111111},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"✨ Summarise","depth":28,"bounds":{"left":0.8229167,"top":0.16111112,"width":0.07361111,"height":0.0011111111},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Open in browser","depth":28,"bounds":{"left":0.8819444,"top":0.16111112,"width":0.022222223,"height":0.0011111111},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Share Story JY-20912","depth":27,"bounds":{"left":0.90416664,"top":0.16111112,"width":0.022222223,"height":0.0011111111},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"View conversations","depth":27,"bounds":{"left":0.92638886,"top":0.16111112,"width":0.022222223,"height":0.0011111111},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More actions","depth":27,"bounds":{"left":0.94861114,"top":0.16111112,"width":0.022222223,"height":0.0011111111},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Lukas Kovalik","depth":24,"bounds":{"left":0.7465278,"top":0.16111112,"width":0.06458333,"height":0.0011111111},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.8111111,"top":0.16111112,"width":0.0055555557,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Yesterday at 6:50:58 PM","depth":24,"bounds":{"left":0.81666666,"top":0.16111112,"width":0.03125,"height":0.0011111111},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6:50 PM","depth":25,"bounds":{"left":0.81666666,"top":0.16111112,"width":0.03125,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"добре, ще го видя","depth":25,"bounds":{"left":0.7465278,"top":0.16111112,"width":0.0875,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Galya Dimitrova","depth":24,"bounds":{"left":0.7465278,"top":0.16111112,"width":0.07638889,"height":0.0011111111},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.8361111,"top":0.16111112,"width":0.0055555557,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Yesterday at 6:51:23 PM","depth":24,"bounds":{"left":0.84166664,"top":0.16111112,"width":0.031944446,"height":0.0011111111},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6:51 PM","depth":25,"bounds":{"left":0.84166664,"top":0.16111112,"width":0.031944446,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"аз няма да успея да вляза че сигурно ще спя","depth":25,"bounds":{"left":0.7465278,"top":0.16111112,"width":0.21319444,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Lukas Kovalik","depth":24,"bounds":{"left":0.7465278,"top":0.16111112,"width":0.06458333,"height":0.0011111111},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.8111111,"top":0.16111112,"width":0.0055555557,"height":0.0011111111},"on_screen":true,"role_description":"text"}]...
|
3028297641983758279
|
-4227662175878704782
|
idle
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
jiminny-x-integration-app
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
curiosity_lab
engineering
general
jiminny-bg
platform-tickets
product_launches
random
releases
sofia-office
support
thank-yous
the_people_of_jiminny
Galya Dimitrova
Nikolay Yankov
Vasil Vasilev
Aneliya Angelova
Stefka Stoyanova
Stoyan Tomov
Todor Stamatov
Mario Georgiev
Nikolay Ivanov
James Graham
Stoyan Tanev
Lukas Kovalik
you
Jira Cloud
Toast
Messages
Messages
Files
Files
Untitled
Untitled
Add and Edit Channel Tabs
Canvas
List
Folder
Jump to date
Yesterday at 6:50:16 PM
6:50
утре на дейлито виж с Ники Я дали ще те отблокира по сторитата за триене на Saved Search и промптове. Ако няма да може тогава докато го чакаш може да отметнем това от следващия спринт -
https://jiminny.atlassian.net/browse/JY-20912
https://jiminny.atlassian.net/browse/JY-20912
Jira Cloud
Jira Cloud
Jira Cloud Story JY-20912 Fallback mechanism for users with active SF tokens for CRM Matching Story JY-20912 in Jira Cloud Preview in Slack Status Backlog Priority Medium Medium Assignee Unassigned Unassigned As of yesterday at 6:50 PM Refresh Open in Jira ✨ Summarise
Fallback mechanism for users with active SF tokens for CRM Matching
Story JY-20912 in Jira Cloud
Preview in Slack
Status
Backlog
Priority
Medium
Assignee
Unassigned
As of yesterday at 6:50 PM
Refresh
Open in Jira
✨ Summarise
Open in browser
Share Story JY-20912
View conversations
More actions
Lukas Kovalik
Yesterday at 6:50:58 PM
6:50 PM
добре, ще го видя
Galya Dimitrova
Yesterday at 6:51:23 PM
6:51 PM
аз няма да успея да вляза че сигурно ще спя
Lukas Kovalik
SlackFileEditViewGoHistoryWindowHelpCopyrZendWhat'lukasOn brChang(us(usUntra(uslibl Flow (Basic)° Homea0 InsightsDictionary& SnippetsTr Style*3. TransformsE ScratchpadWelcome back, LukásMake Flow sound like youSet up different writing styles for different apps.Start nowTODAY12:45 PMАко после иска да го enable-нат, проверяваСамата грешка трябва ли да я правим поо-покажи само, че липсва prompt. Ако липсв:search. Ако липсват и двете, покажи и двесъобщение.Ааа, здрасти, едно бързо питане. Ааа, приsearch-oBeno chlukasEnumelCountDeltaComprWritiTotalremotremotremotremotremotTo gibranclukas1939 words remainingYou get 2000 words perweek. Upgrade for unlimitedaccess.Upgrade to Pro%, Invite your team# Get a free month@ Settings®Help12:44 PMMAY 15, 202611:54 AMMAY 14, 202612:27 PMCurrently, there is an issue in the command toIt doesn't work.ActivityLaterladl§ Support Daily - in 2h 12 m100% (8•Tue 19 May 12:48:58•ED→QDescribe what you are looking forJiminny ...scncral# jiminny-bg# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi...• Direct messages®. Galya Dimitrova. Nikolay Yankov€. Vasil VasilevP. Aneliya Angelovaa. Stefka Stoyanovao Stoyan TomovZa Todor Stamatov **o Mario Georgievao Nikolay Ivanovdo James Graham2. Stoyan TanevLukas Kovalik y...l:: Apps# Jira Cloud• ToastGalya DimitrovaMessagesC Files@ Untitled+Galya DimitrovYesterday ~мерсиToday ~Lukas Kovalik 12:46 PMздрасти, едно бързо питане. При триене наprompt-oвe и activity search-ове маркирамеreport disabled. Ако после искаме да го enable-нем, проверяваме дали има prompts и search.Самата грешка трябва ли да я правимпоотделно?Ако липсва prompt, покажи само, че липсваprompt.Ако липсва search, покажи само, че липсваsearch.Ако липсват и двете, покажи и двете.Или може едно общо съобщение "Cannot enablereport with missing saved search or prompt®Galya Dimitrova 12:48 PMпосле ако се енйбълне от Edit тогавапроверяваме за задължителни полета и излизасъобщениеили ти питаш за ако сe enable през гогъла койтое в таблицатаLukas Kovalik 12:48 PMза toggle, там няма формаMessage Galya Dimitrova• In a meeting • Google ...+...
|
57314
|
NULL
|
NULL
|
NULL
|
|
57279
|
NULL
|
0
|
2026-05-19T09:44:04.049568+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779183844049_m2.jpg...
|
Slack
|
Nikolay Yankov (DM) - Jiminny Inc - 6 new items - Nikolay Yankov (DM) - Jiminny Inc - 6 new items - Slack...
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
jiminny-x-integration-app
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
curiosity_lab
engineering
general
jiminny-bg
platform-tickets
product_launches
random
releases
sofia-office
support
thank-yous
the_people_of_jiminny
Nikolay Yankov
Vasil Vasilev
Galya Dimitrova
Aneliya Angelova
Stefka Stoyanova
Stoyan Tomov
Todor Stamatov
Mario Georgiev
Nikolay Ivanov
James Graham
Stoyan Tanev
Lukas Kovalik
you
Jira Cloud
Toast
Messages
Messages
Add canvas
Add canvas
Files
Files
Add and Edit Channel Tabs
Canvas
List
Folder
Jump to date
Lukas Kovalik
Today at 12:39:15 PM
12:39 PM
ами да и не
Today at 12:39:31 PM
12:39
по принцип то си е DTO ще се показва със списък
Nikolay Yankov
Today at 12:39:42 PM
12:39 PM
то няма проблем да се показва
Today at 12:39:46 PM
12:39
да го има пропъртито
Today at 12:39:52 PM
12:39
то ще е false при другите винаги, нали?
Lukas Kovalik
Today at 12:39:57 PM
12:39 PM
да
Nikolay Yankov
Today at 12:40:00 PM
12:40 PM
супер
Lukas Kovalik
Today at 12:40:12 PM
12:40 PM
ами false ако няма репорт
Today at 12:40:30 PM
12:40
ако има ще е true
Today at 12:40:54 PM
12:40
но реално то ще пречи ли сега
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Nikolay Yankov
Today at 12:41:28 PM
12:41 PM
хмм, че тези промптс не са ли само в кейса на on_demand, т.е. за всеки вид чат - на call, на deal, на паморама да са различни промптовете?
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 12:41:41 PM
12:41
защото трябва само на panorama да. показваме тази логика с модала и триенето
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Lukas Kovalik
Today at 12:42:04 PM
12:42 PM
ами не знам по-скоро се чудя ако е AJ na activity. и има промпт
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 12:42:15 PM
12:42
този ако се ползва при репортите
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 12:42:31 PM
12:42
пак трябва да го покажем warning
(edited)
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 12:42:42 PM
12:42
не знам дали може така
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 12:42:56 PM
12:42
да се споделят
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Nikolay Yankov
Today at 12:43:06 PM
12:43 PM
сега пробвах през UI като switch-вам от панорама на call, виждам различни промптове
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 12:43:36 PM
12:43
/api/v2/user/ask-anything-prompts?target=call
React with white_check_mark
React with eyes...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":14,"bounds":{"left":0.5152925,"top":1.0,"width":0.011968086,"height":-0.058260202},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":14,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":16,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":14,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":16,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":14,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":16,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":14,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":16,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":14,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":16,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":14,"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":16,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":21,"bounds":{"left":0.5465425,"top":1.0,"width":0.018949468,"height":-0.09177971},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":21,"bounds":{"left":0.5465425,"top":1.0,"width":0.01761968,"height":-0.09177971},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":21,"bounds":{"left":0.5465425,"top":1.0,"width":0.018284574,"height":-0.09177971},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":21,"bounds":{"left":0.5465425,"top":1.0,"width":0.02925532,"height":-0.09177971},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":21,"bounds":{"left":0.5980718,"top":1.0,"width":0.0026595744,"height":-0.09177971},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":21,"bounds":{"left":0.5465425,"top":1.0,"width":0.024268618,"height":-0.09177971},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"jiminny-x-integration-app","depth":23,"bounds":{"left":0.5518617,"top":1.0,"width":0.043882977,"height":-0.09177971},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":23,"bounds":{"left":0.5518617,"top":1.0,"width":0.04454787,"height":-0.09177971},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":23,"bounds":{"left":0.5518617,"top":1.0,"width":0.022273935,"height":-0.09177971},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":23,"bounds":{"left":0.5518617,"top":1.0,"width":0.012300532,"height":-0.09177971},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":23,"bounds":{"left":0.5518617,"top":1.0,"width":0.018284574,"height":-0.09177971},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"bugs","depth":23,"bounds":{"left":0.5518617,"top":1.0,"width":0.010638298,"height":-0.09177971},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"confusion-clinic","depth":23,"bounds":{"left":0.5518617,"top":1.0,"width":0.034574468,"height":-0.09177971},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"curiosity_lab","depth":23,"bounds":{"left":0.5518617,"top":1.0,"width":0.027593086,"height":-0.09177971},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"engineering","depth":23,"bounds":{"left":0.5518617,"top":1.0,"width":0.025930852,"height":-0.09177971},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"general","depth":23,"bounds":{"left":0.5518617,"top":1.0,"width":0.016289894,"height":-0.09177971},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"jiminny-bg","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"platform-tickets","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"product_launches","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"random","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"releases","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"sofia-office","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"support","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"thank-yous","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"the_people_of_jiminny","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Vasil Vasilev","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Aneliya Angelova","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Stefka Stoyanova","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Stoyan Tomov","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Todor Stamatov","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Mario Georgiev","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Ivanov","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"James Graham","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Stoyan Tanev","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"you","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Jira Cloud","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Toast","depth":23,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Messages","depth":17,"bounds":{"left":0.61170214,"top":1.0,"width":0.030917553,"height":-0.09177971},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Messages","depth":19,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Add canvas","depth":18,"bounds":{"left":0.64361703,"top":1.0,"width":0.034242023,"height":-0.09177971},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Add canvas","depth":20,"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":17,"bounds":{"left":0.6788564,"top":1.0,"width":0.020944148,"height":-0.09177971},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":19,"on_screen":true,"role_description":"text"},{"role":"AXPopUpButton","text":"Add and Edit Channel Tabs","depth":17,"bounds":{"left":0.70113033,"top":1.0,"width":0.010638298,"height":-0.09177971},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Canvas","depth":17,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"List","depth":17,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Folder","depth":17,"on_screen":false,"role_description":"text"},{"role":"AXPopUpButton","text":"Jump to date","depth":23,"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Lukas Kovalik","depth":24,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:39:15 PM","depth":24,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:39 PM","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ами да и не","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:39:31 PM","depth":25,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:39","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"по принцип то си е DTO ще се показва със списък","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Nikolay Yankov","depth":24,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:39:42 PM","depth":24,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:39 PM","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"то няма проблем да се показва","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:39:46 PM","depth":25,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:39","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"да го има пропъртито","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:39:52 PM","depth":25,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:39","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"то ще е false при другите винаги, нали?","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Lukas Kovalik","depth":24,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:39:57 PM","depth":24,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:39 PM","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"да","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Nikolay Yankov","depth":24,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:40:00 PM","depth":24,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:40 PM","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"супер","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Lukas Kovalik","depth":24,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:40:12 PM","depth":24,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:40 PM","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ами false ако няма репорт","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:40:30 PM","depth":25,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:40","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ако има ще е true","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:40:54 PM","depth":25,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:40","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"но реално то ще пречи ли сега","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"on_screen":true,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"on_screen":true,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"on_screen":true,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"on_screen":false,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"on_screen":false,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Nikolay Yankov","depth":24,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:41:28 PM","depth":24,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:41 PM","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"хмм, че тези промптс не са ли само в кейса на on_demand, т.е. за всеки вид чат - на call, на deal, на паморама да са различни промптовете?","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"on_screen":true,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"on_screen":true,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"on_screen":true,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"on_screen":false,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"on_screen":false,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Today at 12:41:41 PM","depth":25,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:41","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"защото трябва само на panorama да. показваме тази логика с модала и триенето","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"on_screen":true,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"on_screen":true,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"on_screen":true,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"on_screen":false,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"on_screen":false,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Lukas Kovalik","depth":24,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:42:04 PM","depth":24,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:42 PM","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ами не знам по-скоро се чудя ако е AJ na activity. и има промпт","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"on_screen":true,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"on_screen":true,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"on_screen":true,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"on_screen":false,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"on_screen":false,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Today at 12:42:15 PM","depth":25,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:42","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"този ако се ползва при репортите","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"on_screen":true,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"on_screen":true,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"on_screen":true,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"on_screen":false,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"on_screen":false,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Today at 12:42:31 PM","depth":25,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:42","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"пак трябва да го покажем warning","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"(edited)","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"on_screen":true,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"on_screen":true,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"on_screen":true,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"on_screen":false,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"on_screen":false,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Today at 12:42:42 PM","depth":25,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:42","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"не знам дали може така","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"on_screen":true,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"on_screen":true,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"on_screen":true,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"on_screen":false,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"on_screen":false,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Today at 12:42:56 PM","depth":25,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:42","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"да се споделят","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"on_screen":true,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"on_screen":true,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"on_screen":true,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"on_screen":false,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"on_screen":false,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Nikolay Yankov","depth":24,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:43:06 PM","depth":24,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:43 PM","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"сега пробвах през UI като switch-вам от панорама на call, виждам различни промптове","depth":25,"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"on_screen":true,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"on_screen":true,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with raised_hands","depth":26,"on_screen":true,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Add reaction…","depth":26,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reply in thread","depth":26,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward message…","depth":26,"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Save for later","depth":26,"on_screen":false,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"More actions","depth":26,"on_screen":false,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Today at 12:43:36 PM","depth":25,"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:43","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"/api/v2/user/ask-anything-prompts?target=call","depth":26,"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"React with white_check_mark","depth":26,"on_screen":true,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"React with eyes","depth":26,"on_screen":true,"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-8630421617739437245
|
-1573632079270867882
|
click
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
jiminny-x-integration-app
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
curiosity_lab
engineering
general
jiminny-bg
platform-tickets
product_launches
random
releases
sofia-office
support
thank-yous
the_people_of_jiminny
Nikolay Yankov
Vasil Vasilev
Galya Dimitrova
Aneliya Angelova
Stefka Stoyanova
Stoyan Tomov
Todor Stamatov
Mario Georgiev
Nikolay Ivanov
James Graham
Stoyan Tanev
Lukas Kovalik
you
Jira Cloud
Toast
Messages
Messages
Add canvas
Add canvas
Files
Files
Add and Edit Channel Tabs
Canvas
List
Folder
Jump to date
Lukas Kovalik
Today at 12:39:15 PM
12:39 PM
ами да и не
Today at 12:39:31 PM
12:39
по принцип то си е DTO ще се показва със списък
Nikolay Yankov
Today at 12:39:42 PM
12:39 PM
то няма проблем да се показва
Today at 12:39:46 PM
12:39
да го има пропъртито
Today at 12:39:52 PM
12:39
то ще е false при другите винаги, нали?
Lukas Kovalik
Today at 12:39:57 PM
12:39 PM
да
Nikolay Yankov
Today at 12:40:00 PM
12:40 PM
супер
Lukas Kovalik
Today at 12:40:12 PM
12:40 PM
ами false ако няма репорт
Today at 12:40:30 PM
12:40
ако има ще е true
Today at 12:40:54 PM
12:40
но реално то ще пречи ли сега
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Nikolay Yankov
Today at 12:41:28 PM
12:41 PM
хмм, че тези промптс не са ли само в кейса на on_demand, т.е. за всеки вид чат - на call, на deal, на паморама да са различни промптовете?
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 12:41:41 PM
12:41
защото трябва само на panorama да. показваме тази логика с модала и триенето
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Lukas Kovalik
Today at 12:42:04 PM
12:42 PM
ами не знам по-скоро се чудя ако е AJ na activity. и има промпт
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 12:42:15 PM
12:42
този ако се ползва при репортите
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 12:42:31 PM
12:42
пак трябва да го покажем warning
(edited)
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 12:42:42 PM
12:42
не знам дали може така
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 12:42:56 PM
12:42
да се споделят
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Nikolay Yankov
Today at 12:43:06 PM
12:43 PM
сега пробвах през UI като switch-вам от панорама на call, виждам различни промптове
React with white_check_mark
React with eyes
React with raised_hands
Add reaction…
Reply in thread
Forward message…
Save for later
More actions
Today at 12:43:36 PM
12:43
/api/v2/user/ask-anything-prompts?target=call
React with white_check_mark
React with eyes
PnostormProiectFV faVsco.js°9 JY-20676-delete-report-related-objectsC ActivityController.ong=custom.log=laravel.log4 HS_local [jiminny@localhost]© AskAnythingPromptDto.php( EventsAsKAnytningPromptservice.ong© AskAnythingPromptService.php >© AskAnythingPrompt.phpphp api_v2.phpA console [STAGING]CoachingFeedbackCoachUserin.phpc) Automateakeport.pnpc Historyservice.ongD AskJiminnyAiWAWS0 BillingManagementu cachew countryDatabase→ DatadogDatettimeDealinsiahtsN DealRisks1N GlasticSearchEncoding• Encryption1M SakenD FeatureFlagsD FFMpegD FileSystemD Gong_ cuzzienutou reyPolntsKIOSK_ LanquageDetectionW LOCKSW Math_Mediapioeline2 MobileSettinasNudaeIM ParagranhBreaker1 PartitionedCookieM PlavbackPadeM PlavlistProphetM PronhetAfM DrosnorWorkdM Auonc© AskAnythingPromptServiceTest.php) search.phpclass ASKAnyth1ngPromptService23312V2 л v 182public function edita183AskAnvthingPromot Soromot.User suserstring stitle,strina Scontentiarray $shareUsersUuids,array $shareGroupsUuids): AskAnythingPromptDto {...}188 (0public function deletelAskAnythingPrompt $prompt,User Suser): AskAnythingPrompt {...}public function reondendUser suserarray spromptuulds,): void {...}195197199207203* doaram AskAnuthinaPromor Soromot* dreturn arraul arrau<strina>. arrau<strina>1usagepnivate function aetReceiverlluids(AskAnvthingPromot Soromot): arnav/...}lnrivate function deletePromntTfNoRelations(AskAnvthi.naPromotSoromnt: void212if (Sthis->askAnythingRepository->findSharedUsersAndGroupsByPromptId(Sprompt->getId())->iSEmpty 214// Disable and orphan any AutomatedReports that use this prompi$prompt->automatedReports->withTrashed->update([216'ask_anything_prompt_id' => null,'status' => false,1:// Delete only if there are no other relations to [EMAIL]+(Cnnomnt).2202211222223224225private function recreatePromptsForEachRelation(AskAnvthingPrompt Spromot): voidf...}SELECT ar.id, ar.uuid, ar.media type, ar.status, a.typeFROM automated_report_results arJOIN automated_reports a ON a.id = ar.reportidWHERE a.tyRe =TUMET 10:SELECT * EROM automated nenonts where id = 71lSELECT * EROM automated nenont results where renont id = 71.UPDATE automated_reports set playbook_categories = NULL where id = 68SELECT * FROM automated_report_results where id = 275;SELECT * FROM automated_reports order by id desc;SELECT * FROM automated_report_results order by id desc;select * from activity searches where user id = 143:INNER JOIN automated_ reportsautomated_reports'.'idWHERE 1=1AND automated revort• generated ats NUI NULUAND'automated report results"'sent at' IS NOT NULIorts . team 1d = 1AND JSON CONTAINS( 'automated reports', 'recipients'. 143. 's "users"')SELEC * FROM automated renonts where 1d e 6SELECT * FROM automated renorts where 1d = 42SELECT * FROMusers WHERE id = 143; # group 28select * from teams where id = 3143;select * from erm confiaurations where id = 500•select * from users where name = 'Integration Account'; # 1695SELECT * CP0M cocial accountc WHEPE cocjahle id = 1405•colort * fnom activitiec whene enm confiaunation id = 70and recording state = 'recorded' and duration > 60and ctatuc - Icomnlotedi and actual ctant +imo >='2025-12-01'SELECT * FROM activities WHERE uuid to bin('458cf915-b914-4000-b083-5687b32b2956') = uuid:colont d Enom Toode!SELECT * FROM activities WHERE uuid to bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid: # 422003SELECT * FROM activities WHEREid IN (16.422003)SFLFCT * FROM activities where status = 'failed'Socket fail to connect to host:address=(host=localhost) (port=3306)(tvpe=primarv). Connection refusedsuppon Dally • In zn 10l100% 5• lue 19 May 12.44:03+0 ..& console [PROD]# console [euyCascadeAsk Jiminny Report MSo jiminny v021 A1 A18 V2 V6 ^orts trom create() and edtt( Dros (only included in list response):AskAnythingPromptService.phpThought for 6sRead AskAnvthinaPromotServiceTest.pho #L44-223AskAnythingPromptServiceTest.phpSummary of Revisions1. Searchuranstormer now emits has reportsSearchTransformer.nhn: 12_50a searchirapuoac tunccion transtorm search ssearch. arfayreturn ['1d" = Ssearch→>id stringifilterct e Sthic-saetfilterc/@cearch).+24 -2oends laccessor on the Search model correctly — addina it would have caused unnecessary querieseverywnere the modells serlallzed. Ine tlag now lves only in the wranstormer used oy uistaccivitysearch,2. Rethought the prompt DTOYou're riaht - newlv-created and edited oromots will never have related reports, and most existina oromots won't have anvaihor t• Made AskAnythingPromptDto::ShasReports nullable (?bool ShasReports = null).• Oniv included it in toArravo when it is not null — same conditional pattern as ownerid / sharellsers / shareGrouns |• Removed it from create() and edit() DTO construction in AskAnythingPromptService - they always pass nothingnow, so create/uodate responses won't include has reports.•In get(), it stays — calls Sprompt→>gethaskeports() (your renamed accessor) so the list enapoint emits the tlagThis way the per-row exists() auery is oniv run when the list endooint is hit. never on createledit3. Test undateUindatod toctGotAckAnvthinaDromntein AckAnvthinorromprservicelest. onp to mock dechaskeports on everyprompt mock and reflect the values (one true, three false ) in the expected DTOs. The existing testCreateAskAnythingPromptW1thlwoUsers, testEd1tASKAnyth1ngPrompt, etc. don't need changes — they already construct expected DTOswithout an 8th araument which now matches the null default.lö all «Ask anvthina (884-L)<> Code Claude Qnus 1.7 MediumA 7 files committedJY-20676 delete AJ reports related objectsEdit Commit Messaae.Po. 4 spac...
|
57277
|
NULL
|
NULL
|
NULL
|
|
57278
|
NULL
|
0
|
2026-05-19T09:44:04.073618+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779183844073_m1.jpg...
|
Slack
|
Nikolay Yankov (DM) - Jiminny Inc - 6 new items - Nikolay Yankov (DM) - Jiminny Inc - 6 new items - Slack...
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
jiminny-x-integration-app
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
curiosity_lab
engineering
general
jiminny-bg
platform-tickets
product_launches
random
releases
sofia-office
support
thank-yous
the_people_of_jiminny
Nikolay Yankov
Vasil Vasilev
Galya Dimitrova
Aneliya Angelova
Stefka Stoyanova
Stoyan Tomov
Todor Stamatov
Mario Georgiev
Nikolay Ivanov
James Graham
Stoyan Tanev
Lukas Kovalik
you
Jira Cloud
Toast
Messages
Messages
Add canvas
Add canvas
Files
Files
Add and Edit Channel Tabs
Canvas
List
Folder
Jump to date
Lukas Kovalik
Today at 12:39:15 PM
12:39 PM
ами да и не
Today at 12:39:31 PM
12:39
по принцип то си е DTO ще се показва със списък
Nikolay Yankov
Today at 12:39:42 PM
12:39 PM
то няма проблем да се показва
Today at 12:39:46 PM
12:39
да го има пропъртито
Today at 12:39:52 PM
12:39
то ще е false при другите винаги, нали?
Lukas Kovalik
Today at 12:39:57 PM
12:39 PM
да
Nikolay Yankov...
|
[{"role":"AXPopUpButton","text [{"role":"AXPopUpButton","text":"Switch workspaces… (Jiminny Inc) Has new messages","depth":14,"bounds":{"left":0.51180553,"top":0.08111111,"width":0.025,"height":0.04},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Home","depth":14,"bounds":{"left":0.50625,"top":0.14,"width":0.036111113,"height":0.075555556},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Home","depth":16,"bounds":{"left":0.5138889,"top":0.19222222,"width":0.020833334,"height":0.015555556},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"DMs","depth":14,"bounds":{"left":0.50625,"top":0.21555555,"width":0.036111113,"height":0.075555556},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DMs","depth":16,"bounds":{"left":0.5159722,"top":0.26777777,"width":0.016666668,"height":0.015555556},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Activity","depth":14,"bounds":{"left":0.50625,"top":0.2911111,"width":0.036111113,"height":0.075555556},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Activity","depth":16,"bounds":{"left":0.51111114,"top":0.34333333,"width":0.027083334,"height":0.015555556},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.51111114,"top":0.34333333,"width":0.0055555557,"height":0.015555556}},{"char_start":1,"char_count":7,"bounds":{"left":0.5159722,"top":0.34333333,"width":0.022222223,"height":0.015555556}}],"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":14,"bounds":{"left":0.50625,"top":0.36666667,"width":0.036111113,"height":0.075555556},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":16,"bounds":{"left":0.51666665,"top":0.4188889,"width":0.015972223,"height":0.015555556},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.51666665,"top":0.4188889,"width":0.004166667,"height":0.015555556}},{"char_start":1,"char_count":4,"bounds":{"left":0.5208333,"top":0.4188889,"width":0.011805556,"height":0.015555556}}],"role_description":"text"},{"role":"AXRadioButton","text":"Later","depth":14,"bounds":{"left":0.50625,"top":0.4422222,"width":0.036111113,"height":0.075555556},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Later","depth":16,"bounds":{"left":0.5152778,"top":0.49444443,"width":0.018055556,"height":0.015555556},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"More…","depth":14,"bounds":{"left":0.50625,"top":0.5177778,"width":0.036111113,"height":0.075555556},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":16,"bounds":{"left":0.5152778,"top":0.57,"width":0.01875,"height":0.015555556},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Unreads","depth":21,"bounds":{"left":0.57708335,"top":0.12777779,"width":0.039583333,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Threads","depth":21,"bounds":{"left":0.57708335,"top":0.12777779,"width":0.036805555,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Huddles","depth":21,"bounds":{"left":0.57708335,"top":0.12777779,"width":0.038194444,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Drafts & sent","depth":21,"bounds":{"left":0.57708335,"top":0.12777779,"width":0.06111111,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":21,"bounds":{"left":0.68472224,"top":0.12777779,"width":0.0055555557,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Directories","depth":21,"bounds":{"left":0.57708335,"top":0.12777779,"width":0.050694443,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"jiminny-x-integration-app","depth":23,"bounds":{"left":0.58819443,"top":0.12777779,"width":0.09166667,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"platform-inner-team","depth":23,"bounds":{"left":0.58819443,"top":0.12777779,"width":0.093055554,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ai-chapter","depth":23,"bounds":{"left":0.58819443,"top":0.12777779,"width":0.046527777,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"alerts","depth":23,"bounds":{"left":0.58819443,"top":0.12777779,"width":0.025694445,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"backend","depth":23,"bounds":{"left":0.58819443,"top":0.12777779,"width":0.038194444,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"bugs","depth":23,"bounds":{"left":0.58819443,"top":0.12777779,"width":0.022222223,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"confusion-clinic","depth":23,"bounds":{"left":0.58819443,"top":0.12777779,"width":0.072222225,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"curiosity_lab","depth":23,"bounds":{"left":0.58819443,"top":0.12777779,"width":0.057638887,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"engineering","depth":23,"bounds":{"left":0.58819443,"top":0.12777779,"width":0.054166667,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"general","depth":23,"bounds":{"left":0.58819443,"top":0.12777779,"width":0.034027778,"height":0.007777778},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"jiminny-bg","depth":23,"bounds":{"left":0.58819443,"top":0.14666666,"width":0.048611112,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"platform-tickets","depth":23,"bounds":{"left":0.58819443,"top":0.17777778,"width":0.072916664,"height":0.02},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.58819443,"top":0.17777778,"width":0.00625,"height":0.02}},{"char_start":1,"char_count":15,"bounds":{"left":0.59444445,"top":0.17777778,"width":0.06666667,"height":0.02}}],"role_description":"text"},{"role":"AXStaticText","text":"product_launches","depth":23,"bounds":{"left":0.58819443,"top":0.20888889,"width":0.08055556,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"random","depth":23,"bounds":{"left":0.58819443,"top":0.24,"width":0.035416666,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"releases","depth":23,"bounds":{"left":0.58819443,"top":0.2711111,"width":0.038194444,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"sofia-office","depth":23,"bounds":{"left":0.58819443,"top":0.30222222,"width":0.05138889,"height":0.02},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.58819443,"top":0.30222222,"width":0.0048611113,"height":0.02}},{"char_start":1,"char_count":11,"bounds":{"left":0.59305555,"top":0.30222222,"width":0.045833334,"height":0.02}}],"role_description":"text"},{"role":"AXStaticText","text":"support","depth":23,"bounds":{"left":0.58819443,"top":0.33333334,"width":0.036111113,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"thank-yous","depth":23,"bounds":{"left":0.58819443,"top":0.36444443,"width":0.05138889,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"the_people_of_jiminny","depth":23,"bounds":{"left":0.58819443,"top":0.39555556,"width":0.094444446,"height":0.02},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.58819443,"top":0.39555556,"width":0.004166667,"height":0.02}},{"char_start":1,"char_count":20,"bounds":{"left":0.5923611,"top":0.39555556,"width":0.09861111,"height":0.02}}],"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":23,"bounds":{"left":0.58819443,"top":0.46888888,"width":0.06875,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Vasil Vasilev","depth":23,"bounds":{"left":0.58819443,"top":0.5,"width":0.055555556,"height":0.02},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.58819443,"top":0.5,"width":0.00625,"height":0.02}},{"char_start":1,"char_count":12,"bounds":{"left":0.59444445,"top":0.5,"width":0.048611112,"height":0.02}}],"role_description":"text"},{"role":"AXStaticText","text":"Galya Dimitrova","depth":23,"bounds":{"left":0.58819443,"top":0.5311111,"width":0.07361111,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Aneliya Angelova","depth":23,"bounds":{"left":0.58819443,"top":0.56222224,"width":0.07847222,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Stefka Stoyanova","depth":23,"bounds":{"left":0.58819443,"top":0.5933333,"width":0.079166666,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Stoyan Tomov","depth":23,"bounds":{"left":0.58819443,"top":0.6244444,"width":0.06458333,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Todor Stamatov","depth":23,"bounds":{"left":0.58819443,"top":0.65555555,"width":0.072222225,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Mario Georgiev","depth":23,"bounds":{"left":0.58819443,"top":0.68666667,"width":0.07152778,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Nikolay Ivanov","depth":23,"bounds":{"left":0.58819443,"top":0.7177778,"width":0.06736111,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"James Graham","depth":23,"bounds":{"left":0.58819443,"top":0.7488889,"width":0.06666667,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Stoyan Tanev","depth":23,"bounds":{"left":0.58819443,"top":0.78,"width":0.060416665,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":23,"bounds":{"left":0.58819443,"top":0.8111111,"width":0.061805554,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"you","depth":23,"bounds":{"left":0.65555555,"top":0.8111111,"width":0.013194445,"height":0.02},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.65555555,"top":0.8111111,"width":0.0048611113,"height":0.02}},{"char_start":1,"char_count":2,"bounds":{"left":0.66041666,"top":0.8111111,"width":0.011805556,"height":0.02}}],"role_description":"text"},{"role":"AXStaticText","text":"Jira Cloud","depth":23,"bounds":{"left":0.58819443,"top":0.8844444,"width":0.046527777,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Toast","depth":23,"bounds":{"left":0.58819443,"top":0.91555554,"width":0.025694445,"height":0.02},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Messages","depth":17,"bounds":{"left":0.71319443,"top":0.12777779,"width":0.06458333,"height":0.04222222},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true,"is_expanded":false},{"role":"AXStaticText","text":"Messages","depth":19,"bounds":{"left":0.7326389,"top":0.14,"width":0.039583333,"height":0.017777778},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Add canvas","depth":18,"bounds":{"left":0.7798611,"top":0.12777779,"width":0.07152778,"height":0.04222222},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Add canvas","depth":20,"bounds":{"left":0.79930556,"top":0.14,"width":0.046527777,"height":0.017777778},"on_screen":true,"role_description":"text"},{"role":"AXRadioButton","text":"Files","depth":17,"bounds":{"left":0.85347223,"top":0.12777779,"width":0.04375,"height":0.04222222},"on_screen":true,"role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Files","depth":19,"bounds":{"left":0.87291664,"top":0.14,"width":0.01875,"height":0.017777778},"on_screen":true,"lines":[{"char_start":0,"char_count":1,"bounds":{"left":0.87291664,"top":0.14,"width":0.0055555557,"height":0.017777778}},{"char_start":1,"char_count":4,"bounds":{"left":0.8784722,"top":0.14,"width":0.013194445,"height":0.017777778}}],"role_description":"text"},{"role":"AXPopUpButton","text":"Add and Edit Channel Tabs","depth":17,"bounds":{"left":0.9,"top":0.12777779,"width":0.022222223,"height":0.04222222},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Canvas","depth":17,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"List","depth":17,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Folder","depth":17,"on_screen":false,"role_description":"text"},{"role":"AXPopUpButton","text":"Jump to date","depth":23,"bounds":{"left":0.8229167,"top":0.17666666,"width":0.05277778,"height":0.031111112},"on_screen":true,"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Lukas Kovalik","depth":24,"bounds":{"left":0.7465278,"top":0.16111112,"width":0.06458333,"height":0.0011111111},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.8111111,"top":0.16111112,"width":0.0055555557,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:39:15 PM","depth":24,"bounds":{"left":0.81666666,"top":0.16111112,"width":0.036111113,"height":0.0011111111},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:39 PM","depth":25,"bounds":{"left":0.81666666,"top":0.16111112,"width":0.036111113,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"ами да и не","depth":25,"bounds":{"left":0.7465278,"top":0.16111112,"width":0.055555556,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:39:31 PM","depth":25,"bounds":{"left":0.71944445,"top":0.16111112,"width":0.021527778,"height":0.0011111111},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:39","depth":26,"bounds":{"left":0.71944445,"top":0.16111112,"width":0.021527778,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"по принцип то си е DTO ще се показва със списък","depth":25,"bounds":{"left":0.7465278,"top":0.16111112,"width":0.2048611,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Nikolay Yankov","depth":24,"bounds":{"left":0.7465278,"top":0.16111112,"width":0.072222225,"height":0.0011111111},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.81805557,"top":0.16111112,"width":0.00625,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:39:42 PM","depth":24,"bounds":{"left":0.82361114,"top":0.16111112,"width":0.036805555,"height":0.0011111111},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:39 PM","depth":25,"bounds":{"left":0.82361114,"top":0.16111112,"width":0.036805555,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"то няма проблем да се показва","depth":25,"bounds":{"left":0.7465278,"top":0.16111112,"width":0.15,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:39:46 PM","depth":25,"bounds":{"left":0.71944445,"top":0.16111112,"width":0.021527778,"height":0.0011111111},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:39","depth":26,"bounds":{"left":0.71944445,"top":0.16111112,"width":0.021527778,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"да го има пропъртито","depth":25,"bounds":{"left":0.7465278,"top":0.16111112,"width":0.10555556,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:39:52 PM","depth":25,"bounds":{"left":0.71944445,"top":0.16111112,"width":0.021527778,"height":0.0011111111},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:39","depth":26,"bounds":{"left":0.71944445,"top":0.16111112,"width":0.021527778,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"то ще е false при другите винаги, нали?","depth":25,"bounds":{"left":0.7465278,"top":0.16111112,"width":0.18958333,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Lukas Kovalik","depth":24,"bounds":{"left":0.7465278,"top":0.16111112,"width":0.06458333,"height":0.0011111111},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.8111111,"top":0.16111112,"width":0.0055555557,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXLink","text":"Today at 12:39:57 PM","depth":24,"bounds":{"left":0.81666666,"top":0.16111112,"width":0.036111113,"height":0.0011111111},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12:39 PM","depth":25,"bounds":{"left":0.81666666,"top":0.16111112,"width":0.036111113,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"да","depth":25,"bounds":{"left":0.7465278,"top":0.16111112,"width":0.011805556,"height":0.0011111111},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Nikolay Yankov","depth":24,"bounds":{"left":0.7465278,"top":0.16111112,"width":0.072222225,"height":0.0011111111},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"","depth":24,"bounds":{"left":0.81805557,"top":0.16111112,"width":0.00625,"height":0.0011111111},"on_screen":true,"role_description":"text"}]...
|
-5333768559045686886
|
-3519047549236308434
|
click
|
hybrid
|
NULL
|
Switch workspaces… (Jiminny Inc) Has new messages
Switch workspaces… (Jiminny Inc) Has new messages
Home
Home
DMs
DMs
Activity
Activity
Files
Files
Later
Later
More…
More
Unreads
Threads
Huddles
Drafts & sent
1
Directories
jiminny-x-integration-app
platform-inner-team
ai-chapter
alerts
backend
bugs
confusion-clinic
curiosity_lab
engineering
general
jiminny-bg
platform-tickets
product_launches
random
releases
sofia-office
support
thank-yous
the_people_of_jiminny
Nikolay Yankov
Vasil Vasilev
Galya Dimitrova
Aneliya Angelova
Stefka Stoyanova
Stoyan Tomov
Todor Stamatov
Mario Georgiev
Nikolay Ivanov
James Graham
Stoyan Tanev
Lukas Kovalik
you
Jira Cloud
Toast
Messages
Messages
Add canvas
Add canvas
Files
Files
Add and Edit Channel Tabs
Canvas
List
Folder
Jump to date
Lukas Kovalik
Today at 12:39:15 PM
12:39 PM
ами да и не
Today at 12:39:31 PM
12:39
по принцип то си е DTO ще се показва със списък
Nikolay Yankov
Today at 12:39:42 PM
12:39 PM
то няма проблем да се показва
Today at 12:39:46 PM
12:39
да го има пропъртито
Today at 12:39:52 PM
12:39
то ще е false при другите винаги, нали?
Lukas Kovalik
Today at 12:39:57 PM
12:39 PM
да
Nikolay Yankov
SlackFileEditViewGoHistoryWindowHelpCopyrZendWhat'lukasOn brChang(us(usUntra(uslibl Flow (Basic)° Homea0 InsightsDictionary& SnippetsTr Style*8. TransformsE Scratchpadno chlukasEnumeCountDeltaComprWritiTotalremotremotremotremotremotTo gibranclukas2000 words remainingYou get 2000 words perweek. Upgrade for unlimitedaccess.Upgrade to Pro%, Invite your team# Get a free month@ SettingsHelpWelcome back, LukásMake Flow sound like youSet up different writing styles for different apps.Start nowMAY 15, 202611:54 AMMAY 14, 202612:27 PMMAY 13, 202606:52 PM02:12 PM10:58 AMCurrently, there is an issue in the command toIt doesn't work.The issue is with the status of the activity. It ithe dashboard in the completed section.The issue for Scott is related to his email addifrom the email address header, which refers tHowever, there is no such user in Jiminny.tell me: how does the ScreenPipe audio recorActivityLaterlhlSupport Daily - in 2 h 16 m100% C8•Tue 19 May 12:44:03•ED→QDescribe what you are looking forJiminny... vscnicret# jiminny-bg# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi...• Direct messages8. Nikolay Yankov€. Vasil VasilevP. Galya Dimitrova MP. Aneliya Angelovaa. Stefka StoyanovaStoyan Tomova Todor Stamatov *o Mario Georgiev. Nikolay Ivanovdo James Graham8 Stoyan TanevLukas Kovalik y...l:: AppsJira Cloud• ToastNikolay Yankov6 0• MessagesAdd canvasако има ще e true+@ FilesToday~но реално то ще пречи ли сегаNikolay Yankov 12:41 PMхмм, че тези промптс не са ли само в кейса наon_demand, т.e. за всеки вид чат - на call, на deal,на паморама да са различни промптовете?защото трябва само на panoramа да. показваметази логика с модала и триенетоLukas Kovalik 12:42 PMами не знам по-скоро се чудя ако e AJ na activity.и има промпттози ако се ползва при репортитепак трябва да го покажем warning (edited)не знам дали може такада се споделятNikolay Yankov 12:43 PMсега пробвах през UI като switch-вам отпанорама на call, виждам различни промптове/api/v2/user/ask-anything-prompts?target=callто реално промптовете които показваме врепортите като си го сетват са само отпанорамазначи няма как да си изберат такъв промопт отcallMessage Nikolay Yankov+...
|
57276
|
NULL
|
NULL
|
NULL
|
|
57248
|
NULL
|
0
|
2026-05-19T09:39:10.896556+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779183550896_m1.jpg...
|
Firefox
|
NULL
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpAPPDOCKER• ₴1D SlackFileEditViewGoHistoryWindowHelpAPPDOCKER• ₴1DEV (docker)Copyright (c) The PHP GroupZend Engine v4.3.30, Copyright (c) Zend Technologieswith Zend OPcache v8.3.30, Copyright (C), by Zend Technologies₴82APP (-zshWhat's next:Try Docker Debug for seamless, persistentdebugging tools in any containerorimage →Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20676-delete-report-related-obEnumerating objects: 45, done.Counting objects: 100% (45/45), done.Delta compression using up to 8 threadsCompressing objects: 100% (24/24), done.Writing objects: 100% (24/24), 3.62 KiB | 3.62 MiB/s, done.Total 24 (delta 19), reused 0 (delta 0), pack-reused 0remote: Resolving deltas: 100% (19/19), completed with 19 local objects.remote: Create a pullrequest for 'JY-20676-delete-report-related-objects'on GitHub by viremote:[URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20676-delete-report-related-obHomeDMsActivityFilesLater..•More•ED→Jiminny... vscncral# jiminny-bg# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi...• Direct messages8. Nikolay Yankov€. Vasil VasilevP. Galya Dimitrova MP. Aneliya Angelovaa. Stefka StoyanovaStoyan Tomov6 Todor Stamatov "o Mario Georgiev. Nikolay Ivanovdo James GrahamStoyan TanevLukas Kovalik y...l:: AppsJira CloudToast§ Support Daily • in 2h 21 m100% (8•Tue 19 May 12:39:10Describe what you are looking forNikolay Yankov6 0MessagesAdd canvasLukas Kovalik 12.20 nkToday ~ще погледназа сега направих ПРO Files+Nikolay Yankov 12:33 PMя дайLukas Kovalik 12:34 PMhttps://github.com/jiminny/app/pull/12098за сега добавих такава Cannot enable report withmissing saved search or promptче то в крайна сметка ще гледа и дветепропертитаNikolay Yankov 12:35 PMДобрепо принцип най-добре Галя да одобриLukas Kovalik 12:35 PMдаNikolay Yankov 12:35 PMможе да й пишеш, зе това добавямеако нещо друго иска да кажеLukas Kovalik 12:37 PMOKNikolay Yankov 12:38 PMсамо в кейса на target on_demand ще еhas_reports: true, нали?1ами+Shift + Return to add a new line...
|
NULL
|
-772854251644888081
|
NULL
|
click
|
ocr
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpAPPDOCKER• ₴1D SlackFileEditViewGoHistoryWindowHelpAPPDOCKER• ₴1DEV (docker)Copyright (c) The PHP GroupZend Engine v4.3.30, Copyright (c) Zend Technologieswith Zend OPcache v8.3.30, Copyright (C), by Zend Technologies₴82APP (-zshWhat's next:Try Docker Debug for seamless, persistentdebugging tools in any containerorimage →Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20676-delete-report-related-obEnumerating objects: 45, done.Counting objects: 100% (45/45), done.Delta compression using up to 8 threadsCompressing objects: 100% (24/24), done.Writing objects: 100% (24/24), 3.62 KiB | 3.62 MiB/s, done.Total 24 (delta 19), reused 0 (delta 0), pack-reused 0remote: Resolving deltas: 100% (19/19), completed with 19 local objects.remote: Create a pullrequest for 'JY-20676-delete-report-related-objects'on GitHub by viremote:[URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20676-delete-report-related-obHomeDMsActivityFilesLater..•More•ED→Jiminny... vscncral# jiminny-bg# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi...• Direct messages8. Nikolay Yankov€. Vasil VasilevP. Galya Dimitrova MP. Aneliya Angelovaa. Stefka StoyanovaStoyan Tomov6 Todor Stamatov "o Mario Georgiev. Nikolay Ivanovdo James GrahamStoyan TanevLukas Kovalik y...l:: AppsJira CloudToast§ Support Daily • in 2h 21 m100% (8•Tue 19 May 12:39:10Describe what you are looking forNikolay Yankov6 0MessagesAdd canvasLukas Kovalik 12.20 nkToday ~ще погледназа сега направих ПРO Files+Nikolay Yankov 12:33 PMя дайLukas Kovalik 12:34 PMhttps://github.com/jiminny/app/pull/12098за сега добавих такава Cannot enable report withmissing saved search or promptче то в крайна сметка ще гледа и дветепропертитаNikolay Yankov 12:35 PMДобрепо принцип най-добре Галя да одобриLukas Kovalik 12:35 PMдаNikolay Yankov 12:35 PMможе да й пишеш, зе това добавямеако нещо друго иска да кажеLukas Kovalik 12:37 PMOKNikolay Yankov 12:38 PMсамо в кейса на target on_demand ще еhas_reports: true, нали?1ами+Shift + Return to add a new line...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
57247
|
NULL
|
0
|
2026-05-19T09:39:09.985425+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779183549985_m2.jpg...
|
Firefox
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PnostormProiectFV faVsco.js°9 JY-20676-delete-repo PnostormProiectFV faVsco.js°9 JY-20676-delete-report-related-objectsC ActivityController.ong=custom.log=laravel.log4 HS_local [jiminny@localhost]© AskAnythingPromptDto.php( EventsAsKAnytningPromptservice.ong© AskAnythingPromptService.php >© AskAnythingPrompt.phpphp api_v2.phpA console [STAGING]CoachingFeedbackCoachUserin.phpc) Automateakeport.pnpc Historyservice.ongD AskJiminnyAiWAWS0 BillingManagementu cachew countryDatabase→ DatadogDatettimeDealinsiahtsN DealRisks1N GlasticSearchEncoding• Encryption1M SakenD FeatureFlagsD FFMpegD FileSystemD Gong_ cuzzienutou reyPolntsKIOSK_ LanquageDetectionW LOCKSW Math_Mediapioeline2 MobileSettinasNudaeIM ParagranhBreaker1 PartitionedCookieM PlavbackPadeM PlavlistProphetM PronhetAfM DrosnorWorkdM Auonc© AskAnythingPromptServiceTest.php) search.phpclass ASKAnyth1ngPromptService23312V2 л v 182public function edita183AskAnvthingPromot Soromot.User suserstring stitle,strina Scontent.array $shareUsersUuids,array $shareGroupsUuids): AskAnythingPromptDto {...}188 (0public function deletelAskAnythingPrompt $prompt,User Suser): AskAnythingPrompt {...}public function reondendUser suserarray spromptuulds,): void {...}195197199207203* doaram AskAnuthinaPromor Soromot* dreturn arraul arrau<strina>. arrau<strina>1usagepnivate function aetReceiverlluids(AskAnvthingPromot Soromot): arnav/...}lnrivate function deletePromntTfNoRelations(AskAnvthi.naPromotSoromnt: void212if (Sthis->askAnythingRepository->findSharedUsersAndGroupsByPromptId(Sprompt->getId())->iSEmpty 214// Disable and orphan any AutomatedReports that use this prompi$prompt->automatedReports->withTrashed->update([216'ask_anything_prompt_id' => null,'status' => false,1:// Delete only if there are no other relations to [EMAIL]+(Cnnomnt).2202211222223224225private function recreatePromptsForEachRelation(AskAnvthingPrompt Spromot): voidf...}SELECT ar.id, ar.uuid, ar.media type, ar.status, a.typeFROM automated_report_results arJOIN automated_reports a ON a.id = ar.reportidWHERE a.tyRe =TUMET 10:SELECT * EROM automated nenonts where id = 71lSELECT * EROM automated nenont results where renont id = 71.UPDATE automated_reports set playbook_categories = NULL where id = 68SELECT * FROM automated_report_results where id = 275;SELECT * FROM automated_reports order by id desc;SELECT * FROM automated_report_results order by id desc;select * from activity searches where user id = 143:INNER JOIN automated_ reportsautomated_reports'.'idWHERE 1=1AND automated revort• generated ats NUI NULUAND'automated report results"'sent at' IS NOT NULIorts . team 1d = 1AND JSON CONTAINS( 'automated reports', 'recipients'. 143. 's "users"')SELEC * FROM automated renonts where 1d e 6SELECT * FROM automated renorts where 1d = 42SELECT * FROMusers WHERE id = 143; # group 28select * from teams where id = 3143;select * from erm confiaurations where id = 500•select * from users where name = 'Integration Account'; # 1695SELECT * CP0M cocial accountc WHEPE cocjahle id = 1405•colort * fnom activitiec whene enm confiaunation id = 70and recording state = 'recorded' and duration > 60and ctatuc - Icomnlotedi and actual ctant +imo >='2025-12-01'SELECT * FROM activities WHERE uuid to bin('458cf915-b914-4000-b083-5687b32b2956') = uuid:colont d Enom Toode!SELECT * FROM activities WHERE uuid to bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid: # 422003SELECT * FROM activities WHEREid IN (16.422003)SFLFCT * FROM activities where status = 'failed'Socket fail to connect to host:address=(host=localhost) (port=3306)(tvpe=primarv). Connection refused• lue 1y May 12.39:0.+0 ..& console [PROD]# console [euyCascadeAsk Jiminny Report MSo jiminny v021 A1 A18 V2 V6 ^orts trom create() and edtt( Dros (only included in list response):AskAnythingPromptService.phpThought for 6sRead AskAnvthinaPromotServiceTest.pho #L44-223AskAnythingPromptServiceTest.phpSummary of Revisions1. Searchuranstormer now emits has reportsSearchTransformer.nhn: 12_50puoac tunccion transtorm search ssearch. arfayreturn ['1d" = Ssearch→>id stringifilterct e Sthic-saetfilterc/@cearch).+24 -2oends laccessor on the Search model correctly — addina it would have caused unnecessary querieseverywnere the modells serlallzed. Ine tlag now lves only in the wranstormer used oy uistaccivitysearch,2. Rethought the prompt DTOYou're riaht - newlv-created and edited oromots will never have related reports, and most existina oromots won't have anvaihor t• Made AskAnythingPromptDto::ShasReports nullable (?bool ShasReports = null).• Oniv included it in toArravo when it is not null — same conditional pattern as ownerid / sharellsers / shareGrouns |• Removed it from create() and edit() DTO construction in AskAnythingPromptService - they always pass nothingnow, so create/uodate responses won't include has reports.•In get(), it stays — calls Sprompt→>gethaskeports() (your renamed accessor) so the list enapoint emits the tlagThis way the per-row exists() auery is oniv run when the list endooint is hit. never on createledit3. Test undateUindatod toctGotAckAnvthinaDromntein AckAnvthinorromprservicelest. onp to mock dechaskeports on everyprompt mock and reflect the values (one true, three false ) in the expected DTOs. The existing testCreateAskAnythingPromptW1thlwoUsers, testEd1tASKAnyth1ngPrompt, etc. don't need changes — they already construct expected DTOswithout an 8th araument which now matches the null default.lö all «Ask anvthing 884-D)<> Code Claude Qnus 1.7 MediumA 7 files committedJY-20676 delete AJ reports related objectsEdit Commit Messaae.Po. 4 spac...
|
NULL
|
-6450130706111935928
|
NULL
|
click
|
ocr
|
NULL
|
PnostormProiectFV faVsco.js°9 JY-20676-delete-repo PnostormProiectFV faVsco.js°9 JY-20676-delete-report-related-objectsC ActivityController.ong=custom.log=laravel.log4 HS_local [jiminny@localhost]© AskAnythingPromptDto.php( EventsAsKAnytningPromptservice.ong© AskAnythingPromptService.php >© AskAnythingPrompt.phpphp api_v2.phpA console [STAGING]CoachingFeedbackCoachUserin.phpc) Automateakeport.pnpc Historyservice.ongD AskJiminnyAiWAWS0 BillingManagementu cachew countryDatabase→ DatadogDatettimeDealinsiahtsN DealRisks1N GlasticSearchEncoding• Encryption1M SakenD FeatureFlagsD FFMpegD FileSystemD Gong_ cuzzienutou reyPolntsKIOSK_ LanquageDetectionW LOCKSW Math_Mediapioeline2 MobileSettinasNudaeIM ParagranhBreaker1 PartitionedCookieM PlavbackPadeM PlavlistProphetM PronhetAfM DrosnorWorkdM Auonc© AskAnythingPromptServiceTest.php) search.phpclass ASKAnyth1ngPromptService23312V2 л v 182public function edita183AskAnvthingPromot Soromot.User suserstring stitle,strina Scontent.array $shareUsersUuids,array $shareGroupsUuids): AskAnythingPromptDto {...}188 (0public function deletelAskAnythingPrompt $prompt,User Suser): AskAnythingPrompt {...}public function reondendUser suserarray spromptuulds,): void {...}195197199207203* doaram AskAnuthinaPromor Soromot* dreturn arraul arrau<strina>. arrau<strina>1usagepnivate function aetReceiverlluids(AskAnvthingPromot Soromot): arnav/...}lnrivate function deletePromntTfNoRelations(AskAnvthi.naPromotSoromnt: void212if (Sthis->askAnythingRepository->findSharedUsersAndGroupsByPromptId(Sprompt->getId())->iSEmpty 214// Disable and orphan any AutomatedReports that use this prompi$prompt->automatedReports->withTrashed->update([216'ask_anything_prompt_id' => null,'status' => false,1:// Delete only if there are no other relations to [EMAIL]+(Cnnomnt).2202211222223224225private function recreatePromptsForEachRelation(AskAnvthingPrompt Spromot): voidf...}SELECT ar.id, ar.uuid, ar.media type, ar.status, a.typeFROM automated_report_results arJOIN automated_reports a ON a.id = ar.reportidWHERE a.tyRe =TUMET 10:SELECT * EROM automated nenonts where id = 71lSELECT * EROM automated nenont results where renont id = 71.UPDATE automated_reports set playbook_categories = NULL where id = 68SELECT * FROM automated_report_results where id = 275;SELECT * FROM automated_reports order by id desc;SELECT * FROM automated_report_results order by id desc;select * from activity searches where user id = 143:INNER JOIN automated_ reportsautomated_reports'.'idWHERE 1=1AND automated revort• generated ats NUI NULUAND'automated report results"'sent at' IS NOT NULIorts . team 1d = 1AND JSON CONTAINS( 'automated reports', 'recipients'. 143. 's "users"')SELEC * FROM automated renonts where 1d e 6SELECT * FROM automated renorts where 1d = 42SELECT * FROMusers WHERE id = 143; # group 28select * from teams where id = 3143;select * from erm confiaurations where id = 500•select * from users where name = 'Integration Account'; # 1695SELECT * CP0M cocial accountc WHEPE cocjahle id = 1405•colort * fnom activitiec whene enm confiaunation id = 70and recording state = 'recorded' and duration > 60and ctatuc - Icomnlotedi and actual ctant +imo >='2025-12-01'SELECT * FROM activities WHERE uuid to bin('458cf915-b914-4000-b083-5687b32b2956') = uuid:colont d Enom Toode!SELECT * FROM activities WHERE uuid to bin('f43cf158-e60d-46e5-92f8-c4e0594a3219') = uuid: # 422003SELECT * FROM activities WHEREid IN (16.422003)SFLFCT * FROM activities where status = 'failed'Socket fail to connect to host:address=(host=localhost) (port=3306)(tvpe=primarv). Connection refused• lue 1y May 12.39:0.+0 ..& console [PROD]# console [euyCascadeAsk Jiminny Report MSo jiminny v021 A1 A18 V2 V6 ^orts trom create() and edtt( Dros (only included in list response):AskAnythingPromptService.phpThought for 6sRead AskAnvthinaPromotServiceTest.pho #L44-223AskAnythingPromptServiceTest.phpSummary of Revisions1. Searchuranstormer now emits has reportsSearchTransformer.nhn: 12_50puoac tunccion transtorm search ssearch. arfayreturn ['1d" = Ssearch→>id stringifilterct e Sthic-saetfilterc/@cearch).+24 -2oends laccessor on the Search model correctly — addina it would have caused unnecessary querieseverywnere the modells serlallzed. Ine tlag now lves only in the wranstormer used oy uistaccivitysearch,2. Rethought the prompt DTOYou're riaht - newlv-created and edited oromots will never have related reports, and most existina oromots won't have anvaihor t• Made AskAnythingPromptDto::ShasReports nullable (?bool ShasReports = null).• Oniv included it in toArravo when it is not null — same conditional pattern as ownerid / sharellsers / shareGrouns |• Removed it from create() and edit() DTO construction in AskAnythingPromptService - they always pass nothingnow, so create/uodate responses won't include has reports.•In get(), it stays — calls Sprompt→>gethaskeports() (your renamed accessor) so the list enapoint emits the tlagThis way the per-row exists() auery is oniv run when the list endooint is hit. never on createledit3. Test undateUindatod toctGotAckAnvthinaDromntein AckAnvthinorromprservicelest. onp to mock dechaskeports on everyprompt mock and reflect the values (one true, three false ) in the expected DTOs. The existing testCreateAskAnythingPromptW1thlwoUsers, testEd1tASKAnyth1ngPrompt, etc. don't need changes — they already construct expected DTOswithout an 8th araument which now matches the null default.lö all «Ask anvthing 884-D)<> Code Claude Qnus 1.7 MediumA 7 files committedJY-20676 delete AJ reports related objectsEdit Commit Messaae.Po. 4 spac...
|
57245
|
NULL
|
NULL
|
NULL
|
|
57212
|
NULL
|
0
|
2026-05-19T09:34:00.462377+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779183240462_m2.jpg...
|
Firefox
|
JY-20676 delete AJ reports related objects by Laky JY-20676 delete AJ reports related objects by LakyLak · Pull Request #12098 · jiminny/app — Work...
|
1
|
github.com/jiminny/app/pull/12098
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
JY-20808 low priority indexing queue by Vasil-Jimi JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
github.com
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
Close tab
Pipelines - jiminny/app
Pipelines - jiminny/app
New Tab
New Tab
Jiminny
Jiminny
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST [URL_WITH_CREDENTIALS]
Show options
LakyLak commented 32 minutes ago
LakyLak
LakyLak
commented
32 minutes ago
32 minutes ago
JIRA: JY-20676
JIRA:
JY-20676
JY-20676
Changes:
Changes:
Add field has_reports to Activity search and Ask Jiminny prompts lists
mark related object null on its deletion and disable report
Validate prompt and search fields on activate report toggle
Add or remove reactions
@LakyLak
JY-20676
JY-20676
delete AJ reports related objects
delete AJ reports related objects
11 / 12 checks OK
02a3381
02a3381
@sonarqubecloud
Show options
sonarqubecloud Bot commented 23 minutes ago
sonarqubecloud
sonarqubecloud
Bot
commented
23 minutes ago
23 minutes ago
Quality Gate Failed Quality Gate failed
Quality Gate Failed
Quality Gate failed
Failed conditions
1 New Code Smells
1 New Code Smells
(required ≤ 0)
See analysis details on SonarQube Cloud
See analysis details on SonarQube Cloud
Catch issues before they fail your Quality Gate with our IDE extension
SonarQube for IDE
SonarQube for IDE
Add or remove reactions
This branch has not been deployed
This branch has not been deployed
No deployments
Loading
@LakyLak
Add a comment
Add a comment
Comment
Write
Write
Preview
Preview
Comment
Markdown is supported
Markdown
is supported
Paste, drop, or click to add files
Paste, drop, or click to add files
Close pull request
Close pull request
Comment
Remember, contributions to this repository should follow our
GitHub Community Guidelines
GitHub Community Guidelines
.
ProTip!
Add comments to specific lines under
Files changed
Files changed
.
Reviewers...
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app","depth":4,"bounds":{"left":0.08361037,"top":0.15722266,"width":0.082446806,"height":0.032322425},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"github.com","depth":4,"bounds":{"left":0.08361037,"top":0.17877094,"width":0.019614361,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0,"top":0.0518755,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.06304868,"width":0.10106383,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"bounds":{"left":0.0,"top":0.08459697,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.09577015,"width":0.10721409,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.11731844,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.12849163,"width":0.18816489,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.15003991,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.16121309,"width":0.15674867,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.06732048,"top":0.15722266,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.18276137,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.19393456,"width":0.039228722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.0,"top":0.21548285,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"bounds":{"left":0.013297873,"top":0.22665602,"width":0.014960106,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.2482043,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.013297873,"top":0.25937748,"width":0.013131649,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":4,"bounds":{"left":0.0,"top":0.28092578,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":5,"bounds":{"left":0.013297873,"top":0.29209897,"width":0.4644282,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20676 delete AJ reports related objects by LakyLak · Pull Request #12098 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.31364724,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"JY-20676 delete AJ reports related objects by LakyLak · Pull Request #12098 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.32482043,"width":0.15791224,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.06732048,"top":0.32083002,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.0028257978,"top":0.34796488,"width":0.07413564,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0028257978,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.013796543,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.024933511,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.036070477,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.04720745,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to content","depth":6,"bounds":{"left":0.07962101,"top":0.0518755,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to content","depth":7,"bounds":{"left":0.07962101,"top":0.05347167,"width":0.0029920214,"height":0.21468475},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open menu","depth":10,"bounds":{"left":0.08494016,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Homepage (g then d)","depth":9,"bounds":{"left":0.099567816,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"jiminny","depth":12,"bounds":{"left":0.112865694,"top":0.06464485,"width":0.018949468,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jiminny","depth":14,"bounds":{"left":0.11486037,"top":0.07063048,"width":0.014960106,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":12,"bounds":{"left":0.13680187,"top":0.06464485,"width":0.017785905,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":14,"bounds":{"left":0.13879654,"top":0.07063048,"width":0.008477394,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search or jump to…","depth":9,"bounds":{"left":0.81698805,"top":0.06464485,"width":0.06565824,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":12,"bounds":{"left":0.82928854,"top":0.07063048,"width":0.011801862,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":12,"bounds":{"left":0.8424202,"top":0.07222666,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to search","depth":12,"bounds":{"left":0.84640956,"top":0.07063048,"width":0.021276595,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chat with Copilot","depth":10,"bounds":{"left":0.88464093,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Open Copilot…","depth":9,"bounds":{"left":0.8949468,"top":0.06464485,"width":0.008643617,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Create new...","depth":9,"bounds":{"left":0.9115692,"top":0.06464485,"width":0.01662234,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"All issues(g then i)","depth":9,"bounds":{"left":0.93085104,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All pull requests","depth":9,"bounds":{"left":0.94414896,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All repositories","depth":9,"bounds":{"left":0.9574468,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"You have no unread notifications(g then n)","depth":9,"bounds":{"left":0.97074467,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open user navigation menu","depth":9,"bounds":{"left":0.9840425,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Repository navigation","depth":9,"bounds":{"left":0.079288565,"top":0.051077414,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Repository navigation","depth":10,"bounds":{"left":0.079288565,"top":0.05387071,"width":0.0787899,"height":0.023144454},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":12,"bounds":{"left":0.08494016,"top":0.09936153,"width":0.025099734,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":14,"bounds":{"left":0.095744684,"top":0.10574621,"width":0.011469414,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull requests (30)","depth":12,"bounds":{"left":0.11269947,"top":0.09936153,"width":0.05518617,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests","depth":14,"bounds":{"left":0.12333777,"top":0.10574621,"width":0.02925532,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"bounds":{"left":0.15525267,"top":0.113727055,"width":0.0029920214,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30","depth":14,"bounds":{"left":0.15824468,"top":0.113727055,"width":0.005817819,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"bounds":{"left":0.1640625,"top":0.113727055,"width":0.0016622341,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Agents","depth":12,"bounds":{"left":0.1705452,"top":0.09936153,"width":0.029089095,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Agents","depth":14,"bounds":{"left":0.18151596,"top":0.10574621,"width":0.014960106,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Actions","depth":12,"bounds":{"left":0.20229389,"top":0.09936153,"width":0.03025266,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Actions","depth":14,"bounds":{"left":0.21343085,"top":0.10574621,"width":0.015957447,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Wiki","depth":12,"bounds":{"left":0.23520611,"top":0.09936153,"width":0.022938829,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Wiki","depth":14,"bounds":{"left":0.24601063,"top":0.10574621,"width":0.009142287,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security and quality","depth":12,"bounds":{"left":0.26080453,"top":0.09936153,"width":0.05817819,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security and quality","depth":14,"bounds":{"left":0.27260637,"top":0.10574621,"width":0.04255319,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Insights","depth":12,"bounds":{"left":0.32164228,"top":0.09936153,"width":0.03125,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Insights","depth":14,"bounds":{"left":0.33277926,"top":0.10574621,"width":0.016788565,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":12,"bounds":{"left":0.35555187,"top":0.09936153,"width":0.032081116,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":14,"bounds":{"left":0.36668882,"top":0.10574621,"width":0.01761968,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Important update","depth":10,"bounds":{"left":0.09325133,"top":0.14365523,"width":0.0003324468,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Important update","depth":11,"bounds":{"left":0.09325133,"top":0.1452514,"width":0.039228722,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.","depth":10,"bounds":{"left":0.09325133,"top":0.1452514,"width":0.2159242,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review this update","depth":10,"bounds":{"left":0.30917552,"top":0.1452514,"width":0.04055851,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review this update","depth":11,"bounds":{"left":0.30917552,"top":0.1452514,"width":0.04055851,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and manage your preferences in your","depth":10,"bounds":{"left":0.34973404,"top":0.1452514,"width":0.08261303,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub account settings","depth":10,"bounds":{"left":0.4323471,"top":0.1452514,"width":0.05219415,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GitHub account settings","depth":11,"bounds":{"left":0.4323471,"top":0.1452514,"width":0.05219415,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"bounds":{"left":0.48454124,"top":0.1452514,"width":0.0013297872,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dismiss banner","depth":9,"bounds":{"left":0.98636967,"top":0.13886672,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"JY-20676 delete AJ reports related objects #12098 Edit title","depth":13,"bounds":{"left":0.33776596,"top":0.19193934,"width":0.24817154,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"JY-20676 delete AJ reports related objects","depth":14,"bounds":{"left":0.33776596,"top":0.19273743,"width":0.19680852,"height":0.030327214},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"#","depth":15,"bounds":{"left":0.53723407,"top":0.19273743,"width":0.006482713,"height":0.030327214},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12098","depth":15,"bounds":{"left":0.5437167,"top":0.19273743,"width":0.03025266,"height":0.030327214},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Edit title","depth":14,"bounds":{"left":0.5752992,"top":0.19513169,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"View statusView status","depth":13,"bounds":{"left":0.6761968,"top":0.19832402,"width":0.034906916,"height":0.025538707},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Loading","depth":15,"bounds":{"left":0.6909907,"top":0.20670392,"width":0.017453458,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Loading merge status","depth":15,"bounds":{"left":0.6761968,"top":0.22705507,"width":0.06632314,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Code","depth":13,"bounds":{"left":0.7137633,"top":0.19832402,"width":0.02825798,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Code","depth":15,"bounds":{"left":0.7180851,"top":0.20430966,"width":0.011635638,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Open","depth":13,"bounds":{"left":0.34840426,"top":0.23623304,"width":0.011968086,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":15,"bounds":{"left":0.36702126,"top":0.2330407,"width":0.018450798,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":16,"bounds":{"left":0.36702126,"top":0.23463687,"width":0.018450798,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"wants to merge 1 commit into","depth":15,"bounds":{"left":0.38680187,"top":0.23463687,"width":0.06349734,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"master","depth":15,"bounds":{"left":0.45162898,"top":0.23264167,"width":0.018284574,"height":0.017557861},"on_screen":true,"role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"master","depth":16,"bounds":{"left":0.45362368,"top":0.235834,"width":0.014295213,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"from","depth":16,"bounds":{"left":0.47124335,"top":0.23463687,"width":0.009973404,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"JY-20676-delete-report-related-objects","depth":16,"bounds":{"left":0.48254654,"top":0.23264167,"width":0.09524601,"height":0.017557861},"on_screen":true,"role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20676-delete-report-related-objects","depth":17,"bounds":{"left":0.48454124,"top":0.235834,"width":0.09125665,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy head branch name to clipboard","depth":16,"bounds":{"left":0.57912236,"top":0.23024741,"width":0.00930851,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Lines changed: 60 additions & 9 deletions","depth":14,"bounds":{"left":0.7117686,"top":0.28651237,"width":0.019946808,"height":0.11412609},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Conversation (1)","depth":16,"bounds":{"left":0.33776596,"top":0.26855546,"width":0.054022606,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Conversation","depth":17,"bounds":{"left":0.35006648,"top":0.27813247,"width":0.028091755,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"bounds":{"left":0.38746676,"top":0.27813247,"width":0.0029920214,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":18,"bounds":{"left":0.39045876,"top":0.27813247,"width":0.0021609042,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":18,"bounds":{"left":0.39261967,"top":0.27813247,"width":0.0016622341,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Commits (1)","depth":16,"bounds":{"left":0.39178857,"top":0.26855546,"width":0.04504654,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Commits","depth":17,"bounds":{"left":0.4040891,"top":0.27813247,"width":0.019115692,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"bounds":{"left":0.4325133,"top":0.27813247,"width":0.0029920214,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":18,"bounds":{"left":0.43550533,"top":0.27813247,"width":0.0021609042,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":18,"bounds":{"left":0.43766624,"top":0.27813247,"width":0.0016622341,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Checks (3)","depth":16,"bounds":{"left":0.4368351,"top":0.26855546,"width":0.042386968,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Checks","depth":17,"bounds":{"left":0.44913563,"top":0.27813247,"width":0.015957447,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"bounds":{"left":0.47490028,"top":0.27813247,"width":0.0029920214,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3","depth":18,"bounds":{"left":0.47789228,"top":0.27813247,"width":0.0029920214,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":18,"bounds":{"left":0.4808843,"top":0.27813247,"width":0.0016622341,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Files changed (7)","depth":16,"bounds":{"left":0.4792221,"top":0.26855546,"width":0.05618351,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Files changed","depth":17,"bounds":{"left":0.4915226,"top":0.27813247,"width":0.029753989,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"bounds":{"left":0.53108376,"top":0.27813247,"width":0.0029920214,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7","depth":18,"bounds":{"left":0.5340758,"top":0.27813247,"width":0.002493351,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":18,"bounds":{"left":0.5365692,"top":0.27813247,"width":0.0018284575,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Conversation","depth":12,"bounds":{"left":0.33776596,"top":0.3140463,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation","depth":13,"bounds":{"left":0.33776596,"top":0.31683958,"width":0.048204787,"height":0.023144454},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@LakyLak","depth":12,"bounds":{"left":0.33776596,"top":0.3140463,"width":0.013297873,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show options","depth":15,"bounds":{"left":0.61136967,"top":0.31484437,"width":0.007978723,"height":0.02952913},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"LakyLak commented 32 minutes ago","depth":14,"bounds":{"left":0.3620346,"top":0.31484437,"width":0.24135639,"height":0.02952913},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":16,"bounds":{"left":0.3620346,"top":0.32282522,"width":0.018450798,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":17,"bounds":{"left":0.3620346,"top":0.32282522,"width":0.018450798,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"commented","depth":15,"bounds":{"left":0.38181517,"top":0.32282522,"width":0.025598405,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"32 minutes ago","depth":15,"bounds":{"left":0.40874335,"top":0.32122904,"width":0.03324468,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"32 minutes ago","depth":17,"bounds":{"left":0.40874335,"top":0.32282522,"width":0.03324468,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"JIRA: JY-20676","depth":16,"bounds":{"left":0.3620346,"top":0.35794094,"width":0.25731382,"height":0.017557861},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"JIRA:","depth":17,"bounds":{"left":0.3620346,"top":0.35834,"width":0.015791224,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"JY-20676","depth":17,"bounds":{"left":0.3778258,"top":0.35834,"width":0.027426861,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20676","depth":18,"bounds":{"left":0.3778258,"top":0.35834,"width":0.027426861,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Changes:","depth":16,"bounds":{"left":0.3620346,"top":0.39465284,"width":0.25731382,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Changes:","depth":17,"bounds":{"left":0.3620346,"top":0.39465284,"width":0.021110373,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Add field has_reports to Activity search and Ask Jiminny prompts lists","depth":18,"bounds":{"left":0.3700133,"top":0.42298484,"width":0.15009974,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"mark related object null on its deletion and disable report","depth":18,"bounds":{"left":0.3700133,"top":0.4425379,"width":0.12267287,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Validate prompt and search fields on activate report toggle","depth":18,"bounds":{"left":0.3700133,"top":0.46249002,"width":0.1263298,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Add or remove reactions","depth":16,"bounds":{"left":0.3620346,"top":0.490423,"width":0.008643617,"height":0.0207502},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"@LakyLak","depth":12,"bounds":{"left":0.3700133,"top":0.55426973,"width":0.0066489363,"height":0.015961692},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20676","depth":14,"bounds":{"left":0.37865692,"top":0.55786115,"width":0.019115692,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20676","depth":15,"bounds":{"left":0.37865692,"top":0.55786115,"width":0.019115692,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"delete AJ reports related objects","depth":14,"bounds":{"left":0.40009972,"top":0.55786115,"width":0.079288565,"height":0.011572227},"on_screen":true,"help_text":"JY-20676 delete AJ reports related objects","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"delete AJ reports related objects","depth":15,"bounds":{"left":0.40009972,"top":0.55786115,"width":0.079288565,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"11 / 12 checks OK","depth":14,"bounds":{"left":0.60139626,"top":0.55426973,"width":0.005319149,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"02a3381","depth":14,"bounds":{"left":0.6080452,"top":0.55786115,"width":0.016954787,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"02a3381","depth":15,"bounds":{"left":0.6080452,"top":0.55786115,"width":0.016954787,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@sonarqubecloud","depth":13,"bounds":{"left":0.33776596,"top":0.60135674,"width":0.013297873,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show options","depth":14,"bounds":{"left":0.61136967,"top":0.60215485,"width":0.007978723,"height":0.02952913},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"sonarqubecloud Bot commented 23 minutes ago","depth":13,"bounds":{"left":0.3620346,"top":0.60215485,"width":0.24135639,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"sonarqubecloud","depth":15,"bounds":{"left":0.3620346,"top":0.6101357,"width":0.036236703,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"sonarqubecloud","depth":16,"bounds":{"left":0.3620346,"top":0.6101357,"width":0.036236703,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Bot","depth":16,"bounds":{"left":0.40176198,"top":0.6117318,"width":0.0066489363,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"commented","depth":14,"bounds":{"left":0.41206783,"top":0.6105347,"width":0.025598405,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"23 minutes ago","depth":14,"bounds":{"left":0.43899602,"top":0.6089386,"width":0.03324468,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"23 minutes ago","depth":16,"bounds":{"left":0.43899602,"top":0.6105347,"width":0.03324468,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Quality Gate Failed Quality Gate failed","depth":16,"bounds":{"left":0.3620346,"top":0.64565045,"width":0.25731382,"height":0.026735835},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"Quality Gate Failed","depth":17,"bounds":{"left":0.3620346,"top":0.6460495,"width":0.0066489363,"height":0.019952115},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Quality Gate failed","depth":18,"bounds":{"left":0.37034574,"top":0.6460495,"width":0.05867686,"height":0.019952115},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Failed conditions","depth":17,"bounds":{"left":0.3620346,"top":0.6867518,"width":0.036236703,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 New Code Smells","depth":17,"bounds":{"left":0.36851728,"top":0.7035116,"width":0.041223403,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1 New Code Smells","depth":18,"bounds":{"left":0.36851728,"top":0.7035116,"width":0.041223403,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(required ≤ 0)","depth":17,"bounds":{"left":0.4097407,"top":0.7035116,"width":0.031083776,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"See analysis details on SonarQube Cloud","depth":17,"bounds":{"left":0.3620346,"top":0.7330407,"width":0.087932184,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"See analysis details on SonarQube Cloud","depth":18,"bounds":{"left":0.3620346,"top":0.7330407,"width":0.087932184,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Catch issues before they fail your Quality Gate with our IDE extension","depth":17,"bounds":{"left":0.36735374,"top":0.7877095,"width":0.1512633,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"SonarQube for IDE","depth":17,"bounds":{"left":0.52526593,"top":0.7877095,"width":0.040059842,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SonarQube for IDE","depth":18,"bounds":{"left":0.52526593,"top":0.7877095,"width":0.040059842,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Add or remove reactions","depth":15,"bounds":{"left":0.3620346,"top":0.8156425,"width":0.008643617,"height":0.0207502},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"This branch has not been deployed","depth":14,"bounds":{"left":0.375,"top":0.89066243,"width":0.2443484,"height":0.017956903},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"This branch has not been deployed","depth":15,"bounds":{"left":0.375,"top":0.89185953,"width":0.08843085,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"No deployments","depth":14,"bounds":{"left":0.375,"top":0.9102155,"width":0.03274601,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Loading","depth":13,"bounds":{"left":0.48537233,"top":0.9940144,"width":0.016954787,"height":0.0059856176},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@LakyLak","depth":15,"bounds":{"left":0.33776596,"top":1.0,"width":0.013297873,"height":-0.07302475},"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Add a comment","depth":17,"bounds":{"left":0.35638297,"top":1.0,"width":0.03956117,"height":-0.07302475},"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Add a comment","depth":18,"bounds":{"left":0.35638297,"top":1.0,"width":0.03956117,"height":-0.075019956},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Comment","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Write","depth":18,"bounds":{"left":0.35638297,"top":1.0,"width":0.022606382,"height":-0.09856343},"on_screen":false,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Write","depth":19,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Preview","depth":18,"bounds":{"left":0.37898937,"top":1.0,"width":0.028091755,"height":-0.09856343},"on_screen":false,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Preview","depth":19,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"Comment","depth":20,"on_screen":false,"placeholder":" ","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Markdown is supported","depth":19,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Markdown","depth":21,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"is supported","depth":21,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Paste, drop, or click to add files","depth":18,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Paste, drop, or click to add files","depth":20,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close pull request","depth":17,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Close pull request","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Comment","depth":17,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Remember, contributions to this repository should follow our","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub Community Guidelines","depth":15,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GitHub Community Guidelines","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ProTip!","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Add comments to specific lines under","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Files changed","depth":15,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Files changed","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Reviewers","depth":16,"bounds":{"left":0.6356383,"top":0.3140463,"width":0.10638298,"height":0.0207502},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-5633135367624394521
|
5933333154515141017
|
visual_change
|
accessibility
|
NULL
|
JY-20808 low priority indexing queue by Vasil-Jimi JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
github.com
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
Close tab
Pipelines - jiminny/app
Pipelines - jiminny/app
New Tab
New Tab
Jiminny
Jiminny
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST [URL_WITH_CREDENTIALS]
Show options
LakyLak commented 32 minutes ago
LakyLak
LakyLak
commented
32 minutes ago
32 minutes ago
JIRA: JY-20676
JIRA:
JY-20676
JY-20676
Changes:
Changes:
Add field has_reports to Activity search and Ask Jiminny prompts lists
mark related object null on its deletion and disable report
Validate prompt and search fields on activate report toggle
Add or remove reactions
@LakyLak
JY-20676
JY-20676
delete AJ reports related objects
delete AJ reports related objects
11 / 12 checks OK
02a3381
02a3381
@sonarqubecloud
Show options
sonarqubecloud Bot commented 23 minutes ago
sonarqubecloud
sonarqubecloud
Bot
commented
23 minutes ago
23 minutes ago
Quality Gate Failed Quality Gate failed
Quality Gate Failed
Quality Gate failed
Failed conditions
1 New Code Smells
1 New Code Smells
(required ≤ 0)
See analysis details on SonarQube Cloud
See analysis details on SonarQube Cloud
Catch issues before they fail your Quality Gate with our IDE extension
SonarQube for IDE
SonarQube for IDE
Add or remove reactions
This branch has not been deployed
This branch has not been deployed
No deployments
Loading
@LakyLak
Add a comment
Add a comment
Comment
Write
Write
Preview
Preview
Comment
Markdown is supported
Markdown
is supported
Paste, drop, or click to add files
Paste, drop, or click to add files
Close pull request
Close pull request
Comment
Remember, contributions to this repository should follow our
GitHub Community Guidelines
GitHub Community Guidelines
.
ProTip!
Add comments to specific lines under
Files changed
Files changed
.
Reviewers...
|
57211
|
NULL
|
NULL
|
NULL
|
|
57208
|
NULL
|
0
|
2026-05-19T09:33:43.418957+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779183223418_m1.jpg...
|
Firefox
|
Issues - app in Jiminny SonarQube Cloud — Work
|
1
|
sonarcloud.io/project/issues?sinceLeakPeriod=true& sonarcloud.io/project/issues?sinceLeakPeriod=true&issueStatuses=OPEN%2CCONFIRMED&types=CODE_SMELL&pullRequest=12098&id=jiminny_app&open=AZ4_gKRmOMt1tbwo_jHV...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpAPPAPP (-zs.•• SlackFileEditViewGoHistoryWindowHelpAPPAPP (-zs.•••EDDOCKER• ₴1DEV (docker)Copyright (c) The PHP GroupZend Engine v4.3.30, Copyright (c) Zend Technologieswith Zend OPcache v8.3.30, Copyright (C), by Zend Technologies₴82What's next:Try Docker Debug for seamless, persistentdebugging tools in any containerimage →Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20676-delete-report-related-obEnumerating objects: 45, done.Counting objects: 100% (45/45), done.Delta compression using up to 8 threadsCompressing objects: 100% (24/24), done.Writing objects: 100% (24/24), 3.62 KiB | 3.62 MiB/s, done.Total 24 (delta 19), reused 0 (delta 0), pack-reused 0remote: Resolving deltas: 100% (19/19), completed with 19 local objects.remote:remote: Create a pullrequest for 'JY-20676-delete-report-related-objects'on GitHub by viremote:[URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20676-delete-report-related-obHomeDMsActivityFilesLater..•More→Jiminny... vscnicrat# jiminny-bg# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi...• Direct messages8. Nikolay Yankov€. Vasil VasilevP. Galya Dimitrova DP. Aneliya Angelovaa. Stefka StoyanovaStoyan Tomov6 Todor Stamatov "o Mario Georgiev. Nikolay Ivanovdo James GrahamStoyan TanevLukas Kovalik y...l:: AppsJira CloudToastSupport Daily - in 2 h 27 m100% (8•Tue 19 May 12:33:43Describe what you are looking forNikolay Yankov6 0• MessagesAdd canvas@ Files+да го даваме зLukas Kovalik 2:42 PMдаYesterday ~Nikolay Yankov 3:02 PMтестове фейлватрьннах го 2 пътиToday ~Nikolay Yankov 10:05 AM/api/v2/user/ask-anything-prompts?target=on_demandhas_reports/api/v2/user/ask-anything-prompts/3381a35f-f1a3-431d-9510-bd079cd80ed6DELETE/api/v1/activity/saved-searchNikolay Yankov 12:17 PMМисля, че можеш да вкараш такава грешка приtoggle-aA prompt is required to enable this report.Edit the report to select a prompt first.Lukas Kovalik 12:33 PMще погледназа сега направих ПРMessage Nikolay Yankov+Aa...
|
NULL
|
-609106452792010318
|
NULL
|
click
|
ocr
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpAPPAPP (-zs.•• SlackFileEditViewGoHistoryWindowHelpAPPAPP (-zs.•••EDDOCKER• ₴1DEV (docker)Copyright (c) The PHP GroupZend Engine v4.3.30, Copyright (c) Zend Technologieswith Zend OPcache v8.3.30, Copyright (C), by Zend Technologies₴82What's next:Try Docker Debug for seamless, persistentdebugging tools in any containerimage →Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20676-delete-report-related-obEnumerating objects: 45, done.Counting objects: 100% (45/45), done.Delta compression using up to 8 threadsCompressing objects: 100% (24/24), done.Writing objects: 100% (24/24), 3.62 KiB | 3.62 MiB/s, done.Total 24 (delta 19), reused 0 (delta 0), pack-reused 0remote: Resolving deltas: 100% (19/19), completed with 19 local objects.remote:remote: Create a pullrequest for 'JY-20676-delete-report-related-objects'on GitHub by viremote:[URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20676-delete-report-related-obHomeDMsActivityFilesLater..•More→Jiminny... vscnicrat# jiminny-bg# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi...• Direct messages8. Nikolay Yankov€. Vasil VasilevP. Galya Dimitrova DP. Aneliya Angelovaa. Stefka StoyanovaStoyan Tomov6 Todor Stamatov "o Mario Georgiev. Nikolay Ivanovdo James GrahamStoyan TanevLukas Kovalik y...l:: AppsJira CloudToastSupport Daily - in 2 h 27 m100% (8•Tue 19 May 12:33:43Describe what you are looking forNikolay Yankov6 0• MessagesAdd canvas@ Files+да го даваме зLukas Kovalik 2:42 PMдаYesterday ~Nikolay Yankov 3:02 PMтестове фейлватрьннах го 2 пътиToday ~Nikolay Yankov 10:05 AM/api/v2/user/ask-anything-prompts?target=on_demandhas_reports/api/v2/user/ask-anything-prompts/3381a35f-f1a3-431d-9510-bd079cd80ed6DELETE/api/v1/activity/saved-searchNikolay Yankov 12:17 PMМисля, че можеш да вкараш такава грешка приtoggle-aA prompt is required to enable this report.Edit the report to select a prompt first.Lukas Kovalik 12:33 PMще погледназа сега направих ПРMessage Nikolay Yankov+Aa...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
57201
|
NULL
|
0
|
2026-05-19T09:22:34.392467+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779182554392_m2.jpg...
|
Firefox
|
Issues - app in Jiminny SonarQube Cloud — Work
|
1
|
sonarcloud.io/project/issues?sinceLeakPeriod=true& sonarcloud.io/project/issues?sinceLeakPeriod=true&issueStatuses=OPEN%2CCONFIRMED&types=CODE_SMELL&pullRequest=12098&id=jiminny_app&open=AZ4_gKRmOMt1tbwo_jHV...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
New Tab
New Tab
Jiminny
Jiminny
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
Issues - app in Jiminny SonarQube Cloud
Issues - app in Jiminny SonarQube Cloud
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to main content
Skip to main content
Skip to issues list
Skip to issues list
Undock sidebar
Continuous Code Quality
Favorite Projects
Favorite Projects
Assigned Issues
Assigned Issues
Explore
Explore
Search
Product news
1
Help
New...
Account
app
Project
Overview
Overview
Analysis
Summary
Summary
Issues
Issues
Architecture
Architecture
Security hotspots
Security hotspots
Reporting
Measures
Measures
Activity
Activity
Policies
Intended architecture
Intended architecture
Project
Pull Requests 111
Pull Requests
111
Branches 15
Branches
15
Code
Code
Project Information
Project Information
Jiminny
Jiminny
app
app
Issues
Issues
Merge this if statement with the enclosing one.
Issues
Issues
12098 – JY-20676 delete AJ reports related objects
12098 – JY-20676 delete AJ reports related objects
1 /
1
issues
Reload
app/.../API/V2/AskJiminnyReportsController.php
Merge this if statement with the enclosing one.
Merge this if statement with the enclosing one.
1 of 1 shown
Intentionality | Not clear
Intentionality
|
Not clear
Merge this if statement with the enclosing one. Permanent Link
Merge this if statement with the enclosing one.
Permanent Link
Mergeable "if" statements should be combined
php:S1066
php:S1066
Software qualities impacted:
Maintainability
Medium severity impact on Maintainability. Click for more information.
Medium
Open in IDE
Open in IDE
Open
Open
Lukas Kovalik Lukas Kovalik
Lukas Kovalik
Code Smell
Major
Tags
clumsy +
clumsy
+
Line affected
L141
Effort
5
min
Introduced
28 minutes ago
Where is the issue?
Where is the issue?
Why is this an issue?
Why is this an issue?
Activity
Activity
app/Http/Controllers/API/V2/
AskJiminnyReportsController.php
Copy the file path to the clipboard
See all issues in this file
See all issues in this file
Line: 1
Author: [EMAIL], Click to see SCM information
<?php
Line: 2
Author: [EMAIL], Click to see SCM information
Line: 3
Author: [EMAIL], Click to see SCM information
declare
(strict_types=
1
);
Line: 4
Author: [EMAIL], Click to see SCM information
Line: 5
Author: [EMAIL], Click to see SCM information
namespace
Jiminny\Http\Controllers\API\V2;
Line: 6
Author: [EMAIL], Click to see SCM information
Line: 7
Author: [EMAIL], Click to see SCM information
use
Illuminate\Http\JsonResponse;
Line: 8
Author: [EMAIL], Click to see SCM information
use
Illuminate\Http\Request;
Line: 9
Author: [EMAIL], Click to see SCM information
use
Illuminate\Routing\Controller;
Line: 10
Author: [EMAIL], Click to see SCM information
use
Jiminny\Exceptions\InvalidArgumentException;
Line: 11
Author: [EMAIL], Click to see SCM information
use
Jiminny\Exceptions\ModelNotFoundException;
Line: 12
Author: [EMAIL], Click to see SCM information
use
Jiminny\Models\AutomatedReport;
Line: 13
Author: [EMAIL], Click to see SCM information
use
Jiminny\Models\User;...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0,"top":0.0518755,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.06304868,"width":0.10106383,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"bounds":{"left":0.0,"top":0.08459697,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.09577015,"width":0.10721409,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.11731844,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.12849163,"width":0.18816489,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.15003991,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.16121309,"width":0.15674867,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.18276137,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.19393456,"width":0.039228722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.0,"top":0.21548285,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"bounds":{"left":0.013297873,"top":0.22665602,"width":0.014960106,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.2482043,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.013297873,"top":0.25937748,"width":0.013131649,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":4,"bounds":{"left":0.0,"top":0.28092578,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":5,"bounds":{"left":0.013297873,"top":0.29209897,"width":0.4644282,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Issues - app in Jiminny SonarQube Cloud","depth":4,"bounds":{"left":0.0,"top":0.31364724,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Issues - app in Jiminny SonarQube Cloud","depth":5,"bounds":{"left":0.013297873,"top":0.32482043,"width":0.071476065,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.06732048,"top":0.32083002,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.0028257978,"top":0.34796488,"width":0.07413564,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0028257978,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.013796543,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.024933511,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.036070477,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.04720745,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to main content","depth":7,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to main content","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Skip to issues list","depth":7,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to issues list","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Undock sidebar","depth":8,"bounds":{"left":0.08361037,"top":0.059856344,"width":0.011968086,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Continuous Code Quality","depth":8,"bounds":{"left":0.103557184,"top":0.058260176,"width":0.04936835,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Favorite Projects","depth":11,"bounds":{"left":0.16489361,"top":0.061452515,"width":0.041888297,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Favorite Projects","depth":12,"bounds":{"left":0.1668883,"top":0.06743815,"width":0.037898935,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Assigned Issues","depth":11,"bounds":{"left":0.20944148,"top":0.061452515,"width":0.040724736,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Assigned Issues","depth":12,"bounds":{"left":0.21143617,"top":0.06743815,"width":0.03673537,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Explore","depth":11,"bounds":{"left":0.2528258,"top":0.061452515,"width":0.020944148,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Explore","depth":12,"bounds":{"left":0.25482047,"top":0.06743815,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search","depth":8,"bounds":{"left":0.9281915,"top":0.061452515,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Product news","depth":8,"bounds":{"left":0.94148934,"top":0.061452515,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":10,"bounds":{"left":0.9481383,"top":0.06384677,"width":0.0019946808,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Help","depth":8,"bounds":{"left":0.95478725,"top":0.061452515,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New...","depth":8,"bounds":{"left":0.9680851,"top":0.061452515,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Account","depth":8,"bounds":{"left":0.98138297,"top":0.061452515,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app","depth":12,"bounds":{"left":0.095578454,"top":0.111332804,"width":0.008477394,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Project","depth":11,"bounds":{"left":0.095578454,"top":0.1264964,"width":0.013297873,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Overview","depth":10,"bounds":{"left":0.08228058,"top":0.15881884,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Overview","depth":12,"bounds":{"left":0.09291888,"top":0.16480447,"width":0.020777926,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Analysis","depth":13,"bounds":{"left":0.08494016,"top":0.19752593,"width":0.015791224,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Summary","depth":13,"bounds":{"left":0.08228058,"top":0.21947326,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summary","depth":15,"bounds":{"left":0.09291888,"top":0.2254589,"width":0.020944148,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Issues","depth":13,"bounds":{"left":0.08228058,"top":0.2482043,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Issues","depth":15,"bounds":{"left":0.09291888,"top":0.25418994,"width":0.01462766,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Architecture","depth":13,"bounds":{"left":0.08228058,"top":0.27693537,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Architecture","depth":15,"bounds":{"left":0.09291888,"top":0.282921,"width":0.026928192,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security hotspots","depth":13,"bounds":{"left":0.08228058,"top":0.3056664,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security hotspots","depth":15,"bounds":{"left":0.09291888,"top":0.31165203,"width":0.03856383,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Reporting","depth":13,"bounds":{"left":0.08494016,"top":0.3443735,"width":0.018284574,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Measures","depth":13,"bounds":{"left":0.08228058,"top":0.36632082,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Measures","depth":15,"bounds":{"left":0.09291888,"top":0.37230647,"width":0.021609042,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Activity","depth":13,"bounds":{"left":0.08228058,"top":0.39505187,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Activity","depth":15,"bounds":{"left":0.09291888,"top":0.4010375,"width":0.016456118,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Policies","depth":13,"bounds":{"left":0.08494016,"top":0.43375897,"width":0.014461436,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Intended architecture","depth":13,"bounds":{"left":0.08228058,"top":0.4557063,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Intended architecture","depth":15,"bounds":{"left":0.09291888,"top":0.46169195,"width":0.047041222,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Project","depth":13,"bounds":{"left":0.08494016,"top":0.4944134,"width":0.013297873,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull Requests 111","depth":13,"bounds":{"left":0.08228058,"top":0.51636076,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull Requests","depth":15,"bounds":{"left":0.09291888,"top":0.5223464,"width":0.029587766,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"111","depth":15,"bounds":{"left":0.14777261,"top":0.5231444,"width":0.004986702,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Branches 15","depth":13,"bounds":{"left":0.08228058,"top":0.5450918,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Branches","depth":15,"bounds":{"left":0.09291888,"top":0.5510774,"width":0.020777926,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"15","depth":15,"bounds":{"left":0.14860372,"top":0.5518755,"width":0.004155585,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":13,"bounds":{"left":0.08228058,"top":0.5738228,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":15,"bounds":{"left":0.09291888,"top":0.5798085,"width":0.011801862,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Project Information","depth":13,"bounds":{"left":0.08228058,"top":0.60255384,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Project Information","depth":15,"bounds":{"left":0.09291888,"top":0.6085395,"width":0.041888297,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Jiminny","depth":9,"bounds":{"left":0.16771941,"top":0.11691939,"width":0.01462766,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":10,"bounds":{"left":0.16771941,"top":0.11691939,"width":0.01462766,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":9,"bounds":{"left":0.19165559,"top":0.11691939,"width":0.0071476065,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":10,"bounds":{"left":0.19165559,"top":0.11691939,"width":0.0071476065,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Issues","depth":8,"bounds":{"left":0.2081117,"top":0.11652035,"width":0.011968086,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Issues","depth":9,"bounds":{"left":0.2081117,"top":0.11691939,"width":0.011968086,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Merge this if statement with the enclosing one.","depth":10,"bounds":{"left":0.2293883,"top":0.11691939,"width":0.08826463,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Issues","depth":8,"bounds":{"left":0.16771941,"top":0.14205906,"width":0.023936171,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Issues","depth":9,"bounds":{"left":0.16771941,"top":0.14485236,"width":0.023936171,"height":0.023543496},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12098 – JY-20676 delete AJ reports related objects","depth":8,"bounds":{"left":0.19963431,"top":0.14365523,"width":0.13297872,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12098 – JY-20676 delete AJ reports related objects","depth":11,"bounds":{"left":0.21110372,"top":0.14964086,"width":0.115192816,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1 /","depth":10,"bounds":{"left":0.1690492,"top":0.21268955,"width":0.006150266,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":10,"bounds":{"left":0.17519946,"top":0.21268955,"width":0.0018284575,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"issues","depth":9,"bounds":{"left":0.1783577,"top":0.21268955,"width":0.013962766,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Reload","depth":8,"bounds":{"left":0.24185506,"top":0.20670392,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app/.../API/V2/AskJiminnyReportsController.php","depth":10,"bounds":{"left":0.17170878,"top":0.25897846,"width":0.10555186,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Merge this if statement with the enclosing one.","depth":8,"bounds":{"left":0.16638963,"top":0.27773345,"width":0.08610372,"height":0.06384677},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Merge this if statement with the enclosing one.","depth":10,"bounds":{"left":0.17170878,"top":0.29169992,"width":0.06948138,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1 of 1 shown","depth":10,"bounds":{"left":0.19614361,"top":0.34277734,"width":0.026595745,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Intentionality | Not clear","depth":10,"bounds":{"left":0.44498006,"top":0.21069433,"width":0.049035903,"height":0.015961692},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Intentionality","depth":12,"bounds":{"left":0.44630983,"top":0.21268955,"width":0.025099734,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"|","depth":12,"bounds":{"left":0.47273937,"top":0.21268955,"width":0.002493351,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Not clear","depth":12,"bounds":{"left":0.47523272,"top":0.21268955,"width":0.017453458,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Merge this if statement with the enclosing one. Permanent Link","depth":9,"bounds":{"left":0.44498006,"top":0.23942538,"width":0.12732713,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Merge this if statement with the enclosing one.","depth":10,"bounds":{"left":0.44498006,"top":0.24301676,"width":0.115359046,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Permanent Link","depth":10,"bounds":{"left":0.5616689,"top":0.23942538,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Mergeable \"if\" statements should be combined","depth":10,"bounds":{"left":0.44498006,"top":0.2753392,"width":0.103557184,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"php:S1066","depth":10,"bounds":{"left":0.54986703,"top":0.2753392,"width":0.024102394,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"php:S1066","depth":11,"bounds":{"left":0.54986703,"top":0.2753392,"width":0.024102394,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Software qualities impacted:","depth":11,"bounds":{"left":0.44498006,"top":0.3104549,"width":0.062333778,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Maintainability","depth":13,"bounds":{"left":0.5106383,"top":0.31165203,"width":0.027759308,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Medium severity impact on Maintainability. Click for more information.","depth":12,"bounds":{"left":0.5403923,"top":0.30806065,"width":0.027426861,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Medium","depth":14,"bounds":{"left":0.5503657,"top":0.31165203,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open in IDE","depth":10,"bounds":{"left":0.7137633,"top":0.30327216,"width":0.03474069,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Open in IDE","depth":13,"bounds":{"left":0.7180851,"top":0.3104549,"width":0.026097074,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Open","depth":12,"bounds":{"left":0.44498006,"top":0.35873902,"width":0.023769947,"height":0.015961692},"on_screen":true,"value":"Open","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Open","depth":13,"bounds":{"left":0.45162898,"top":0.35953712,"width":0.011801862,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Lukas Kovalik Lukas Kovalik","depth":12,"bounds":{"left":0.47273937,"top":0.35993615,"width":0.04454787,"height":0.013567438},"on_screen":true,"value":"Lukas Kovalik Lukas Kovalik","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Lukas Kovalik","depth":15,"bounds":{"left":0.48071808,"top":0.35953712,"width":0.029920213,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Code Smell","depth":12,"bounds":{"left":0.5319149,"top":0.3603352,"width":0.025099734,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Major","depth":12,"bounds":{"left":0.56765294,"top":0.3603352,"width":0.012466756,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Tags","depth":10,"bounds":{"left":0.7647939,"top":0.24022347,"width":0.010804521,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"clumsy +","depth":10,"bounds":{"left":0.7647939,"top":0.25538707,"width":0.025265958,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"clumsy","depth":12,"bounds":{"left":0.76612365,"top":0.25778133,"width":0.015625,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"+","depth":12,"bounds":{"left":0.78573805,"top":0.25778133,"width":0.0029920214,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Line affected","depth":10,"bounds":{"left":0.7647939,"top":0.28890663,"width":0.02925532,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"L141","depth":10,"bounds":{"left":0.7647939,"top":0.3048683,"width":0.008976064,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Effort","depth":10,"bounds":{"left":0.7647939,"top":0.33439744,"width":0.012466756,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5","depth":9,"bounds":{"left":0.7647939,"top":0.35035914,"width":0.0026595744,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"min","depth":9,"bounds":{"left":0.7687833,"top":0.35035914,"width":0.007978723,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Introduced","depth":10,"bounds":{"left":0.7647939,"top":0.37988827,"width":0.02443484,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"28 minutes ago","depth":10,"bounds":{"left":0.7647939,"top":0.39584997,"width":0.033909574,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Where is the issue?","depth":11,"bounds":{"left":0.4453125,"top":0.4309657,"width":0.0546875,"height":0.027134877},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Where is the issue?","depth":12,"bounds":{"left":0.45063165,"top":0.43735036,"width":0.043716755,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Why is this an issue?","depth":11,"bounds":{"left":0.5,"top":0.4309657,"width":0.056848403,"height":0.027134877},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Why is this an issue?","depth":12,"bounds":{"left":0.5053192,"top":0.43735036,"width":0.045877658,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Activity","depth":11,"bounds":{"left":0.5568484,"top":0.4309657,"width":0.027094414,"height":0.027134877},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Activity","depth":12,"bounds":{"left":0.5621675,"top":0.43735036,"width":0.016456118,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app/Http/Controllers/API/V2/","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AskJiminnyReportsController.php","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy the file path to the clipboard","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"See all issues in this file","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"See all issues in this file","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 1","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":14,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"<?php","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 2","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":14,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 3","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":14,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"declare","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(strict_types=","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":");","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 4","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":14,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 5","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":14,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"namespace","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny\\Http\\Controllers\\API\\V2;","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 6","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":14,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 7","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":14,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Illuminate\\Http\\JsonResponse;","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 8","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":14,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Illuminate\\Http\\Request;","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 9","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":14,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Illuminate\\Routing\\Controller;","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 10","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":14,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny\\Exceptions\\InvalidArgumentException;","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 11","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":14,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny\\Exceptions\\ModelNotFoundException;","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 12","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":14,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny\\Models\\AutomatedReport;","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 13","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":14,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny\\Models\\User;","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-1990837530771359369
|
8166198287282529068
|
idle
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
New Tab
New Tab
Jiminny
Jiminny
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
Issues - app in Jiminny SonarQube Cloud
Issues - app in Jiminny SonarQube Cloud
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to main content
Skip to main content
Skip to issues list
Skip to issues list
Undock sidebar
Continuous Code Quality
Favorite Projects
Favorite Projects
Assigned Issues
Assigned Issues
Explore
Explore
Search
Product news
1
Help
New...
Account
app
Project
Overview
Overview
Analysis
Summary
Summary
Issues
Issues
Architecture
Architecture
Security hotspots
Security hotspots
Reporting
Measures
Measures
Activity
Activity
Policies
Intended architecture
Intended architecture
Project
Pull Requests 111
Pull Requests
111
Branches 15
Branches
15
Code
Code
Project Information
Project Information
Jiminny
Jiminny
app
app
Issues
Issues
Merge this if statement with the enclosing one.
Issues
Issues
12098 – JY-20676 delete AJ reports related objects
12098 – JY-20676 delete AJ reports related objects
1 /
1
issues
Reload
app/.../API/V2/AskJiminnyReportsController.php
Merge this if statement with the enclosing one.
Merge this if statement with the enclosing one.
1 of 1 shown
Intentionality | Not clear
Intentionality
|
Not clear
Merge this if statement with the enclosing one. Permanent Link
Merge this if statement with the enclosing one.
Permanent Link
Mergeable "if" statements should be combined
php:S1066
php:S1066
Software qualities impacted:
Maintainability
Medium severity impact on Maintainability. Click for more information.
Medium
Open in IDE
Open in IDE
Open
Open
Lukas Kovalik Lukas Kovalik
Lukas Kovalik
Code Smell
Major
Tags
clumsy +
clumsy
+
Line affected
L141
Effort
5
min
Introduced
28 minutes ago
Where is the issue?
Where is the issue?
Why is this an issue?
Why is this an issue?
Activity
Activity
app/Http/Controllers/API/V2/
AskJiminnyReportsController.php
Copy the file path to the clipboard
See all issues in this file
See all issues in this file
Line: 1
Author: [EMAIL], Click to see SCM information
<?php
Line: 2
Author: [EMAIL], Click to see SCM information
Line: 3
Author: [EMAIL], Click to see SCM information
declare
(strict_types=
1
);
Line: 4
Author: [EMAIL], Click to see SCM information
Line: 5
Author: [EMAIL], Click to see SCM information
namespace
Jiminny\Http\Controllers\API\V2;
Line: 6
Author: [EMAIL], Click to see SCM information
Line: 7
Author: [EMAIL], Click to see SCM information
use
Illuminate\Http\JsonResponse;
Line: 8
Author: [EMAIL], Click to see SCM information
use
Illuminate\Http\Request;
Line: 9
Author: [EMAIL], Click to see SCM information
use
Illuminate\Routing\Controller;
Line: 10
Author: [EMAIL], Click to see SCM information
use
Jiminny\Exceptions\InvalidArgumentException;
Line: 11
Author: [EMAIL], Click to see SCM information
use
Jiminny\Exceptions\ModelNotFoundException;
Line: 12
Author: [EMAIL], Click to see SCM information
use
Jiminny\Models\AutomatedReport;
Line: 13
Author: [EMAIL], Click to see SCM information
use
Jiminny\Models\User;...
|
57199
|
NULL
|
NULL
|
NULL
|
|
57200
|
NULL
|
0
|
2026-05-19T09:22:32.703051+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779182552703_m1.jpg...
|
Firefox
|
Issues - app in Jiminny SonarQube Cloud — Work
|
1
|
sonarcloud.io/project/issues?sinceLeakPeriod=true& sonarcloud.io/project/issues?sinceLeakPeriod=true&issueStatuses=OPEN%2CCONFIRMED&types=CODE_SMELL&pullRequest=12098&id=jiminny_app&open=AZ4_gKRmOMt1tbwo_jHV...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
New Tab
New Tab
Jiminny
Jiminny
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
Issues - app in Jiminny SonarQube Cloud
Issues - app in Jiminny SonarQube Cloud
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to main content
Skip to main content
Skip to issues list
Skip to issues list
Undock sidebar
Continuous Code Quality
Favorite Projects
Favorite Projects
Assigned Issues
Assigned Issues
Explore
Explore
Search
Product news
1
Help
New...
Account
app
Project
Overview
Overview
Analysis
Summary
Summary
Issues
Issues
Architecture
Architecture
Security hotspots
Security hotspots
Reporting
Measures
Measures
Activity
Activity
Policies
Intended architecture
Intended architecture
Project
Pull Requests 111
Pull Requests
111
Branches 15
Branches
15
Code
Code
Project Information
Project Information
Jiminny
Jiminny
app
app
Issues
Issues
Merge this if statement with the enclosing one.
Issues
Issues
12098 – JY-20676 delete AJ reports related objects
12098 – JY-20676 delete AJ reports related objects
1 /
1
issues
Reload
app/.../API/V2/AskJiminnyReportsController.php
Merge this if statement with the enclosing one.
Merge this if statement with the enclosing one.
1 of 1 shown
Intentionality | Not clear
Intentionality
|
Not clear
Merge this if statement with the enclosing one. Permanent Link
Merge this if statement with the enclosing one.
Permanent Link
Mergeable "if" statements should be combined
php:S1066
php:S1066
Software qualities impacted:
Maintainability
Medium severity impact on Maintainability. Click for more information.
Medium
Open in IDE
Open in IDE
Open
Open
Lukas Kovalik Lukas Kovalik
Lukas Kovalik
Code Smell
Major
Tags
clumsy +
clumsy
+
Line affected
L141
Effort
5
min
Introduced
28 minutes ago
Where is the issue?
Where is the issue?
Why is this an issue?
Why is this an issue?
Activity
Activity
app/Http/Controllers/API/V2/
AskJiminnyReportsController.php
Copy the file path to the clipboard
See all issues in this file
See all issues in this file
Line: 1
Author: [EMAIL], Click to see SCM information
<?php
Line: 2
Author: [EMAIL], Click to see SCM information
Line: 3
Author: [EMAIL], Click to see SCM information
declare
(strict_types=
1
);
Line: 4
Author: [EMAIL], Click to see SCM information
Line: 5
Author: [EMAIL], Click to see SCM information
namespace
Jiminny\Http\Controllers\API\V2;
Line: 6
Author: [EMAIL], Click to see SCM information
Line: 7
Author: [EMAIL], Click to see SCM information
use
Illuminate\Http\JsonResponse;
Line: 8
Author: [EMAIL], Click to see SCM information
use
Illuminate\Http\Request;
Line: 9
Author: [EMAIL], Click to see SCM information
use
Illuminate\Routing\Controller;
Line: 10
Author: [EMAIL], Click to see SCM information
use
Jiminny\Exceptions\InvalidArgumentException;
Line: 11
Author: [EMAIL], Click to see SCM information
use
Jiminny\Exceptions\ModelNotFoundException;
Line: 12
Author: [EMAIL], Click to see SCM information
use
Jiminny\Models\AutomatedReport;
Line: 13
Author: [EMAIL], Click to see SCM information
use
Jiminny\Models\User;
Line: 14
Author: [EMAIL], Click to see SCM information
use
Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
Line: 15
Author: [EMAIL], Click to see SCM information
use...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Issues - app in Jiminny SonarQube Cloud","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Issues - app in Jiminny SonarQube Cloud","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to main content","depth":7,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to main content","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Skip to issues list","depth":7,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to issues list","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Undock sidebar","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Continuous Code Quality","depth":8,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Favorite Projects","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Favorite Projects","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Assigned Issues","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Assigned Issues","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Explore","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Explore","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Product news","depth":8,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Help","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New...","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Account","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Project","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Overview","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Overview","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Analysis","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Summary","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summary","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Issues","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Issues","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Architecture","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Architecture","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security hotspots","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security hotspots","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Reporting","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Measures","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Measures","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Activity","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Activity","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Policies","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Intended architecture","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Intended architecture","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Project","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull Requests 111","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull Requests","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"111","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Branches 15","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Branches","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"15","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Project Information","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Project Information","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Jiminny","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Issues","depth":8,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Issues","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Merge this if statement with the enclosing one.","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Issues","depth":8,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Issues","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12098 – JY-20676 delete AJ reports related objects","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12098 – JY-20676 delete AJ reports related objects","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1 /","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"issues","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Reload","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app/.../API/V2/AskJiminnyReportsController.php","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Merge this if statement with the enclosing one.","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Merge this if statement with the enclosing one.","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1 of 1 shown","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Intentionality | Not clear","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Intentionality","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"|","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Not clear","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Merge this if statement with the enclosing one. Permanent Link","depth":9,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Merge this if statement with the enclosing one.","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Permanent Link","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Mergeable \"if\" statements should be combined","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"php:S1066","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"php:S1066","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Software qualities impacted:","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Maintainability","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Medium severity impact on Maintainability. Click for more information.","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Medium","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open in IDE","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Open in IDE","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Open","depth":12,"on_screen":true,"value":"Open","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Open","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Lukas Kovalik Lukas Kovalik","depth":12,"on_screen":true,"value":"Lukas Kovalik Lukas Kovalik","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Lukas Kovalik","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Code Smell","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Major","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Tags","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"clumsy +","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"clumsy","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"+","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Line affected","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"L141","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Effort","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"min","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Introduced","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"28 minutes ago","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Where is the issue?","depth":11,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Where is the issue?","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Why is this an issue?","depth":11,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Why is this an issue?","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Activity","depth":11,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Activity","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app/Http/Controllers/API/V2/","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AskJiminnyReportsController.php","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy the file path to the clipboard","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"See all issues in this file","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"See all issues in this file","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 1","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":14,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"<?php","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 2","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":14,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 3","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":14,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"declare","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(strict_types=","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":");","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 4","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":14,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 5","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":14,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"namespace","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny\\Http\\Controllers\\API\\V2;","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 6","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":14,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 7","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":14,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Illuminate\\Http\\JsonResponse;","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 8","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":14,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Illuminate\\Http\\Request;","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 9","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":14,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Illuminate\\Routing\\Controller;","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 10","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":14,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny\\Exceptions\\InvalidArgumentException;","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 11","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":14,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny\\Exceptions\\ModelNotFoundException;","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 12","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":14,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny\\Models\\AutomatedReport;","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 13","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":14,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny\\Models\\User;","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 14","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":14,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 15","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":14,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
6248146403791394841
|
8166198287282529068
|
idle
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
New Tab
New Tab
Jiminny
Jiminny
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
Issues - app in Jiminny SonarQube Cloud
Issues - app in Jiminny SonarQube Cloud
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to main content
Skip to main content
Skip to issues list
Skip to issues list
Undock sidebar
Continuous Code Quality
Favorite Projects
Favorite Projects
Assigned Issues
Assigned Issues
Explore
Explore
Search
Product news
1
Help
New...
Account
app
Project
Overview
Overview
Analysis
Summary
Summary
Issues
Issues
Architecture
Architecture
Security hotspots
Security hotspots
Reporting
Measures
Measures
Activity
Activity
Policies
Intended architecture
Intended architecture
Project
Pull Requests 111
Pull Requests
111
Branches 15
Branches
15
Code
Code
Project Information
Project Information
Jiminny
Jiminny
app
app
Issues
Issues
Merge this if statement with the enclosing one.
Issues
Issues
12098 – JY-20676 delete AJ reports related objects
12098 – JY-20676 delete AJ reports related objects
1 /
1
issues
Reload
app/.../API/V2/AskJiminnyReportsController.php
Merge this if statement with the enclosing one.
Merge this if statement with the enclosing one.
1 of 1 shown
Intentionality | Not clear
Intentionality
|
Not clear
Merge this if statement with the enclosing one. Permanent Link
Merge this if statement with the enclosing one.
Permanent Link
Mergeable "if" statements should be combined
php:S1066
php:S1066
Software qualities impacted:
Maintainability
Medium severity impact on Maintainability. Click for more information.
Medium
Open in IDE
Open in IDE
Open
Open
Lukas Kovalik Lukas Kovalik
Lukas Kovalik
Code Smell
Major
Tags
clumsy +
clumsy
+
Line affected
L141
Effort
5
min
Introduced
28 minutes ago
Where is the issue?
Where is the issue?
Why is this an issue?
Why is this an issue?
Activity
Activity
app/Http/Controllers/API/V2/
AskJiminnyReportsController.php
Copy the file path to the clipboard
See all issues in this file
See all issues in this file
Line: 1
Author: [EMAIL], Click to see SCM information
<?php
Line: 2
Author: [EMAIL], Click to see SCM information
Line: 3
Author: [EMAIL], Click to see SCM information
declare
(strict_types=
1
);
Line: 4
Author: [EMAIL], Click to see SCM information
Line: 5
Author: [EMAIL], Click to see SCM information
namespace
Jiminny\Http\Controllers\API\V2;
Line: 6
Author: [EMAIL], Click to see SCM information
Line: 7
Author: [EMAIL], Click to see SCM information
use
Illuminate\Http\JsonResponse;
Line: 8
Author: [EMAIL], Click to see SCM information
use
Illuminate\Http\Request;
Line: 9
Author: [EMAIL], Click to see SCM information
use
Illuminate\Routing\Controller;
Line: 10
Author: [EMAIL], Click to see SCM information
use
Jiminny\Exceptions\InvalidArgumentException;
Line: 11
Author: [EMAIL], Click to see SCM information
use
Jiminny\Exceptions\ModelNotFoundException;
Line: 12
Author: [EMAIL], Click to see SCM information
use
Jiminny\Models\AutomatedReport;
Line: 13
Author: [EMAIL], Click to see SCM information
use
Jiminny\Models\User;
Line: 14
Author: [EMAIL], Click to see SCM information
use
Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
Line: 15
Author: [EMAIL], Click to see SCM information
use...
|
57198
|
NULL
|
NULL
|
NULL
|
|
57187
|
NULL
|
0
|
2026-05-19T09:19:02.385725+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779182342385_m2.jpg...
|
Firefox
|
Issues - app in Jiminny SonarQube Cloud — Work
|
1
|
sonarcloud.io/project/issues?sinceLeakPeriod=true& sonarcloud.io/project/issues?sinceLeakPeriod=true&issueStatuses=OPEN%2CCONFIRMED&types=CODE_SMELL&pullRequest=12098&id=jiminny_app&open=AZ4_gKRmOMt1tbwo_jHV...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
New Tab
New Tab
Jiminny
Jiminny
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
Issues - app in Jiminny SonarQube Cloud
Issues - app in Jiminny SonarQube Cloud
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to main content
Skip to main content
Skip to issues list
Skip to issues list
Undock sidebar
Continuous Code Quality
Favorite Projects
Favorite Projects
Assigned Issues
Assigned Issues
Explore
Explore
Search
Product news
1
Help
New...
Account
app
Project
Overview
Overview
Analysis
Summary
Summary
Issues
Issues
Architecture
Architecture
Security hotspots
Security hotspots
Reporting
Measures
Measures
Activity
Activity
Policies
Intended architecture
Intended architecture
Project
Pull Requests 109
Pull Requests
109
Branches 15
Branches
15
Code
Code
Project Information
Project Information
Jiminny
Jiminny
app
app
Issues
Issues
Merge this if statement with the enclosing one.
Issues
Issues
12098 – JY-20676 delete AJ reports related objects
12098 – JY-20676 delete AJ reports related objects
1 /
1
issues
Reload
app/.../API/V2/AskJiminnyReportsController.php
Merge this if statement with the enclosing one.
Merge this if statement with the enclosing one.
1 of 1 shown
Intentionality | Not clear
Intentionality
|
Not clear
Merge this if statement with the enclosing one. Permanent Link
Merge this if statement with the enclosing one.
Permanent Link
Mergeable "if" statements should be combined
php:S1066
php:S1066
Software qualities impacted:
Maintainability
Medium severity impact on Maintainability. Click for more information.
Medium
Open in IDE
Open in IDE
Open
Open
Lukas Kovalik Lukas Kovalik
Lukas Kovalik
Code Smell
Major
Tags
clumsy +
clumsy
+
Line affected
L141
Effort
5
min
Introduced
19 minutes ago
Where is the issue?
Where is the issue?
Why is this an issue?
Why is this an issue?
Activity
Activity
app/Http/Controllers/API/V2/
AskJiminnyReportsController.php
Copy the file path to the clipboard
See all issues in this file
See all issues in this file
Line: 1
Author: [EMAIL], Click to see SCM information
<?php
Line: 2
Author: [EMAIL], Click to see SCM information
Line: 3
Author: [EMAIL], Click to see SCM information
declare
(strict_types=
1
);
Line: 4
Author: [EMAIL], Click to see SCM information
Line: 5
Author: [EMAIL], Click to see SCM information
namespace
Jiminny\Http\Controllers\API\V2;
Line: 6
Author: [EMAIL], Click to see SCM information
Line: 7
Author: [EMAIL], Click to see SCM information
use
Illuminate\Http\JsonResponse;
Line: 8
Author: [EMAIL], Click to see SCM information
use
Illuminate\Http\Request;...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0,"top":0.0518755,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.06304868,"width":0.10106383,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"bounds":{"left":0.0,"top":0.08459697,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.09577015,"width":0.10721409,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.11731844,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.12849163,"width":0.18816489,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.15003991,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.16121309,"width":0.15674867,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.18276137,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.19393456,"width":0.039228722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.0,"top":0.21548285,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"bounds":{"left":0.013297873,"top":0.22665602,"width":0.014960106,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.2482043,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.013297873,"top":0.25937748,"width":0.013131649,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":4,"bounds":{"left":0.0,"top":0.28092578,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":5,"bounds":{"left":0.013297873,"top":0.29209897,"width":0.4644282,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Issues - app in Jiminny SonarQube Cloud","depth":4,"bounds":{"left":0.0,"top":0.31364724,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Issues - app in Jiminny SonarQube Cloud","depth":5,"bounds":{"left":0.013297873,"top":0.32482043,"width":0.071476065,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.06732048,"top":0.32083002,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.0028257978,"top":0.34796488,"width":0.07413564,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0028257978,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.013796543,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.024933511,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.036070477,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.04720745,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to main content","depth":7,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to main content","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Skip to issues list","depth":7,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to issues list","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Undock sidebar","depth":8,"bounds":{"left":0.08361037,"top":0.059856344,"width":0.011968086,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Continuous Code Quality","depth":8,"bounds":{"left":0.103557184,"top":0.058260176,"width":0.04936835,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Favorite Projects","depth":11,"bounds":{"left":0.16489361,"top":0.061452515,"width":0.041888297,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Favorite Projects","depth":12,"bounds":{"left":0.1668883,"top":0.06743815,"width":0.037898935,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Assigned Issues","depth":11,"bounds":{"left":0.20944148,"top":0.061452515,"width":0.040724736,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Assigned Issues","depth":12,"bounds":{"left":0.21143617,"top":0.06743815,"width":0.03673537,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Explore","depth":11,"bounds":{"left":0.2528258,"top":0.061452515,"width":0.020944148,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Explore","depth":12,"bounds":{"left":0.25482047,"top":0.06743815,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search","depth":8,"bounds":{"left":0.9281915,"top":0.061452515,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Product news","depth":8,"bounds":{"left":0.94148934,"top":0.061452515,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":10,"bounds":{"left":0.9481383,"top":0.06384677,"width":0.0019946808,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Help","depth":8,"bounds":{"left":0.95478725,"top":0.061452515,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New...","depth":8,"bounds":{"left":0.9680851,"top":0.061452515,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Account","depth":8,"bounds":{"left":0.98138297,"top":0.061452515,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app","depth":12,"bounds":{"left":0.095578454,"top":0.111332804,"width":0.008477394,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Project","depth":11,"bounds":{"left":0.095578454,"top":0.1264964,"width":0.013297873,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Overview","depth":10,"bounds":{"left":0.08228058,"top":0.15881884,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Overview","depth":12,"bounds":{"left":0.09291888,"top":0.16480447,"width":0.020777926,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Analysis","depth":13,"bounds":{"left":0.08494016,"top":0.19752593,"width":0.015791224,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Summary","depth":13,"bounds":{"left":0.08228058,"top":0.21947326,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summary","depth":15,"bounds":{"left":0.09291888,"top":0.2254589,"width":0.020944148,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Issues","depth":13,"bounds":{"left":0.08228058,"top":0.2482043,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Issues","depth":15,"bounds":{"left":0.09291888,"top":0.25418994,"width":0.01462766,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Architecture","depth":13,"bounds":{"left":0.08228058,"top":0.27693537,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Architecture","depth":15,"bounds":{"left":0.09291888,"top":0.282921,"width":0.026928192,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security hotspots","depth":13,"bounds":{"left":0.08228058,"top":0.3056664,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security hotspots","depth":15,"bounds":{"left":0.09291888,"top":0.31165203,"width":0.03856383,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Reporting","depth":13,"bounds":{"left":0.08494016,"top":0.3443735,"width":0.018284574,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Measures","depth":13,"bounds":{"left":0.08228058,"top":0.36632082,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Measures","depth":15,"bounds":{"left":0.09291888,"top":0.37230647,"width":0.021609042,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Activity","depth":13,"bounds":{"left":0.08228058,"top":0.39505187,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Activity","depth":15,"bounds":{"left":0.09291888,"top":0.4010375,"width":0.016456118,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Policies","depth":13,"bounds":{"left":0.08494016,"top":0.43375897,"width":0.014461436,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Intended architecture","depth":13,"bounds":{"left":0.08228058,"top":0.4557063,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Intended architecture","depth":15,"bounds":{"left":0.09291888,"top":0.46169195,"width":0.047041222,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Project","depth":13,"bounds":{"left":0.08494016,"top":0.4944134,"width":0.013297873,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull Requests 109","depth":13,"bounds":{"left":0.08228058,"top":0.51636076,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull Requests","depth":15,"bounds":{"left":0.09291888,"top":0.5223464,"width":0.029587766,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"109","depth":15,"bounds":{"left":0.14594415,"top":0.5231444,"width":0.0068151597,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Branches 15","depth":13,"bounds":{"left":0.08228058,"top":0.5450918,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Branches","depth":15,"bounds":{"left":0.09291888,"top":0.5510774,"width":0.020777926,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"15","depth":15,"bounds":{"left":0.14860372,"top":0.5518755,"width":0.004155585,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":13,"bounds":{"left":0.08228058,"top":0.5738228,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":15,"bounds":{"left":0.09291888,"top":0.5798085,"width":0.011801862,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Project Information","depth":13,"bounds":{"left":0.08228058,"top":0.60255384,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Project Information","depth":15,"bounds":{"left":0.09291888,"top":0.6085395,"width":0.041888297,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Jiminny","depth":9,"bounds":{"left":0.16771941,"top":0.11691939,"width":0.01462766,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":10,"bounds":{"left":0.16771941,"top":0.11691939,"width":0.01462766,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":9,"bounds":{"left":0.19165559,"top":0.11691939,"width":0.0071476065,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":10,"bounds":{"left":0.19165559,"top":0.11691939,"width":0.0071476065,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Issues","depth":8,"bounds":{"left":0.2081117,"top":0.11652035,"width":0.011968086,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Issues","depth":9,"bounds":{"left":0.2081117,"top":0.11691939,"width":0.011968086,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Merge this if statement with the enclosing one.","depth":10,"bounds":{"left":0.2293883,"top":0.11691939,"width":0.08826463,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Issues","depth":8,"bounds":{"left":0.16771941,"top":0.14205906,"width":0.023936171,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Issues","depth":9,"bounds":{"left":0.16771941,"top":0.14485236,"width":0.023936171,"height":0.023543496},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12098 – JY-20676 delete AJ reports related objects","depth":8,"bounds":{"left":0.19963431,"top":0.14365523,"width":0.13297872,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12098 – JY-20676 delete AJ reports related objects","depth":11,"bounds":{"left":0.21110372,"top":0.14964086,"width":0.115192816,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1 /","depth":10,"bounds":{"left":0.1690492,"top":0.21268955,"width":0.006150266,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":10,"bounds":{"left":0.17519946,"top":0.21268955,"width":0.0018284575,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"issues","depth":9,"bounds":{"left":0.1783577,"top":0.21268955,"width":0.013962766,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Reload","depth":8,"bounds":{"left":0.24185506,"top":0.20670392,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app/.../API/V2/AskJiminnyReportsController.php","depth":10,"bounds":{"left":0.17170878,"top":0.25897846,"width":0.10555186,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Merge this if statement with the enclosing one.","depth":8,"bounds":{"left":0.16638963,"top":0.27773345,"width":0.08610372,"height":0.06384677},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Merge this if statement with the enclosing one.","depth":10,"bounds":{"left":0.17170878,"top":0.29169992,"width":0.06948138,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1 of 1 shown","depth":10,"bounds":{"left":0.19614361,"top":0.34277734,"width":0.026595745,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Intentionality | Not clear","depth":10,"bounds":{"left":0.44498006,"top":0.21069433,"width":0.049035903,"height":0.015961692},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Intentionality","depth":12,"bounds":{"left":0.44630983,"top":0.21268955,"width":0.025099734,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"|","depth":12,"bounds":{"left":0.47273937,"top":0.21268955,"width":0.002493351,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Not clear","depth":12,"bounds":{"left":0.47523272,"top":0.21268955,"width":0.017453458,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Merge this if statement with the enclosing one. Permanent Link","depth":9,"bounds":{"left":0.44498006,"top":0.23942538,"width":0.12732713,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Merge this if statement with the enclosing one.","depth":10,"bounds":{"left":0.44498006,"top":0.24301676,"width":0.115359046,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Permanent Link","depth":10,"bounds":{"left":0.5616689,"top":0.23942538,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Mergeable \"if\" statements should be combined","depth":10,"bounds":{"left":0.44498006,"top":0.2753392,"width":0.103557184,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"php:S1066","depth":10,"bounds":{"left":0.54986703,"top":0.2753392,"width":0.024102394,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"php:S1066","depth":11,"bounds":{"left":0.54986703,"top":0.2753392,"width":0.024102394,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Software qualities impacted:","depth":11,"bounds":{"left":0.44498006,"top":0.3104549,"width":0.062333778,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Maintainability","depth":13,"bounds":{"left":0.5106383,"top":0.31165203,"width":0.027759308,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Medium severity impact on Maintainability. Click for more information.","depth":12,"bounds":{"left":0.5403923,"top":0.30806065,"width":0.027426861,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Medium","depth":14,"bounds":{"left":0.5503657,"top":0.31165203,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open in IDE","depth":10,"bounds":{"left":0.7137633,"top":0.30327216,"width":0.03474069,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Open in IDE","depth":13,"bounds":{"left":0.7180851,"top":0.3104549,"width":0.026097074,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Open","depth":12,"bounds":{"left":0.44498006,"top":0.35873902,"width":0.023769947,"height":0.015961692},"on_screen":true,"value":"Open","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Open","depth":13,"bounds":{"left":0.45162898,"top":0.35953712,"width":0.011801862,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Lukas Kovalik Lukas Kovalik","depth":12,"bounds":{"left":0.47273937,"top":0.35993615,"width":0.04454787,"height":0.013567438},"on_screen":true,"value":"Lukas Kovalik Lukas Kovalik","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Lukas Kovalik","depth":15,"bounds":{"left":0.48071808,"top":0.35953712,"width":0.029920213,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Code Smell","depth":12,"bounds":{"left":0.5319149,"top":0.3603352,"width":0.025099734,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Major","depth":12,"bounds":{"left":0.56765294,"top":0.3603352,"width":0.012466756,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Tags","depth":10,"bounds":{"left":0.7647939,"top":0.24022347,"width":0.010804521,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"clumsy +","depth":10,"bounds":{"left":0.7647939,"top":0.25538707,"width":0.025265958,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"clumsy","depth":12,"bounds":{"left":0.76612365,"top":0.25778133,"width":0.015625,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"+","depth":12,"bounds":{"left":0.78573805,"top":0.25778133,"width":0.0029920214,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Line affected","depth":10,"bounds":{"left":0.7647939,"top":0.28890663,"width":0.02925532,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"L141","depth":10,"bounds":{"left":0.7647939,"top":0.3048683,"width":0.008976064,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Effort","depth":10,"bounds":{"left":0.7647939,"top":0.33439744,"width":0.012466756,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5","depth":9,"bounds":{"left":0.7647939,"top":0.35035914,"width":0.0026595744,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"min","depth":9,"bounds":{"left":0.7687833,"top":0.35035914,"width":0.007978723,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Introduced","depth":10,"bounds":{"left":0.7647939,"top":0.37988827,"width":0.02443484,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"19 minutes ago","depth":10,"bounds":{"left":0.7647939,"top":0.39584997,"width":0.032912236,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Where is the issue?","depth":11,"bounds":{"left":0.4453125,"top":0.4309657,"width":0.0546875,"height":0.027134877},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Where is the issue?","depth":12,"bounds":{"left":0.45063165,"top":0.43735036,"width":0.043716755,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Why is this an issue?","depth":11,"bounds":{"left":0.5,"top":0.4309657,"width":0.056848403,"height":0.027134877},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Why is this an issue?","depth":12,"bounds":{"left":0.5053192,"top":0.43735036,"width":0.045877658,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Activity","depth":11,"bounds":{"left":0.5568484,"top":0.4309657,"width":0.027094414,"height":0.027134877},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Activity","depth":12,"bounds":{"left":0.5621675,"top":0.43735036,"width":0.016456118,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app/Http/Controllers/API/V2/","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AskJiminnyReportsController.php","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy the file path to the clipboard","depth":11,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"See all issues in this file","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"See all issues in this file","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 1","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"<?php","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 2","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 3","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"declare","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(strict_types=","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":");","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 4","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 5","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"namespace","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny\\Http\\Controllers\\API\\V2;","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 6","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 7","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Illuminate\\Http\\JsonResponse;","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 8","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Illuminate\\Http\\Request;","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
4510474911769475262
|
8166154298227489676
|
idle
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
New Tab
New Tab
Jiminny
Jiminny
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
Issues - app in Jiminny SonarQube Cloud
Issues - app in Jiminny SonarQube Cloud
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to main content
Skip to main content
Skip to issues list
Skip to issues list
Undock sidebar
Continuous Code Quality
Favorite Projects
Favorite Projects
Assigned Issues
Assigned Issues
Explore
Explore
Search
Product news
1
Help
New...
Account
app
Project
Overview
Overview
Analysis
Summary
Summary
Issues
Issues
Architecture
Architecture
Security hotspots
Security hotspots
Reporting
Measures
Measures
Activity
Activity
Policies
Intended architecture
Intended architecture
Project
Pull Requests 109
Pull Requests
109
Branches 15
Branches
15
Code
Code
Project Information
Project Information
Jiminny
Jiminny
app
app
Issues
Issues
Merge this if statement with the enclosing one.
Issues
Issues
12098 – JY-20676 delete AJ reports related objects
12098 – JY-20676 delete AJ reports related objects
1 /
1
issues
Reload
app/.../API/V2/AskJiminnyReportsController.php
Merge this if statement with the enclosing one.
Merge this if statement with the enclosing one.
1 of 1 shown
Intentionality | Not clear
Intentionality
|
Not clear
Merge this if statement with the enclosing one. Permanent Link
Merge this if statement with the enclosing one.
Permanent Link
Mergeable "if" statements should be combined
php:S1066
php:S1066
Software qualities impacted:
Maintainability
Medium severity impact on Maintainability. Click for more information.
Medium
Open in IDE
Open in IDE
Open
Open
Lukas Kovalik Lukas Kovalik
Lukas Kovalik
Code Smell
Major
Tags
clumsy +
clumsy
+
Line affected
L141
Effort
5
min
Introduced
19 minutes ago
Where is the issue?
Where is the issue?
Why is this an issue?
Why is this an issue?
Activity
Activity
app/Http/Controllers/API/V2/
AskJiminnyReportsController.php
Copy the file path to the clipboard
See all issues in this file
See all issues in this file
Line: 1
Author: [EMAIL], Click to see SCM information
<?php
Line: 2
Author: [EMAIL], Click to see SCM information
Line: 3
Author: [EMAIL], Click to see SCM information
declare
(strict_types=
1
);
Line: 4
Author: [EMAIL], Click to see SCM information
Line: 5
Author: [EMAIL], Click to see SCM information
namespace
Jiminny\Http\Controllers\API\V2;
Line: 6
Author: [EMAIL], Click to see SCM information
Line: 7
Author: [EMAIL], Click to see SCM information
use
Illuminate\Http\JsonResponse;
Line: 8
Author: [EMAIL], Click to see SCM information
use
Illuminate\Http\Request;...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
57186
|
NULL
|
0
|
2026-05-19T09:19:01.115996+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779182341115_m1.jpg...
|
Firefox
|
Issues - app in Jiminny SonarQube Cloud — Work
|
1
|
sonarcloud.io/project/issues?sinceLeakPeriod=true& sonarcloud.io/project/issues?sinceLeakPeriod=true&issueStatuses=OPEN%2CCONFIRMED&types=CODE_SMELL&pullRequest=12098&id=jiminny_app&open=AZ4_gKRmOMt1tbwo_jHV...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
New Tab
New Tab
Jiminny
Jiminny
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
Issues - app in Jiminny SonarQube Cloud
Issues - app in Jiminny SonarQube Cloud
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to main content
Skip to main content
Skip to issues list
Skip to issues list
Undock sidebar
Continuous Code Quality
Favorite Projects
Favorite Projects
Assigned Issues
Assigned Issues
Explore
Explore
Search
Product news
1
Help
New...
Account
app
Project
Overview
Overview
Analysis
Summary
Summary
Issues
Issues
Architecture
Architecture
Security hotspots
Security hotspots
Reporting
Measures
Measures
Activity
Activity
Policies
Intended architecture
Intended architecture
Project
Pull Requests 109
Pull Requests
109
Branches 15
Branches
15
Code
Code
Project Information
Project Information
Jiminny
Jiminny
app
app
Issues
Issues
Merge this if statement with the enclosing one.
Issues
Issues
12098 – JY-20676 delete AJ reports related objects
12098 – JY-20676 delete AJ reports related objects
1 /
1
issues
Reload
app/.../API/V2/AskJiminnyReportsController.php
Merge this if statement with the enclosing one.
Merge this if statement with the enclosing one.
1 of 1 shown
Intentionality | Not clear
Intentionality
|
Not clear
Merge this if statement with the enclosing one. Permanent Link
Merge this if statement with the enclosing one.
Permanent Link
Mergeable "if" statements should be combined
php:S1066
php:S1066
Software qualities impacted:
Maintainability
Medium severity impact on Maintainability. Click for more information.
Medium
Open in IDE
Open in IDE
Open
Open
Lukas Kovalik Lukas Kovalik
Lukas Kovalik
Code Smell
Major
Tags
clumsy +
clumsy
+
Line affected
L141
Effort
5
min
Introduced
19 minutes ago
Where is the issue?
Where is the issue?
Why is this an issue?
Why is this an issue?
Activity
Activity
app/Http/Controllers/API/V2/
AskJiminnyReportsController.php
Copy the file path to the clipboard
See all issues in this file
See all issues in this file...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Issues - app in Jiminny SonarQube Cloud","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Issues - app in Jiminny SonarQube Cloud","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to main content","depth":7,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to main content","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Skip to issues list","depth":7,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to issues list","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Undock sidebar","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Continuous Code Quality","depth":8,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Favorite Projects","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Favorite Projects","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Assigned Issues","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Assigned Issues","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Explore","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Explore","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Product news","depth":8,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Help","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New...","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Account","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Project","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Overview","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Overview","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Analysis","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Summary","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summary","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Issues","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Issues","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Architecture","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Architecture","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security hotspots","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security hotspots","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Reporting","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Measures","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Measures","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Activity","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Activity","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Policies","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Intended architecture","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Intended architecture","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Project","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull Requests 109","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull Requests","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"109","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Branches 15","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Branches","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"15","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Project Information","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Project Information","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Jiminny","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Issues","depth":8,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Issues","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Merge this if statement with the enclosing one.","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Issues","depth":8,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Issues","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12098 – JY-20676 delete AJ reports related objects","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12098 – JY-20676 delete AJ reports related objects","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1 /","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"issues","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Reload","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app/.../API/V2/AskJiminnyReportsController.php","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Merge this if statement with the enclosing one.","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Merge this if statement with the enclosing one.","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1 of 1 shown","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Intentionality | Not clear","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Intentionality","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"|","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Not clear","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Merge this if statement with the enclosing one. Permanent Link","depth":9,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Merge this if statement with the enclosing one.","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Permanent Link","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Mergeable \"if\" statements should be combined","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"php:S1066","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"php:S1066","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Software qualities impacted:","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Maintainability","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Medium severity impact on Maintainability. Click for more information.","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Medium","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open in IDE","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Open in IDE","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Open","depth":12,"on_screen":true,"value":"Open","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Open","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Lukas Kovalik Lukas Kovalik","depth":12,"on_screen":true,"value":"Lukas Kovalik Lukas Kovalik","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Lukas Kovalik","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Code Smell","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Major","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Tags","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"clumsy +","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"clumsy","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"+","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Line affected","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"L141","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Effort","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"min","depth":9,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Introduced","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"19 minutes ago","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Where is the issue?","depth":11,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Where is the issue?","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Why is this an issue?","depth":11,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Why is this an issue?","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Activity","depth":11,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Activity","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app/Http/Controllers/API/V2/","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AskJiminnyReportsController.php","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy the file path to the clipboard","depth":11,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"See all issues in this file","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"See all issues in this file","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
4934749108964173839
|
8342357667119430533
|
idle
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
New Tab
New Tab
Jiminny
Jiminny
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
Issues - app in Jiminny SonarQube Cloud
Issues - app in Jiminny SonarQube Cloud
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to main content
Skip to main content
Skip to issues list
Skip to issues list
Undock sidebar
Continuous Code Quality
Favorite Projects
Favorite Projects
Assigned Issues
Assigned Issues
Explore
Explore
Search
Product news
1
Help
New...
Account
app
Project
Overview
Overview
Analysis
Summary
Summary
Issues
Issues
Architecture
Architecture
Security hotspots
Security hotspots
Reporting
Measures
Measures
Activity
Activity
Policies
Intended architecture
Intended architecture
Project
Pull Requests 109
Pull Requests
109
Branches 15
Branches
15
Code
Code
Project Information
Project Information
Jiminny
Jiminny
app
app
Issues
Issues
Merge this if statement with the enclosing one.
Issues
Issues
12098 – JY-20676 delete AJ reports related objects
12098 – JY-20676 delete AJ reports related objects
1 /
1
issues
Reload
app/.../API/V2/AskJiminnyReportsController.php
Merge this if statement with the enclosing one.
Merge this if statement with the enclosing one.
1 of 1 shown
Intentionality | Not clear
Intentionality
|
Not clear
Merge this if statement with the enclosing one. Permanent Link
Merge this if statement with the enclosing one.
Permanent Link
Mergeable "if" statements should be combined
php:S1066
php:S1066
Software qualities impacted:
Maintainability
Medium severity impact on Maintainability. Click for more information.
Medium
Open in IDE
Open in IDE
Open
Open
Lukas Kovalik Lukas Kovalik
Lukas Kovalik
Code Smell
Major
Tags
clumsy +
clumsy
+
Line affected
L141
Effort
5
min
Introduced
19 minutes ago
Where is the issue?
Where is the issue?
Why is this an issue?
Why is this an issue?
Activity
Activity
app/Http/Controllers/API/V2/
AskJiminnyReportsController.php
Copy the file path to the clipboard
See all issues in this file
See all issues in this file...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
57167
|
NULL
|
0
|
2026-05-19T09:13:59.472631+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779182039472_m2.jpg...
|
Firefox
|
Issues - app in Jiminny SonarQube Cloud — Work
|
1
|
sonarcloud.io/project/issues?sinceLeakPeriod=true& sonarcloud.io/project/issues?sinceLeakPeriod=true&issueStatuses=OPEN%2CCONFIRMED&types=CODE_SMELL&pullRequest=12098&id=jiminny_app&open=AZ4_gKRmOMt1tbwo_jHV...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
New Tab
New Tab
Jiminny
Jiminny
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
Issues - app in Jiminny SonarQube Cloud
Issues - app in Jiminny SonarQube Cloud
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to main content
Skip to main content
Skip to issues list
Skip to issues list
Undock sidebar
Continuous Code Quality
Favorite Projects
Favorite Projects
Assigned Issues
Assigned Issues
Explore
Explore
Search
Product news
1
Help
New...
Account
app
Project
Overview
Overview
Analysis
Summary
Summary
Issues
Issues
Architecture
Architecture
Security hotspots
Security hotspots
Reporting
Measures
Measures
Activity
Activity
Policies
Intended architecture
Intended architecture
Project
Pull Requests 109
Pull Requests
109
Branches 15
Branches
15
Code
Code
Project Information
Project Information
Jiminny
Jiminny
app
app
Issues
Issues
Merge this if statement with the enclosing one.
Issues
Issues
12098 – JY-20676 delete AJ reports related objects
12098 – JY-20676 delete AJ reports related objects
1 /
1
issues
Reload
app/.../API/V2/AskJiminnyReportsController.php
Merge this if statement with the enclosing one.
Merge this if statement with the enclosing one.
1 of 1 shown
Intentionality | Not clear
Intentionality
|
Not clear
Merge this if statement with the enclosing one. Permanent Link
Merge this if statement with the enclosing one.
Permanent Link
Mergeable "if" statements should be combined
php:S1066
php:S1066
Software qualities impacted:
Maintainability
Medium severity impact on Maintainability. Click for more information.
Medium
Open in IDE
Open in IDE
Open
Open
Lukas Kovalik Lukas Kovalik
Lukas Kovalik
Code Smell
Major
Tags
clumsy +
clumsy
+
Line affected
L141
Effort
5
min
Introduced
19 minutes ago
Where is the issue?
Where is the issue?
Why is this an issue?
Why is this an issue?
Activity
Activity
app/Http/Controllers/API/V2/
AskJiminnyReportsController.php
Copy the file path to the clipboard
See all issues in this file
See all issues in this file
Line: 1
Author: [EMAIL], Click to see SCM information
<?php
Line: 2
Author: [EMAIL], Click to see SCM information
Line: 3
Author: [EMAIL], Click to see SCM information
declare
(strict_types=
1
);
Line: 4
Author: [EMAIL], Click to see SCM information
Line: 5
Author: [EMAIL], Click to see SCM information
namespace
Jiminny\Http\Controllers\API\V2;
Line: 6
Author: [EMAIL], Click to see SCM information
Line: 7
Author: [EMAIL], Click to see SCM information
use
Illuminate\Http\JsonResponse;
Line: 8
Author: [EMAIL], Click to see SCM information
use
Illuminate\Http\Request;
Line: 9
Author: [EMAIL], Click to see SCM information
use
Illuminate\Routing\Controller;
Line: 10
Author: [EMAIL], Click to see SCM information
use
Jiminny\Exceptions\InvalidArgumentException;
Line: 11
Author: [EMAIL], Click to see SCM information
use
Jiminny\Exceptions\ModelNotFoundException;
Line: 12
Author: [EMAIL], Click to see SCM information
use
Jiminny\Models\AutomatedReport;
Line: 13
Author: [EMAIL], Click to see SCM information
use
Jiminny\Models\User;
Line: 14
Author: [EMAIL], Click to see SCM information
use
Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
Line: 15
Author: [EMAIL], Click to see SCM information
use
Psr\Log\LoggerInterface;
Line: 16
Author: [EMAIL], Click to see SCM information
use...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0,"top":0.0518755,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.06304868,"width":0.10106383,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"bounds":{"left":0.0,"top":0.08459697,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.09577015,"width":0.10721409,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.11731844,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.12849163,"width":0.18816489,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.15003991,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.16121309,"width":0.15674867,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.18276137,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.19393456,"width":0.039228722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.0,"top":0.21548285,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"bounds":{"left":0.013297873,"top":0.22665602,"width":0.014960106,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.2482043,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.013297873,"top":0.25937748,"width":0.013131649,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":4,"bounds":{"left":0.0,"top":0.28092578,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":5,"bounds":{"left":0.013297873,"top":0.29209897,"width":0.4644282,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Issues - app in Jiminny SonarQube Cloud","depth":4,"bounds":{"left":0.0,"top":0.31364724,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Issues - app in Jiminny SonarQube Cloud","depth":5,"bounds":{"left":0.013297873,"top":0.32482043,"width":0.071476065,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.06732048,"top":0.32083002,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.0028257978,"top":0.34796488,"width":0.07413564,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0028257978,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.013796543,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.024933511,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.036070477,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.04720745,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to main content","depth":7,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to main content","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Skip to issues list","depth":7,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to issues list","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Undock sidebar","depth":8,"bounds":{"left":0.08361037,"top":0.059856344,"width":0.011968086,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Continuous Code Quality","depth":8,"bounds":{"left":0.103557184,"top":0.058260176,"width":0.04936835,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Favorite Projects","depth":11,"bounds":{"left":0.16489361,"top":0.061452515,"width":0.041888297,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Favorite Projects","depth":12,"bounds":{"left":0.1668883,"top":0.06743815,"width":0.037898935,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Assigned Issues","depth":11,"bounds":{"left":0.20944148,"top":0.061452515,"width":0.040724736,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Assigned Issues","depth":12,"bounds":{"left":0.21143617,"top":0.06743815,"width":0.03673537,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Explore","depth":11,"bounds":{"left":0.2528258,"top":0.061452515,"width":0.020944148,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Explore","depth":12,"bounds":{"left":0.25482047,"top":0.06743815,"width":0.016954787,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search","depth":8,"bounds":{"left":0.9281915,"top":0.061452515,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Product news","depth":8,"bounds":{"left":0.94148934,"top":0.061452515,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":10,"bounds":{"left":0.9481383,"top":0.06384677,"width":0.0019946808,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Help","depth":8,"bounds":{"left":0.95478725,"top":0.061452515,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New...","depth":8,"bounds":{"left":0.9680851,"top":0.061452515,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Account","depth":8,"bounds":{"left":0.98138297,"top":0.061452515,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app","depth":12,"bounds":{"left":0.095578454,"top":0.111332804,"width":0.008477394,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Project","depth":11,"bounds":{"left":0.095578454,"top":0.1264964,"width":0.013297873,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Overview","depth":10,"bounds":{"left":0.08228058,"top":0.15881884,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Overview","depth":12,"bounds":{"left":0.09291888,"top":0.16480447,"width":0.020777926,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Analysis","depth":13,"bounds":{"left":0.08494016,"top":0.19752593,"width":0.015791224,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Summary","depth":13,"bounds":{"left":0.08228058,"top":0.21947326,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summary","depth":15,"bounds":{"left":0.09291888,"top":0.2254589,"width":0.020944148,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Issues","depth":13,"bounds":{"left":0.08228058,"top":0.2482043,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Issues","depth":15,"bounds":{"left":0.09291888,"top":0.25418994,"width":0.01462766,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Architecture","depth":13,"bounds":{"left":0.08228058,"top":0.27693537,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Architecture","depth":15,"bounds":{"left":0.09291888,"top":0.282921,"width":0.026928192,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security hotspots","depth":13,"bounds":{"left":0.08228058,"top":0.3056664,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security hotspots","depth":15,"bounds":{"left":0.09291888,"top":0.31165203,"width":0.03856383,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Reporting","depth":13,"bounds":{"left":0.08494016,"top":0.3443735,"width":0.018284574,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Measures","depth":13,"bounds":{"left":0.08228058,"top":0.36632082,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Measures","depth":15,"bounds":{"left":0.09291888,"top":0.37230647,"width":0.021609042,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Activity","depth":13,"bounds":{"left":0.08228058,"top":0.39505187,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Activity","depth":15,"bounds":{"left":0.09291888,"top":0.4010375,"width":0.016456118,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Policies","depth":13,"bounds":{"left":0.08494016,"top":0.43375897,"width":0.014461436,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Intended architecture","depth":13,"bounds":{"left":0.08228058,"top":0.4557063,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Intended architecture","depth":15,"bounds":{"left":0.09291888,"top":0.46169195,"width":0.047041222,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Project","depth":13,"bounds":{"left":0.08494016,"top":0.4944134,"width":0.013297873,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull Requests 109","depth":13,"bounds":{"left":0.08228058,"top":0.51636076,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull Requests","depth":15,"bounds":{"left":0.09291888,"top":0.5223464,"width":0.029587766,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"109","depth":15,"bounds":{"left":0.14594415,"top":0.5231444,"width":0.0068151597,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Branches 15","depth":13,"bounds":{"left":0.08228058,"top":0.5450918,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Branches","depth":15,"bounds":{"left":0.09291888,"top":0.5510774,"width":0.020777926,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"15","depth":15,"bounds":{"left":0.14860372,"top":0.5518755,"width":0.004155585,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":13,"bounds":{"left":0.08228058,"top":0.5738228,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":15,"bounds":{"left":0.09291888,"top":0.5798085,"width":0.011801862,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Project Information","depth":13,"bounds":{"left":0.08228058,"top":0.60255384,"width":0.07446808,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Project Information","depth":15,"bounds":{"left":0.09291888,"top":0.6085395,"width":0.041888297,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Jiminny","depth":9,"bounds":{"left":0.16771941,"top":0.11691939,"width":0.01462766,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":10,"bounds":{"left":0.16771941,"top":0.11691939,"width":0.01462766,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":9,"bounds":{"left":0.19165559,"top":0.11691939,"width":0.0071476065,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":10,"bounds":{"left":0.19165559,"top":0.11691939,"width":0.0071476065,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Issues","depth":8,"bounds":{"left":0.2081117,"top":0.11652035,"width":0.011968086,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Issues","depth":9,"bounds":{"left":0.2081117,"top":0.11691939,"width":0.011968086,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Merge this if statement with the enclosing one.","depth":10,"bounds":{"left":0.2293883,"top":0.11691939,"width":0.08826463,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Issues","depth":8,"bounds":{"left":0.16771941,"top":0.14205906,"width":0.023936171,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Issues","depth":9,"bounds":{"left":0.16771941,"top":0.14485236,"width":0.023936171,"height":0.023543496},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12098 – JY-20676 delete AJ reports related objects","depth":8,"bounds":{"left":0.19963431,"top":0.14365523,"width":0.13297872,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12098 – JY-20676 delete AJ reports related objects","depth":11,"bounds":{"left":0.21110372,"top":0.14964086,"width":0.115192816,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1 /","depth":10,"bounds":{"left":0.1690492,"top":0.21268955,"width":0.006150266,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":10,"bounds":{"left":0.17519946,"top":0.21268955,"width":0.0018284575,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"issues","depth":9,"bounds":{"left":0.1783577,"top":0.21268955,"width":0.013962766,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Reload","depth":8,"bounds":{"left":0.24185506,"top":0.20670392,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app/.../API/V2/AskJiminnyReportsController.php","depth":10,"bounds":{"left":0.17170878,"top":0.25897846,"width":0.10555186,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Merge this if statement with the enclosing one.","depth":8,"bounds":{"left":0.16638963,"top":0.27773345,"width":0.08610372,"height":0.06384677},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Merge this if statement with the enclosing one.","depth":10,"bounds":{"left":0.17170878,"top":0.29169992,"width":0.06948138,"height":0.029928172},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1 of 1 shown","depth":10,"bounds":{"left":0.19614361,"top":0.34277734,"width":0.026595745,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Intentionality | Not clear","depth":10,"bounds":{"left":0.44498006,"top":0.21069433,"width":0.049035903,"height":0.015961692},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Intentionality","depth":12,"bounds":{"left":0.44630983,"top":0.21268955,"width":0.025099734,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"|","depth":12,"bounds":{"left":0.47273937,"top":0.21268955,"width":0.002493351,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Not clear","depth":12,"bounds":{"left":0.47523272,"top":0.21268955,"width":0.017453458,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Merge this if statement with the enclosing one. Permanent Link","depth":9,"bounds":{"left":0.44498006,"top":0.23942538,"width":0.12732713,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Merge this if statement with the enclosing one.","depth":10,"bounds":{"left":0.44498006,"top":0.24301676,"width":0.115359046,"height":0.01556265},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Permanent Link","depth":10,"bounds":{"left":0.5616689,"top":0.23942538,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Mergeable \"if\" statements should be combined","depth":10,"bounds":{"left":0.44498006,"top":0.2753392,"width":0.103557184,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"php:S1066","depth":10,"bounds":{"left":0.54986703,"top":0.2753392,"width":0.024102394,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"php:S1066","depth":11,"bounds":{"left":0.54986703,"top":0.2753392,"width":0.024102394,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Software qualities impacted:","depth":11,"bounds":{"left":0.44498006,"top":0.3104549,"width":0.062333778,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Maintainability","depth":13,"bounds":{"left":0.5106383,"top":0.31165203,"width":0.027759308,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Medium severity impact on Maintainability. Click for more information.","depth":12,"bounds":{"left":0.5403923,"top":0.30806065,"width":0.027426861,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Medium","depth":14,"bounds":{"left":0.5503657,"top":0.31165203,"width":0.015458777,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open in IDE","depth":10,"bounds":{"left":0.7137633,"top":0.30327216,"width":0.03474069,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Open in IDE","depth":13,"bounds":{"left":0.7180851,"top":0.3104549,"width":0.026097074,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Open","depth":12,"bounds":{"left":0.44498006,"top":0.35873902,"width":0.023769947,"height":0.015961692},"on_screen":true,"value":"Open","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Open","depth":13,"bounds":{"left":0.45162898,"top":0.35953712,"width":0.011801862,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Lukas Kovalik Lukas Kovalik","depth":12,"bounds":{"left":0.47273937,"top":0.35993615,"width":0.04454787,"height":0.013567438},"on_screen":true,"value":"Lukas Kovalik Lukas Kovalik","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Lukas Kovalik","depth":15,"bounds":{"left":0.48071808,"top":0.35953712,"width":0.029920213,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Code Smell","depth":12,"bounds":{"left":0.5319149,"top":0.3603352,"width":0.025099734,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Major","depth":12,"bounds":{"left":0.56765294,"top":0.3603352,"width":0.012466756,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Tags","depth":10,"bounds":{"left":0.7647939,"top":0.24022347,"width":0.010804521,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"clumsy +","depth":10,"bounds":{"left":0.7647939,"top":0.25538707,"width":0.025265958,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"clumsy","depth":12,"bounds":{"left":0.76612365,"top":0.25778133,"width":0.015625,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"+","depth":12,"bounds":{"left":0.78573805,"top":0.25778133,"width":0.0029920214,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Line affected","depth":10,"bounds":{"left":0.7647939,"top":0.28890663,"width":0.02925532,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"L141","depth":10,"bounds":{"left":0.7647939,"top":0.3048683,"width":0.008976064,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Effort","depth":10,"bounds":{"left":0.7647939,"top":0.33439744,"width":0.012466756,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5","depth":9,"bounds":{"left":0.7647939,"top":0.35035914,"width":0.0026595744,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"min","depth":9,"bounds":{"left":0.7687833,"top":0.35035914,"width":0.007978723,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Introduced","depth":10,"bounds":{"left":0.7647939,"top":0.37988827,"width":0.02443484,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"19 minutes ago","depth":10,"bounds":{"left":0.7647939,"top":0.39584997,"width":0.032912236,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Where is the issue?","depth":11,"bounds":{"left":0.4453125,"top":0.4309657,"width":0.0546875,"height":0.027134877},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Where is the issue?","depth":12,"bounds":{"left":0.45063165,"top":0.43735036,"width":0.043716755,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Why is this an issue?","depth":11,"bounds":{"left":0.5,"top":0.4309657,"width":0.056848403,"height":0.027134877},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Why is this an issue?","depth":12,"bounds":{"left":0.5053192,"top":0.43735036,"width":0.045877658,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Activity","depth":11,"bounds":{"left":0.5568484,"top":0.4309657,"width":0.027094414,"height":0.027134877},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Activity","depth":12,"bounds":{"left":0.5621675,"top":0.43735036,"width":0.016456118,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app/Http/Controllers/API/V2/","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AskJiminnyReportsController.php","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy the file path to the clipboard","depth":11,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"See all issues in this file","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"See all issues in this file","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 1","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"<?php","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 2","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 3","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"declare","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(strict_types=","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":");","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 4","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 5","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"namespace","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny\\Http\\Controllers\\API\\V2;","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 6","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 7","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Illuminate\\Http\\JsonResponse;","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 8","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Illuminate\\Http\\Request;","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 9","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Illuminate\\Routing\\Controller;","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 10","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny\\Exceptions\\InvalidArgumentException;","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 11","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny\\Exceptions\\ModelNotFoundException;","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 12","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny\\Models\\AutomatedReport;","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 13","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny\\Models\\User;","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 14","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 15","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Psr\\Log\\LoggerInterface;","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 16","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-6518889188584818576
|
8166198287282529064
|
idle
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
New Tab
New Tab
Jiminny
Jiminny
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
Issues - app in Jiminny SonarQube Cloud
Issues - app in Jiminny SonarQube Cloud
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to main content
Skip to main content
Skip to issues list
Skip to issues list
Undock sidebar
Continuous Code Quality
Favorite Projects
Favorite Projects
Assigned Issues
Assigned Issues
Explore
Explore
Search
Product news
1
Help
New...
Account
app
Project
Overview
Overview
Analysis
Summary
Summary
Issues
Issues
Architecture
Architecture
Security hotspots
Security hotspots
Reporting
Measures
Measures
Activity
Activity
Policies
Intended architecture
Intended architecture
Project
Pull Requests 109
Pull Requests
109
Branches 15
Branches
15
Code
Code
Project Information
Project Information
Jiminny
Jiminny
app
app
Issues
Issues
Merge this if statement with the enclosing one.
Issues
Issues
12098 – JY-20676 delete AJ reports related objects
12098 – JY-20676 delete AJ reports related objects
1 /
1
issues
Reload
app/.../API/V2/AskJiminnyReportsController.php
Merge this if statement with the enclosing one.
Merge this if statement with the enclosing one.
1 of 1 shown
Intentionality | Not clear
Intentionality
|
Not clear
Merge this if statement with the enclosing one. Permanent Link
Merge this if statement with the enclosing one.
Permanent Link
Mergeable "if" statements should be combined
php:S1066
php:S1066
Software qualities impacted:
Maintainability
Medium severity impact on Maintainability. Click for more information.
Medium
Open in IDE
Open in IDE
Open
Open
Lukas Kovalik Lukas Kovalik
Lukas Kovalik
Code Smell
Major
Tags
clumsy +
clumsy
+
Line affected
L141
Effort
5
min
Introduced
19 minutes ago
Where is the issue?
Where is the issue?
Why is this an issue?
Why is this an issue?
Activity
Activity
app/Http/Controllers/API/V2/
AskJiminnyReportsController.php
Copy the file path to the clipboard
See all issues in this file
See all issues in this file
Line: 1
Author: [EMAIL], Click to see SCM information
<?php
Line: 2
Author: [EMAIL], Click to see SCM information
Line: 3
Author: [EMAIL], Click to see SCM information
declare
(strict_types=
1
);
Line: 4
Author: [EMAIL], Click to see SCM information
Line: 5
Author: [EMAIL], Click to see SCM information
namespace
Jiminny\Http\Controllers\API\V2;
Line: 6
Author: [EMAIL], Click to see SCM information
Line: 7
Author: [EMAIL], Click to see SCM information
use
Illuminate\Http\JsonResponse;
Line: 8
Author: [EMAIL], Click to see SCM information
use
Illuminate\Http\Request;
Line: 9
Author: [EMAIL], Click to see SCM information
use
Illuminate\Routing\Controller;
Line: 10
Author: [EMAIL], Click to see SCM information
use
Jiminny\Exceptions\InvalidArgumentException;
Line: 11
Author: [EMAIL], Click to see SCM information
use
Jiminny\Exceptions\ModelNotFoundException;
Line: 12
Author: [EMAIL], Click to see SCM information
use
Jiminny\Models\AutomatedReport;
Line: 13
Author: [EMAIL], Click to see SCM information
use
Jiminny\Models\User;
Line: 14
Author: [EMAIL], Click to see SCM information
use
Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
Line: 15
Author: [EMAIL], Click to see SCM information
use
Psr\Log\LoggerInterface;
Line: 16
Author: [EMAIL], Click to see SCM information
use...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
57165
|
NULL
|
0
|
2026-05-19T09:13:28.934799+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779182008934_m1.jpg...
|
Firefox
|
Issues - app in Jiminny SonarQube Cloud — Work
|
1
|
sonarcloud.io/project/issues?sinceLeakPeriod=true& sonarcloud.io/project/issues?sinceLeakPeriod=true&issueStatuses=OPEN%2CCONFIRMED&types=CODE_SMELL&pullRequest=12098&id=jiminny_app&open=AZ4_gKRmOMt1tbwo_jHV...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
New Tab
New Tab
Jiminny
Jiminny
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
Issues - app in Jiminny SonarQube Cloud
Issues - app in Jiminny SonarQube Cloud
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to main content
Skip to main content
Skip to issues list
Skip to issues list
Undock sidebar
Continuous Code Quality
Favorite Projects
Favorite Projects
Assigned Issues
Assigned Issues
Explore
Explore
Search
Product news
1
Help
New...
Account
app
Project
Overview
Overview
Analysis
Summary
Summary
Issues
Issues
Architecture
Architecture
Security hotspots
Security hotspots
Reporting
Measures
Measures
Activity
Activity
Policies
Intended architecture
Intended architecture
Project
Pull Requests 109
Pull Requests
109...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Issues - app in Jiminny SonarQube Cloud","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Issues - app in Jiminny SonarQube Cloud","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to main content","depth":7,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to main content","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Skip to issues list","depth":7,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to issues list","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Undock sidebar","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Continuous Code Quality","depth":8,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Favorite Projects","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Favorite Projects","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Assigned Issues","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Assigned Issues","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Explore","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Explore","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Product news","depth":8,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Help","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New...","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Account","depth":8,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Project","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Overview","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Overview","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Analysis","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Summary","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summary","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Issues","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Issues","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Architecture","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Architecture","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security hotspots","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security hotspots","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Reporting","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Measures","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Measures","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Activity","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Activity","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Policies","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Intended architecture","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Intended architecture","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Project","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull Requests 109","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull Requests","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"109","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-2544379216858840197
|
5856389879485716868
|
idle
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
New Tab
New Tab
Jiminny
Jiminny
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
Issues - app in Jiminny SonarQube Cloud
Issues - app in Jiminny SonarQube Cloud
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to main content
Skip to main content
Skip to issues list
Skip to issues list
Undock sidebar
Continuous Code Quality
Favorite Projects
Favorite Projects
Assigned Issues
Assigned Issues
Explore
Explore
Search
Product news
1
Help
New...
Account
app
Project
Overview
Overview
Analysis
Summary
Summary
Issues
Issues
Architecture
Architecture
Security hotspots
Security hotspots
Reporting
Measures
Measures
Activity
Activity
Policies
Intended architecture
Intended architecture
Project
Pull Requests 109
Pull Requests
109...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
57147
|
NULL
|
0
|
2026-05-19T09:08:57.164365+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779181737164_m2.jpg...
|
Firefox
|
Pipelines - jiminny/app — Work
|
1
|
app.circleci.com/pipelines/github/jiminny/app
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
Close tab
New Tab
New Tab
Jiminny
Jiminny
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
JY-20676 delete AJ reports related objects by LakyLak · Pull Request #12098 · jiminny/app
JY-20676 delete AJ reports related objects by LakyLak · Pull Request #12098 · jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Go to home page
View third-party service outages
Auto theme
Open notifications
Open support menu
Open user menu
org avatar Current organization: jiminny
Home
Home
Pipelines
Pipelines
Projects
Projects
Deploys
Deploys
Insights
Insights
Runners
Runners
Org
Org
Plan
Plan
Chunk sidecars
Chunk sidecars
PREVIEW
Chunk
Chunk
Dashboard All Pipelines
All Pipelines
Project Outline app
app
app
app
Overview
Overview
Settings
Settings
Deploys
Deploys
Lightning Manage triggers
Manage triggers
Trigger Pipeline
Pipelines All pipelines my-pipelines-filter
All pipelines
app Project Filter. Selected "app"
app
All branches Branch Filter. Selected "All branches"
All branches
Start Time Cutoff date Arrow Drop Down
Cutoff date
All statuses Arrow Drop Down
All
statuses
Filter Display options
Display options
Pipeline
Status
Workflow
Checkout source
Trigger event
Start
Duration
Actions
app
58542
58542
RUNNING workflow build_accept_deploy. Collapse the workflow jobs list.
Status Running Running
Running
22m 0s
remain
Info Outline
build_accept_deploy
build_accept_deploy
JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details
JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details
Open commit on version control site
2b5e6ea
Merge branch 'master' into JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details
Push
Commit pushed
Copy timestamp to clipboard
3m ago
Copy timestamp duration to clipboard
Rerun workflow from start
Rerun workflow from failed
Cancel workflow
Fix workflow
More Actions
Jobs
SUCCESS job checkout-code
checkout-code
889231
1m 37s
1m 37s
SUCCESS job build-frontend
build-frontend
889235
1m 14s
1m 14s
RUNNING job test-frontend
test-frontend
889236
8s
8s
RUNNING job build-backend
build-backend
889232
1m 22s
1m 22s
phpstan
889233
setup
889237
test
889238
test-backend-lint
889234
sonar_cloud
889239
SUCCESS workflow setup-workflow. Collapse the workflow jobs list.
Status Passed Success
Success
setup-workflow
setup-workflow
SETUP
JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details
JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details
Open commit on version control site
2b5e6ea
Merge branch 'master' into JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details
Push
Commit pushed
Copy timestamp to clipboard
4m ago
Copy timestamp duration to clipboard
Rerun workflow from start
Rerun workflow from failed
Cancel workflow
Fix workflow
More Actions
Jobs
SUCCESS job setup
setup
889230
52s
52s
app
58541
58541
RUNNING workflow build_accept_deploy. Collapse the workflow jobs list.
Status Running Running
Running
20m 4s
remain
Info Outline
build_accept_deploy
build_accept_deploy
JY-20920-fix-participant-flip
JY-20920-fix-participant-flip
Open commit on version control site
c04bb4e
Merge branch 'master' into JY-20920-fix-participant-flip
Push
Commit pushed
Copy timestamp to clipboard
5m ago...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0,"top":0.0518755,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.06304868,"width":0.10106383,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"bounds":{"left":0.0,"top":0.08459697,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.09577015,"width":0.10721409,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.11731844,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.12849163,"width":0.18816489,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.15003991,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.16121309,"width":0.15674867,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.18276137,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.19393456,"width":0.039228722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.06732048,"top":0.18994413,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.0,"top":0.21548285,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"bounds":{"left":0.013297873,"top":0.22665602,"width":0.014960106,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.2482043,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.013297873,"top":0.25937748,"width":0.013131649,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":4,"bounds":{"left":0.0,"top":0.28092578,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":5,"bounds":{"left":0.013297873,"top":0.29209897,"width":0.4644282,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20676 delete AJ reports related objects by LakyLak · Pull Request #12098 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.31364724,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20676 delete AJ reports related objects by LakyLak · Pull Request #12098 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.32482043,"width":0.15791224,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.0028257978,"top":0.34796488,"width":0.07413564,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0028257978,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.013796543,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.024933511,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.036070477,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.04720745,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Go to home page","depth":9,"bounds":{"left":0.08726729,"top":0.061452515,"width":0.044215426,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"View third-party service outages","depth":9,"bounds":{"left":0.13813165,"top":0.07102953,"width":0.005319149,"height":0.012769354},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Auto theme","depth":9,"bounds":{"left":0.9375,"top":0.061452515,"width":0.013297873,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open notifications","depth":9,"bounds":{"left":0.95212764,"top":0.061452515,"width":0.013297873,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Open support menu","depth":9,"bounds":{"left":0.96675533,"top":0.061452515,"width":0.013297873,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Open user menu","depth":9,"bounds":{"left":0.98138297,"top":0.061452515,"width":0.013297873,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"org avatar Current organization: jiminny","depth":9,"bounds":{"left":0.08693484,"top":0.10295291,"width":0.01462766,"height":0.035115723},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Home","depth":10,"bounds":{"left":0.08494016,"top":0.15083799,"width":0.01861702,"height":0.046288908},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Home","depth":12,"bounds":{"left":0.087765954,"top":0.1839585,"width":0.012965426,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pipelines","depth":10,"bounds":{"left":0.08494016,"top":0.21308859,"width":0.01861702,"height":0.046288908},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines","depth":12,"bounds":{"left":0.083942816,"top":0.2462091,"width":0.020611702,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Projects","depth":10,"bounds":{"left":0.08494016,"top":0.2753392,"width":0.01861702,"height":0.04668795},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Projects","depth":12,"bounds":{"left":0.0852726,"top":0.3084597,"width":0.017952127,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Deploys","depth":10,"bounds":{"left":0.08494016,"top":0.33798882,"width":0.01861702,"height":0.046288908},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Deploys","depth":12,"bounds":{"left":0.08543883,"top":0.37071028,"width":0.01761968,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Insights","depth":10,"bounds":{"left":0.08494016,"top":0.40023944,"width":0.01861702,"height":0.046288908},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Insights","depth":12,"bounds":{"left":0.085605055,"top":0.4329609,"width":0.017287234,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Runners","depth":10,"bounds":{"left":0.08494016,"top":0.46249002,"width":0.01861702,"height":0.046288908},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Runners","depth":12,"bounds":{"left":0.0852726,"top":0.49561054,"width":0.017952127,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Org","depth":10,"bounds":{"left":0.08494016,"top":0.52474064,"width":0.01861702,"height":0.046288908},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Org","depth":12,"bounds":{"left":0.090259306,"top":0.55786115,"width":0.007978723,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Plan","depth":10,"bounds":{"left":0.08494016,"top":0.58699125,"width":0.01861702,"height":0.04668795},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Plan","depth":12,"bounds":{"left":0.08959442,"top":0.6201117,"width":0.00930851,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chunk sidecars","depth":11,"bounds":{"left":0.07962101,"top":0.8591381,"width":0.02925532,"height":0.059457302},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Chunk sidecars","depth":13,"bounds":{"left":0.08494016,"top":0.8922586,"width":0.01861702,"height":0.026735835},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"PREVIEW","depth":12,"bounds":{"left":0.08743351,"top":0.8567438,"width":0.013630319,"height":0.009177973},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chunk","depth":10,"bounds":{"left":0.07962101,"top":0.9345571,"width":0.02925532,"height":0.046288908},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Chunk","depth":12,"bounds":{"left":0.08726729,"top":0.96727854,"width":0.013962766,"height":0.01396648},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Dashboard All Pipelines","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"All Pipelines","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Project Outline app","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"app","depth":12,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Overview","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Overview","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Deploys","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Deploys","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Lightning Manage triggers","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Manage triggers","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Trigger Pipeline","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Pipelines All pipelines my-pipelines-filter","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"All pipelines","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"app Project Filter. Selected \"app\"","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"All branches Branch Filter. Selected \"All branches\"","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"All branches","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Start Time Cutoff date Arrow Drop Down","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Cutoff date","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"All statuses Arrow Drop Down","depth":12,"on_screen":false,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"All","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"statuses","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Filter Display options","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Display options","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pipeline","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Status","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Workflow","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Checkout source","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Trigger event","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Start","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Duration","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Actions","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"58542","depth":11,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"58542","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"RUNNING workflow build_accept_deploy. Collapse the workflow jobs list.","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Status Running Running","depth":11,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Running","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"22m 0s","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"remain","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Info Outline","depth":11,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"build_accept_deploy","depth":11,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"build_accept_deploy","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Open commit on version control site","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"2b5e6ea","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Merge branch 'master' into JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Push","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Commit pushed","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy timestamp to clipboard","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"3m ago","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy timestamp duration to clipboard","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Rerun workflow from start","depth":11,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Rerun workflow from failed","depth":11,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Cancel workflow","depth":11,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Fix workflow","depth":11,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"More Actions","depth":11,"on_screen":false,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Jobs","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"SUCCESS job checkout-code","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"checkout-code","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"889231","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1m 37s","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1m 37s","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"SUCCESS job build-frontend","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"build-frontend","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"889235","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1m 14s","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1m 14s","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"RUNNING job test-frontend","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"test-frontend","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"889236","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"8s","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"8s","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"RUNNING job build-backend","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"build-backend","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"889232","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1m 22s","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1m 22s","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"phpstan","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"889233","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"setup","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"889237","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"test","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"889238","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"test-backend-lint","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"889234","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"sonar_cloud","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"889239","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"SUCCESS workflow setup-workflow. Collapse the workflow jobs list.","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Status Passed Success","depth":11,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Success","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"setup-workflow","depth":11,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"setup-workflow","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SETUP","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Open commit on version control site","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"2b5e6ea","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Merge branch 'master' into JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Push","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Commit pushed","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy timestamp to clipboard","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"4m ago","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy timestamp duration to clipboard","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Rerun workflow from start","depth":11,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Rerun workflow from failed","depth":11,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Cancel workflow","depth":11,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Fix workflow","depth":11,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"More Actions","depth":11,"on_screen":false,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Jobs","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"SUCCESS job setup","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"setup","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"889230","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"52s","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"52s","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"58541","depth":11,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"58541","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"RUNNING workflow build_accept_deploy. Collapse the workflow jobs list.","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Status Running Running","depth":11,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Running","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"20m 4s","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"remain","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Info Outline","depth":11,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"build_accept_deploy","depth":11,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"build_accept_deploy","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"JY-20920-fix-participant-flip","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20920-fix-participant-flip","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Open commit on version control site","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"c04bb4e","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Merge branch 'master' into JY-20920-fix-participant-flip","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Push","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Commit pushed","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy timestamp to clipboard","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"5m ago","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
8808926660480622599
|
5496157915933601940
|
idle
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
Close tab
New Tab
New Tab
Jiminny
Jiminny
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
JY-20676 delete AJ reports related objects by LakyLak · Pull Request #12098 · jiminny/app
JY-20676 delete AJ reports related objects by LakyLak · Pull Request #12098 · jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Go to home page
View third-party service outages
Auto theme
Open notifications
Open support menu
Open user menu
org avatar Current organization: jiminny
Home
Home
Pipelines
Pipelines
Projects
Projects
Deploys
Deploys
Insights
Insights
Runners
Runners
Org
Org
Plan
Plan
Chunk sidecars
Chunk sidecars
PREVIEW
Chunk
Chunk
Dashboard All Pipelines
All Pipelines
Project Outline app
app
app
app
Overview
Overview
Settings
Settings
Deploys
Deploys
Lightning Manage triggers
Manage triggers
Trigger Pipeline
Pipelines All pipelines my-pipelines-filter
All pipelines
app Project Filter. Selected "app"
app
All branches Branch Filter. Selected "All branches"
All branches
Start Time Cutoff date Arrow Drop Down
Cutoff date
All statuses Arrow Drop Down
All
statuses
Filter Display options
Display options
Pipeline
Status
Workflow
Checkout source
Trigger event
Start
Duration
Actions
app
58542
58542
RUNNING workflow build_accept_deploy. Collapse the workflow jobs list.
Status Running Running
Running
22m 0s
remain
Info Outline
build_accept_deploy
build_accept_deploy
JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details
JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details
Open commit on version control site
2b5e6ea
Merge branch 'master' into JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details
Push
Commit pushed
Copy timestamp to clipboard
3m ago
Copy timestamp duration to clipboard
Rerun workflow from start
Rerun workflow from failed
Cancel workflow
Fix workflow
More Actions
Jobs
SUCCESS job checkout-code
checkout-code
889231
1m 37s
1m 37s
SUCCESS job build-frontend
build-frontend
889235
1m 14s
1m 14s
RUNNING job test-frontend
test-frontend
889236
8s
8s
RUNNING job build-backend
build-backend
889232
1m 22s
1m 22s
phpstan
889233
setup
889237
test
889238
test-backend-lint
889234
sonar_cloud
889239
SUCCESS workflow setup-workflow. Collapse the workflow jobs list.
Status Passed Success
Success
setup-workflow
setup-workflow
SETUP
JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details
JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details
Open commit on version control site
2b5e6ea
Merge branch 'master' into JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details
Push
Commit pushed
Copy timestamp to clipboard
4m ago
Copy timestamp duration to clipboard
Rerun workflow from start
Rerun workflow from failed
Cancel workflow
Fix workflow
More Actions
Jobs
SUCCESS job setup
setup
889230
52s
52s
app
58541
58541
RUNNING workflow build_accept_deploy. Collapse the workflow jobs list.
Status Running Running
Running
20m 4s
remain
Info Outline
build_accept_deploy
build_accept_deploy
JY-20920-fix-participant-flip
JY-20920-fix-participant-flip
Open commit on version control site
c04bb4e
Merge branch 'master' into JY-20920-fix-participant-flip
Push
Commit pushed
Copy timestamp to clipboard
5m ago...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
57146
|
NULL
|
0
|
2026-05-19T09:08:53.997509+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779181733997_m1.jpg...
|
Firefox
|
Pipelines - jiminny/app — Work
|
1
|
app.circleci.com/pipelines/github/jiminny/app
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
Close tab
New Tab
New Tab
Jiminny
Jiminny
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
JY-20676 delete AJ reports related objects by LakyLak · Pull Request #12098 · jiminny/app
JY-20676 delete AJ reports related objects by LakyLak · Pull Request #12098 · jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Go to home page
View third-party service outages
Auto theme
Open notifications
Open support menu
Open user menu
org avatar Current organization: jiminny
Home
Home
Pipelines
Pipelines
Projects
Projects
Deploys
Deploys
Insights
Insights
Runners
Runners
Org
Org
Plan
Plan
Chunk sidecars
Chunk sidecars
PREVIEW
Chunk
Chunk
Dashboard All Pipelines
All Pipelines
Project Outline app
app
app
app
Overview
Overview
Settings
Settings
Deploys
Deploys
Lightning Manage triggers
Manage triggers
Trigger Pipeline
Pipelines All pipelines my-pipelines-filter
All pipelines
app Project Filter. Selected "app"
app
All branches Branch Filter. Selected "All branches"
All branches
Start Time Cutoff date Arrow Drop Down
Cutoff date
All statuses Arrow Drop Down
All
statuses
Filter Display options
Display options
Pipeline
Status
Workflow
Checkout source
Trigger event
Start
Duration
Actions
app
58542
58542
RUNNING workflow build_accept_deploy. Collapse the workflow jobs list.
Status Running Running...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"New Tab","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20676 delete AJ reports related objects by LakyLak · Pull Request #12098 · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20676 delete AJ reports related objects by LakyLak · Pull Request #12098 · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Go to home page","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"View third-party service outages","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Auto theme","depth":9,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open notifications","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Open support menu","depth":9,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Open user menu","depth":9,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"org avatar Current organization: jiminny","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Home","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Home","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pipelines","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Projects","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Projects","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Deploys","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Deploys","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Insights","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Insights","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Runners","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Runners","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Org","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Org","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Plan","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Plan","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chunk sidecars","depth":11,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Chunk sidecars","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"PREVIEW","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chunk","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Chunk","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Dashboard All Pipelines","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"All Pipelines","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Project Outline app","depth":14,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"app","depth":12,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Overview","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Overview","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Deploys","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Deploys","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Lightning Manage triggers","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Manage triggers","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Trigger Pipeline","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Pipelines All pipelines my-pipelines-filter","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"All pipelines","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"app Project Filter. Selected \"app\"","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"All branches Branch Filter. Selected \"All branches\"","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"All branches","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Start Time Cutoff date Arrow Drop Down","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Cutoff date","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"All statuses Arrow Drop Down","depth":12,"on_screen":false,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"All","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"statuses","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Filter Display options","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Display options","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pipeline","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Status","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Workflow","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Checkout source","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Trigger event","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Start","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Duration","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Actions","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"58542","depth":11,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"58542","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"RUNNING workflow build_accept_deploy. Collapse the workflow jobs list.","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Status Running Running","depth":11,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
-8417495977395296162
|
5928539214327869569
|
idle
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
Close tab
New Tab
New Tab
Jiminny
Jiminny
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
JY-20676 delete AJ reports related objects by LakyLak · Pull Request #12098 · jiminny/app
JY-20676 delete AJ reports related objects by LakyLak · Pull Request #12098 · jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Go to home page
View third-party service outages
Auto theme
Open notifications
Open support menu
Open user menu
org avatar Current organization: jiminny
Home
Home
Pipelines
Pipelines
Projects
Projects
Deploys
Deploys
Insights
Insights
Runners
Runners
Org
Org
Plan
Plan
Chunk sidecars
Chunk sidecars
PREVIEW
Chunk
Chunk
Dashboard All Pipelines
All Pipelines
Project Outline app
app
app
app
Overview
Overview
Settings
Settings
Deploys
Deploys
Lightning Manage triggers
Manage triggers
Trigger Pipeline
Pipelines All pipelines my-pipelines-filter
All pipelines
app Project Filter. Selected "app"
app
All branches Branch Filter. Selected "All branches"
All branches
Start Time Cutoff date Arrow Drop Down
Cutoff date
All statuses Arrow Drop Down
All
statuses
Filter Display options
Display options
Pipeline
Status
Workflow
Checkout source
Trigger event
Start
Duration
Actions
app
58542
58542
RUNNING workflow build_accept_deploy. Collapse the workflow jobs list.
Status Running Running...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
57124
|
NULL
|
0
|
2026-05-19T09:03:40.050892+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779181420050_m2.jpg...
|
Firefox
|
SevenShores\Hubspot\Exceptions\BadRequest: Client SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT — Work...
|
1
|
jiminny.sentry.io/issues/7007366572/?environment=p jiminny.sentry.io/issues/7007366572/?environment=production-eu&environment=production&project=82419&query=is%3Aunresolved&referrer=issue-stream&sort=freq...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
New Tab
New Tab
Jiminny
Jiminny
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
Close tab
JY-20676 delete AJ reports related objects by LakyLak · Pull Request #12098 · jiminny/app
JY-20676 delete AJ reports related objects by LakyLak · Pull Request #12098 · jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to main content
Skip to main content
Toggle organization menu
Issues
Issues
Explore
Explore
Dashboards
Dashboards
Monitors
Monitors
Settings
Settings
Try Business
What's New
Help
[EMAIL]
Issues
Expand
Feed
Feed
Errors & Outages
Errors & Outages
Breached Metrics
Breached Metrics
Warnings
Warnings
User Feedback
User Feedback
Autofix
Autofix
Recently Run
Recently Run...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0,"top":0.0518755,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.06304868,"width":0.10106383,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"bounds":{"left":0.0,"top":0.08459697,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.09577015,"width":0.10721409,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.11731844,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.12849163,"width":0.18816489,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.15003991,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.16121309,"width":0.15674867,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.18276137,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.19393456,"width":0.039228722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.0,"top":0.21548285,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"bounds":{"left":0.013297873,"top":0.22665602,"width":0.014960106,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.2482043,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.013297873,"top":0.25937748,"width":0.013131649,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":4,"bounds":{"left":0.0,"top":0.28092578,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":5,"bounds":{"left":0.013297873,"top":0.29209897,"width":0.4644282,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.06732048,"top":0.28810853,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"JY-20676 delete AJ reports related objects by LakyLak · Pull Request #12098 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.31364724,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20676 delete AJ reports related objects by LakyLak · Pull Request #12098 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.32482043,"width":0.15791224,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.0028257978,"top":0.34796488,"width":0.07413564,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0028257978,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.013796543,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.024933511,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.036070477,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.04720745,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to main content","depth":8,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to main content","depth":9,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Toggle organization menu","depth":11,"bounds":{"left":0.08643617,"top":0.059856344,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Issues","depth":12,"bounds":{"left":0.0809508,"top":0.09736632,"width":0.021609042,"height":0.050678372},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Issues","depth":14,"bounds":{"left":0.0866024,"top":0.13048683,"width":0.010305851,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Explore","depth":12,"bounds":{"left":0.0809508,"top":0.14804469,"width":0.021609042,"height":0.050678372},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Explore","depth":14,"bounds":{"left":0.08577128,"top":0.1811652,"width":0.011968086,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Dashboards","depth":12,"bounds":{"left":0.0809508,"top":0.19872306,"width":0.021609042,"height":0.05027933},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Dashboards","depth":14,"bounds":{"left":0.08211436,"top":0.23184358,"width":0.019281914,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Monitors","depth":12,"bounds":{"left":0.0809508,"top":0.2490024,"width":0.021609042,"height":0.050678372},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Monitors","depth":14,"bounds":{"left":0.084773935,"top":0.2821229,"width":0.013962766,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":12,"bounds":{"left":0.0809508,"top":0.29968077,"width":0.021609042,"height":0.050678372},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":14,"bounds":{"left":0.08494016,"top":0.33280128,"width":0.013630319,"height":0.009976057},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Try Business","depth":10,"bounds":{"left":0.08643617,"top":0.88667196,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"What's New","depth":10,"bounds":{"left":0.08643617,"top":0.9114126,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Help","depth":10,"bounds":{"left":0.08643617,"top":0.93615323,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"lukas.kovalik@jiminny.com","depth":10,"bounds":{"left":0.08643617,"top":0.9680766,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Issues","depth":13,"bounds":{"left":0.04305186,"top":0.066640064,"width":0.014461436,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Expand","depth":13,"bounds":{"left":0.088597074,"top":0.061452515,"width":0.00930851,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Feed","depth":15,"bounds":{"left":0.039727394,"top":0.10055866,"width":0.058843084,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed","depth":17,"bounds":{"left":0.044049203,"top":0.10734238,"width":0.010638298,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Errors & Outages","depth":15,"bounds":{"left":0.039727394,"top":0.14046289,"width":0.058843084,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Errors & Outages","depth":17,"bounds":{"left":0.044049203,"top":0.14724661,"width":0.03673537,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Breached Metrics","depth":15,"bounds":{"left":0.039727394,"top":0.16759777,"width":0.058843084,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Breached Metrics","depth":17,"bounds":{"left":0.044049203,"top":0.17438148,"width":0.037898935,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Warnings","depth":15,"bounds":{"left":0.039727394,"top":0.19473264,"width":0.058843084,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Warnings","depth":17,"bounds":{"left":0.044049203,"top":0.20151636,"width":0.019946808,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"User Feedback","depth":15,"bounds":{"left":0.039727394,"top":0.22186752,"width":0.058843084,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Feedback","depth":17,"bounds":{"left":0.044049203,"top":0.22865124,"width":0.032081116,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Autofix","depth":13,"bounds":{"left":0.039727394,"top":0.26177174,"width":0.058843084,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Autofix","depth":16,"bounds":{"left":0.043716755,"top":0.26855546,"width":0.016289894,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Recently Run","depth":15,"bounds":{"left":0.039727394,"top":0.28731045,"width":0.058843084,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Recently Run","depth":17,"bounds":{"left":0.044049203,"top":0.29409418,"width":0.028922873,"height":0.012370312},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-5389316026793675197
|
5928499083059179717
|
idle
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
New Tab
New Tab
Jiminny
Jiminny
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
Close tab
JY-20676 delete AJ reports related objects by LakyLak · Pull Request #12098 · jiminny/app
JY-20676 delete AJ reports related objects by LakyLak · Pull Request #12098 · jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to main content
Skip to main content
Toggle organization menu
Issues
Issues
Explore
Explore
Dashboards
Dashboards
Monitors
Monitors
Settings
Settings
Try Business
What's New
Help
[EMAIL]
Issues
Expand
Feed
Feed
Errors & Outages
Errors & Outages
Breached Metrics
Breached Metrics
Warnings
Warnings
User Feedback
User Feedback
Autofix
Autofix
Recently Run
Recently Run...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
57123
|
NULL
|
0
|
2026-05-19T09:03:40.066752+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779181420066_m1.jpg...
|
Firefox
|
SevenShores\Hubspot\Exceptions\BadRequest: Client SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT — Work...
|
1
|
jiminny.sentry.io/issues/7007366572/?environment=p jiminny.sentry.io/issues/7007366572/?environment=production-eu&environment=production&project=82419&query=is%3Aunresolved&referrer=issue-stream&sort=freq...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
New Tab
New Tab
Jiminny
Jiminny
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
Close tab
JY-20676 delete AJ reports related objects by LakyLak · Pull Request #12098 · jiminny/app
JY-20676 delete AJ reports related objects by LakyLak · Pull Request #12098 · jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to main content
Skip to main content
Toggle organization menu
Issues
Issues
Explore
Explore
Dashboards
Dashboards
Monitors
Monitors
Settings
Settings
Try Business
What's New
Help
[EMAIL]
Issues
Expand
Feed
Feed
Errors & Outages
Errors & Outages
Breached Metrics
Breached Metrics
Warnings
Warnings
User Feedback
User Feedback
Autofix
Autofix
Recently Run
Recently Run...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"JY-20676 delete AJ reports related objects by LakyLak · Pull Request #12098 · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20676 delete AJ reports related objects by LakyLak · Pull Request #12098 · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to main content","depth":8,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to main content","depth":9,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Toggle organization menu","depth":11,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Issues","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Issues","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Explore","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Explore","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Dashboards","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Dashboards","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Monitors","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Monitors","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Try Business","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"What's New","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Help","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"lukas.kovalik@jiminny.com","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Issues","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Expand","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Feed","depth":15,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Errors & Outages","depth":15,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Errors & Outages","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Breached Metrics","depth":15,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Breached Metrics","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Warnings","depth":15,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Warnings","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"User Feedback","depth":15,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Feedback","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Autofix","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Autofix","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Recently Run","depth":15,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Recently Run","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-5389316026793675197
|
5928499083059179717
|
idle
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
New Tab
New Tab
Jiminny
Jiminny
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
Close tab
JY-20676 delete AJ reports related objects by LakyLak · Pull Request #12098 · jiminny/app
JY-20676 delete AJ reports related objects by LakyLak · Pull Request #12098 · jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to main content
Skip to main content
Toggle organization menu
Issues
Issues
Explore
Explore
Dashboards
Dashboards
Monitors
Monitors
Settings
Settings
Try Business
What's New
Help
[EMAIL]
Issues
Expand
Feed
Feed
Errors & Outages
Errors & Outages
Breached Metrics
Breached Metrics
Warnings
Warnings
User Feedback
User Feedback
Autofix
Autofix
Recently Run
Recently Run...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
57104
|
NULL
|
0
|
2026-05-19T08:58:50.730611+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779181130730_m1.jpg...
|
Firefox
|
Comparing master...JY-20676-delete-report-related- Comparing master...JY-20676-delete-report-related-objects · jiminny/app — Work...
|
1
|
github.com/jiminny/app/compare/JY-20676-delete-rep github.com/jiminny/app/compare/JY-20676-delete-report-related-objects?expand=1...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
New Tab
New Tab
Jiminny
Jiminny
Feed — jiminny — Sentry
Feed — jiminny — Sentry
Comparing master...JY-20676-delete-report-related-objects · jiminny/app
Comparing master...JY-20676-delete-report-related-objects · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (29)
Pull requests
(
29
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality (1)
Security and quality
(
1
)
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Comparing changes
Comparing changes
Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also
compare across forks
or
learn more about diff comparisons
learn more about diff comparisons
.
base: master
base:
master
...
compare: JY-20676-delete-report-related-objects
compare:
JY-20676-delete-report-related-objects
Able to merge.
These branches can be automatically merged.
@LakyLak
Add a title
*
JY-20676 delete AJ reports related objects
Generate pull request title with Copilot
Add a description
Add a description
Comment
Write
Write
Preview
Preview
### JIRA: JY-20676
#### Changes:
- Add field has_reports to Activity search and Ask Jiminny prompts lists
-
Markdown is supported
Markdown
is supported
Paste, drop, or click to add files
Paste, drop, or click to add files
Create pull request
Select a type of pull request
Remember, contributions to this repository should follow our
GitHub Community Guidelines
GitHub Community Guidelines
.
️
Reviewers
Suggestions
Request
Request
@nikolaybiaivanov
nikolaybiaivanov
nikolaybiaivanov
Request
Request
@ivhristova
ivhristova
ivhristova
At least 1 approving review is required to merge this pull request.
Assignees
No one—
assign yourself
Labels
None yet
Projects
None yet
Milestone
No milestone
Helpful resources
GitHub Community Guidelines
GitHub Community Guidelines
1
commit
7
files changed
1
contributor
Commits on May 19, 2026
Commits on May 19, 2026
JY-20676
JY-20676
delete AJ reports related objects
delete AJ reports related objects
@LakyLak
LakyLak
LakyLak
committed
5 minutes ago
4 / 9 checks OK
Copy the full SHA
02a3381
02a3381
Browse the repository at this point in the history
Split
Split
Unified
Unified
Showing
7 changed files
with
60 additions
and
9 deletions
.
Toggle diff contents
Expand all
8 changes: 6 additions & 2 deletions
app/Component/AskAnything/AskAnythingPromptService.php
app/Component/AskAnything/AskAnythingPromptService.php
Copy
Show options
Original file line number
Original file line
Diff line number
Diff line change
Expand Up
@@ -56,6 +56,7 @@ public function get(User $user, AskAnythingPromptTarget $target): array
56
$
ownerUuid
,
56
$
ownerUuid
,
57
$
shareUsers
,
57
$
shareUsers
,
58
$
shareGroups
,
58
$
shareGroups
,
59
+
$
prompt
->
getHasReports
(),
59
);
60
);
60
}
61
}
61
62...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Comparing master...JY-20676-delete-report-related-objects · jiminny/app","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Comparing master...JY-20676-delete-report-related-objects · jiminny/app","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to content","depth":6,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to content","depth":7,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open menu","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Homepage (g then d)","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"jiminny","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jiminny","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search or jump to…","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to search","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chat with Copilot","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Open Copilot…","depth":9,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Create new...","depth":9,"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"All issues(g then i)","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All pull requests","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All repositories","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"You have unread notifications(g then n)","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open user navigation menu","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Repository navigation","depth":9,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Repository navigation","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull requests (29)","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"29","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Agents","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Agents","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Actions","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Actions","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Wiki","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Wiki","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security and quality (1)","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security and quality","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Insights","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Insights","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Important update","depth":10,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Important update","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review this update","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review this update","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and manage your preferences in your","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub account settings","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GitHub account settings","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dismiss banner","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Comparing changes","depth":9,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Comparing changes","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"compare across forks","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"or","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"learn more about diff comparisons","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"learn more about diff comparisons","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"base: master","depth":11,"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"base:","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"master","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"...","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"compare: JY-20676-delete-report-related-objects","depth":11,"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"compare:","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"JY-20676-delete-report-related-objects","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Able to merge.","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"These branches can be automatically merged.","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@LakyLak","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Add a title","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"*","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"JY-20676 delete AJ reports related objects","depth":15,"on_screen":true,"value":"JY-20676 delete AJ reports related objects","help_text":"","placeholder":"Title","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Generate pull request title with Copilot","depth":16,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Add a description","depth":12,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Add a description","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Comment","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Write","depth":13,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Write","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Preview","depth":13,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Preview","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"### JIRA: JY-20676\n\n#### Changes:\n\n- Add field has_reports to Activity search and Ask Jiminny prompts lists\n-","depth":15,"on_screen":true,"value":"### JIRA: JY-20676\n\n#### Changes:\n\n- Add field has_reports to Activity search and Ask Jiminny prompts lists\n-","placeholder":" ","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXLink","text":"Markdown is supported","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Markdown","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"is supported","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Paste, drop, or click to add files","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Paste, drop, or click to add files","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Create pull request","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Select a type of pull request","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Remember, contributions to this repository should follow our","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub Community Guidelines","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GitHub Community Guidelines","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"️","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Reviewers","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Suggestions","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Request","depth":13,"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Request","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@nikolaybiaivanov","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"nikolaybiaivanov","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"nikolaybiaivanov","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Request","depth":13,"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Request","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@ivhristova","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"ivhristova","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ivhristova","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"At least 1 approving review is required to merge this pull request.","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Assignees","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"No one—","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"assign yourself","depth":11,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Labels","depth":11,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"None yet","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Projects","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"None yet","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Milestone","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"No milestone","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Helpful resources","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub Community Guidelines","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GitHub Community Guidelines","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"commit","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"files changed","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"contributor","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Commits on May 19, 2026","depth":10,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Commits on May 19, 2026","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"JY-20676","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20676","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"delete AJ reports related objects","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"delete AJ reports related objects","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@LakyLak","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"LakyLak","depth":13,"on_screen":true,"help_text":"View all commits by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"committed","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5 minutes ago","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"4 / 9 checks OK","depth":14,"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Copy the full SHA","depth":13,"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"02a3381","depth":13,"on_screen":true,"role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"02a3381","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Browse the repository at this point in the history","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Split","depth":16,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Split","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Unified","depth":16,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Unified","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Showing","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"7 changed files","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"with","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"60 additions","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"9 deletions","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Toggle diff contents","depth":15,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXButton","text":"Expand all","depth":16,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"8 changes: 6 additions & 2 deletions","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app/Component/AskAnything/AskAnythingPromptService.php","depth":15,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app/Component/AskAnything/AskAnythingPromptService.php","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy","depth":16,"bounds":{"left":0.0,"top":0.0,"width":0.011111111,"height":0.016111111},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show options","depth":15,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Original file line number","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Original file line","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Diff line number","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Diff line change","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Expand Up","depth":17,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"@@ -56,6 +56,7 @@ public function get(User $user, AskAnythingPromptTarget $target): array","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"56","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ownerUuid","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":18,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"56","depth":17,"bounds":{"left":0.5767361,"top":0.0,"width":0.010069445,"height":0.016111111},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":18,"bounds":{"left":0.6888889,"top":0.0,"width":0.0052083335,"height":0.016111111},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ownerUuid","depth":18,"bounds":{"left":0.6940972,"top":0.0,"width":0.045138888,"height":0.016111111},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":18,"bounds":{"left":0.7392361,"top":0.0,"width":0.0048611113,"height":0.016111111},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"57","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"shareUsers","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"57","depth":17,"bounds":{"left":0.5767361,"top":0.021666666,"width":0.010069445,"height":0.016111111},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":18,"bounds":{"left":0.6888889,"top":0.021666666,"width":0.0052083335,"height":0.016111111},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"shareUsers","depth":18,"bounds":{"left":0.6940972,"top":0.021666666,"width":0.05,"height":0.016111111},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":18,"bounds":{"left":0.74409723,"top":0.021666666,"width":0.0052083335,"height":0.016111111},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"58","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"shareGroups","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"58","depth":17,"bounds":{"left":0.5767361,"top":0.04388889,"width":0.010069445,"height":0.016111111},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":18,"bounds":{"left":0.6888889,"top":0.04388889,"width":0.0052083335,"height":0.016111111},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"shareGroups","depth":18,"bounds":{"left":0.6940972,"top":0.04388889,"width":0.055208333,"height":0.016111111},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":18,"bounds":{"left":0.74930555,"top":0.04388889,"width":0.0048611113,"height":0.016111111},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"59","depth":17,"bounds":{"left":0.5767361,"top":0.06611111,"width":0.010069445,"height":0.016111111},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"+","depth":18,"bounds":{"left":0.59930557,"top":0.06722222,"width":0.0048611113,"height":0.016111111},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":18,"bounds":{"left":0.6888889,"top":0.06611111,"width":0.0052083335,"height":0.016111111},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"prompt","depth":18,"bounds":{"left":0.6940972,"top":0.06611111,"width":0.029861111,"height":0.016111111},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->","depth":18,"bounds":{"left":0.7239583,"top":0.06611111,"width":0.010069445,"height":0.016111111},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"getHasReports","depth":18,"bounds":{"left":0.7340278,"top":0.06611111,"width":0.06527778,"height":0.016111111},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(),","depth":18,"bounds":{"left":0.79930556,"top":0.06611111,"width":0.014930556,"height":0.016111111},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"59","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":");","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"60","depth":17,"bounds":{"left":0.5767361,"top":0.08833333,"width":0.010069445,"height":0.016111111},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":");","depth":18,"bounds":{"left":0.6090278,"top":0.08833333,"width":0.07013889,"height":0.016111111},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"60","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"}","depth":18,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"61","depth":17,"bounds":{"left":0.5767361,"top":0.11055555,"width":0.010069445,"height":0.016111111},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"}","depth":18,"bounds":{"left":0.6090278,"top":0.11055555,"width":0.044791665,"height":0.016111111},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"61","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"62","depth":17,"bounds":{"left":0.5767361,"top":0.13277778,"width":0.010069445,"height":0.016111111},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-7283670509911136743
|
5784437285922037645
|
idle
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
New Tab
New Tab
Jiminny
Jiminny
Feed — jiminny — Sentry
Feed — jiminny — Sentry
Comparing master...JY-20676-delete-report-related-objects · jiminny/app
Comparing master...JY-20676-delete-report-related-objects · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (29)
Pull requests
(
29
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality (1)
Security and quality
(
1
)
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Comparing changes
Comparing changes
Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also
compare across forks
or
learn more about diff comparisons
learn more about diff comparisons
.
base: master
base:
master
...
compare: JY-20676-delete-report-related-objects
compare:
JY-20676-delete-report-related-objects
Able to merge.
These branches can be automatically merged.
@LakyLak
Add a title
*
JY-20676 delete AJ reports related objects
Generate pull request title with Copilot
Add a description
Add a description
Comment
Write
Write
Preview
Preview
### JIRA: JY-20676
#### Changes:
- Add field has_reports to Activity search and Ask Jiminny prompts lists
-
Markdown is supported
Markdown
is supported
Paste, drop, or click to add files
Paste, drop, or click to add files
Create pull request
Select a type of pull request
Remember, contributions to this repository should follow our
GitHub Community Guidelines
GitHub Community Guidelines
.
️
Reviewers
Suggestions
Request
Request
@nikolaybiaivanov
nikolaybiaivanov
nikolaybiaivanov
Request
Request
@ivhristova
ivhristova
ivhristova
At least 1 approving review is required to merge this pull request.
Assignees
No one—
assign yourself
Labels
None yet
Projects
None yet
Milestone
No milestone
Helpful resources
GitHub Community Guidelines
GitHub Community Guidelines
1
commit
7
files changed
1
contributor
Commits on May 19, 2026
Commits on May 19, 2026
JY-20676
JY-20676
delete AJ reports related objects
delete AJ reports related objects
@LakyLak
LakyLak
LakyLak
committed
5 minutes ago
4 / 9 checks OK
Copy the full SHA
02a3381
02a3381
Browse the repository at this point in the history
Split
Split
Unified
Unified
Showing
7 changed files
with
60 additions
and
9 deletions
.
Toggle diff contents
Expand all
8 changes: 6 additions & 2 deletions
app/Component/AskAnything/AskAnythingPromptService.php
app/Component/AskAnything/AskAnythingPromptService.php
Copy
Show options
Original file line number
Original file line
Diff line number
Diff line change
Expand Up
@@ -56,6 +56,7 @@ public function get(User $user, AskAnythingPromptTarget $target): array
56
$
ownerUuid
,
56
$
ownerUuid
,
57
$
shareUsers
,
57
$
shareUsers
,
58
$
shareGroups
,
58
$
shareGroups
,
59
+
$
prompt
->
getHasReports
(),
59
);
60
);
60
}
61
}
61
62...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
57103
|
NULL
|
0
|
2026-05-19T08:58:48.761669+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779181128761_m2.jpg...
|
Firefox
|
Comparing master...JY-20676-delete-report-related- Comparing master...JY-20676-delete-report-related-objects · jiminny/app — Work...
|
1
|
github.com/jiminny/app/compare/JY-20676-delete-rep github.com/jiminny/app/compare/JY-20676-delete-report-related-objects?expand=1...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
New Tab
New Tab
Jiminny
Jiminny
Feed — jiminny — Sentry
Feed — jiminny — Sentry
Comparing master...JY-20676-delete-report-related-objects · jiminny/app
Comparing master...JY-20676-delete-report-related-objects · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (29)
Pull requests
(
29
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality (1)
Security and quality
(
1
)
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Comparing changes
Comparing changes
Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also
compare across forks
or
learn more about diff comparisons
learn more about diff comparisons
.
base: master
base:
master
...
compare: JY-20676-delete-report-related-objects
compare:
JY-20676-delete-report-related-objects
Able to merge.
These branches can be automatically merged.
@LakyLak
Add a title
*
JY-20676 delete AJ reports related objects
Generate pull request title with Copilot
Add a description
Add a description
Comment
Write
Write
Preview
Preview
### JIRA: JY-20676
#### Changes:
- Add field has_reports to Activity search and Ask Jiminny prompts lists
-
Markdown is supported
Markdown
is supported
Paste, drop, or click to add files
Paste, drop, or click to add files
Create pull request
Select a type of pull request
Remember, contributions to this repository should follow our
GitHub Community Guidelines...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0,"top":0.0518755,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.06304868,"width":0.10106383,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"bounds":{"left":0.0,"top":0.08459697,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.09577015,"width":0.10721409,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.11731844,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.12849163,"width":0.18816489,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.15003991,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.16121309,"width":0.15674867,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.18276137,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.19393456,"width":0.039228722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.0,"top":0.21548285,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"bounds":{"left":0.013297873,"top":0.22665602,"width":0.014960106,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.2482043,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.013297873,"top":0.25937748,"width":0.013131649,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"bounds":{"left":0.0,"top":0.28092578,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"bounds":{"left":0.013297873,"top":0.29209897,"width":0.042719416,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Comparing master...JY-20676-delete-report-related-objects · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.31364724,"width":0.07962101,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Comparing master...JY-20676-delete-report-related-objects · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.32482043,"width":0.12865691,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.06732048,"top":0.32083002,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.0028257978,"top":0.34796488,"width":0.07413564,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0028257978,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.013796543,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.024933511,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.036070477,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.04720745,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to content","depth":6,"bounds":{"left":0.07962101,"top":0.0518755,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to content","depth":7,"bounds":{"left":0.07962101,"top":0.05347167,"width":0.0029920214,"height":0.21468475},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open menu","depth":10,"bounds":{"left":0.08494016,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Homepage (g then d)","depth":9,"bounds":{"left":0.099567816,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"jiminny","depth":12,"bounds":{"left":0.112865694,"top":0.06464485,"width":0.018949468,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jiminny","depth":14,"bounds":{"left":0.11486037,"top":0.07063048,"width":0.014960106,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":12,"bounds":{"left":0.13680187,"top":0.06464485,"width":0.017785905,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":14,"bounds":{"left":0.13879654,"top":0.07063048,"width":0.008477394,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search or jump to…","depth":9,"bounds":{"left":0.81698805,"top":0.06464485,"width":0.06565824,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":12,"bounds":{"left":0.82928854,"top":0.07063048,"width":0.011801862,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":12,"bounds":{"left":0.8424202,"top":0.07222666,"width":0.002493351,"height":0.011572227},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to search","depth":12,"bounds":{"left":0.84640956,"top":0.07063048,"width":0.021276595,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chat with Copilot","depth":10,"bounds":{"left":0.88464093,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Open Copilot…","depth":9,"bounds":{"left":0.8949468,"top":0.06464485,"width":0.008643617,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Create new...","depth":9,"bounds":{"left":0.9115692,"top":0.06464485,"width":0.01662234,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"All issues(g then i)","depth":9,"bounds":{"left":0.93085104,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All pull requests","depth":9,"bounds":{"left":0.94414896,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"All repositories","depth":9,"bounds":{"left":0.9574468,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"You have unread notifications(g then n)","depth":9,"bounds":{"left":0.97074467,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open user navigation menu","depth":9,"bounds":{"left":0.9840425,"top":0.06464485,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Repository navigation","depth":9,"bounds":{"left":0.079288565,"top":0.051077414,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Repository navigation","depth":10,"bounds":{"left":0.079288565,"top":0.05387071,"width":0.0787899,"height":0.023144454},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":12,"bounds":{"left":0.08494016,"top":0.09936153,"width":0.025099734,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":14,"bounds":{"left":0.095578454,"top":0.10574621,"width":0.011801862,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull requests (29)","depth":12,"bounds":{"left":0.11269947,"top":0.09936153,"width":0.05501995,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests","depth":14,"bounds":{"left":0.12400266,"top":0.10574621,"width":0.027925532,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"bounds":{"left":0.15525267,"top":0.113727055,"width":0.0029920214,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"29","depth":14,"bounds":{"left":0.15824468,"top":0.113727055,"width":0.0056515955,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"bounds":{"left":0.16389628,"top":0.113727055,"width":0.0018284575,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Agents","depth":12,"bounds":{"left":0.17037898,"top":0.09936153,"width":0.029089095,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Agents","depth":14,"bounds":{"left":0.18151596,"top":0.10574621,"width":0.014960106,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Actions","depth":12,"bounds":{"left":0.20212767,"top":0.09936153,"width":0.03025266,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Actions","depth":14,"bounds":{"left":0.21326463,"top":0.10574621,"width":0.016123671,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Wiki","depth":12,"bounds":{"left":0.23503989,"top":0.09936153,"width":0.023105053,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Wiki","depth":14,"bounds":{"left":0.24601063,"top":0.10574621,"width":0.009142287,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security and quality (1)","depth":12,"bounds":{"left":0.26080453,"top":0.09936153,"width":0.06732048,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security and quality","depth":14,"bounds":{"left":0.27244017,"top":0.10574621,"width":0.042719416,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"bounds":{"left":0.31881648,"top":0.113727055,"width":0.0029920214,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":14,"bounds":{"left":0.32180852,"top":0.113727055,"width":0.0021609042,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"bounds":{"left":0.32396942,"top":0.113727055,"width":0.0016622341,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Insights","depth":12,"bounds":{"left":0.3307846,"top":0.09936153,"width":0.03125,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Insights","depth":14,"bounds":{"left":0.34208778,"top":0.10574621,"width":0.016788565,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":12,"bounds":{"left":0.36469415,"top":0.09936153,"width":0.032081116,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":14,"bounds":{"left":0.37583113,"top":0.10574621,"width":0.017785905,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Important update","depth":10,"bounds":{"left":0.09325133,"top":0.14365523,"width":0.0003324468,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Important update","depth":11,"bounds":{"left":0.09325133,"top":0.1452514,"width":0.039228722,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.","depth":10,"bounds":{"left":0.09325133,"top":0.1452514,"width":0.2159242,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review this update","depth":10,"bounds":{"left":0.30917552,"top":0.1452514,"width":0.04055851,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review this update","depth":11,"bounds":{"left":0.30917552,"top":0.1452514,"width":0.04055851,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and manage your preferences in your","depth":10,"bounds":{"left":0.34973404,"top":0.1452514,"width":0.08261303,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub account settings","depth":10,"bounds":{"left":0.4323471,"top":0.1452514,"width":0.05219415,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GitHub account settings","depth":11,"bounds":{"left":0.4323471,"top":0.1452514,"width":0.05219415,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"bounds":{"left":0.48454124,"top":0.1452514,"width":0.0013297872,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dismiss banner","depth":9,"bounds":{"left":0.98636967,"top":0.13886672,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Comparing changes","depth":9,"bounds":{"left":0.33776596,"top":0.1915403,"width":0.40425533,"height":0.028731046},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Comparing changes","depth":10,"bounds":{"left":0.33776596,"top":0.1943336,"width":0.069148935,"height":0.023144454},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also","depth":10,"bounds":{"left":0.33776596,"top":0.22186752,"width":0.22240691,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"compare across forks","depth":10,"bounds":{"left":0.56017286,"top":0.22027135,"width":0.04637633,"height":0.016759777},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"or","depth":10,"bounds":{"left":0.6065492,"top":0.22186752,"width":0.006981383,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"learn more about diff comparisons","depth":10,"bounds":{"left":0.6135306,"top":0.22186752,"width":0.07396942,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"learn more about diff comparisons","depth":11,"bounds":{"left":0.6135306,"top":0.22186752,"width":0.07396942,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"bounds":{"left":0.6875,"top":0.22186752,"width":0.0013297872,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"base: master","depth":11,"bounds":{"left":0.35405585,"top":0.264166,"width":0.036402926,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"base:","depth":13,"bounds":{"left":0.3570479,"top":0.26935354,"width":0.010638298,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"master","depth":14,"bounds":{"left":0.36884972,"top":0.26935354,"width":0.013297873,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"...","depth":10,"bounds":{"left":0.39378324,"top":0.2717478,"width":0.0039893617,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"compare: JY-20676-delete-report-related-objects","depth":11,"bounds":{"left":0.4010971,"top":0.264166,"width":0.09075798,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"compare:","depth":13,"bounds":{"left":0.4040891,"top":0.26935354,"width":0.018450798,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"JY-20676-delete-report-related-objects","depth":14,"bounds":{"left":0.42370346,"top":0.26935354,"width":0.078125,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Able to merge.","depth":11,"bounds":{"left":0.50116354,"top":0.26855546,"width":0.035405584,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"These branches can be automatically merged.","depth":10,"bounds":{"left":0.5365692,"top":0.26855546,"width":0.09923537,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@LakyLak","depth":12,"bounds":{"left":0.33776596,"top":0.3064645,"width":0.013297873,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Add a title","depth":16,"bounds":{"left":0.35638297,"top":0.3084597,"width":0.025598405,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"*","depth":16,"bounds":{"left":0.38331118,"top":0.3084597,"width":0.002493351,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"JY-20676 delete AJ reports related objects","depth":15,"bounds":{"left":0.3567154,"top":0.32960895,"width":0.26529256,"height":0.023942538},"on_screen":true,"value":"JY-20676 delete AJ reports related objects","help_text":"","placeholder":"Title","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Generate pull request title with Copilot","depth":16,"bounds":{"left":0.62599736,"top":0.3320032,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Add a description","depth":12,"bounds":{"left":0.35638297,"top":0.36711892,"width":0.04438165,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Add a description","depth":13,"bounds":{"left":0.35638297,"top":0.36911413,"width":0.04438165,"height":0.015163607},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Comment","depth":12,"bounds":{"left":0.35638297,"top":0.3942538,"width":0.021775266,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Write","depth":13,"bounds":{"left":0.35638297,"top":0.3926576,"width":0.022606382,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Write","depth":14,"bounds":{"left":0.3620346,"top":0.40223464,"width":0.011303191,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Preview","depth":13,"bounds":{"left":0.37898937,"top":0.3926576,"width":0.028091755,"height":0.031923383},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Preview","depth":14,"bounds":{"left":0.38464096,"top":0.40223464,"width":0.016788565,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"### JIRA: JY-20676\n\n#### Changes:\n\n- Add field has_reports to Activity search and Ask Jiminny prompts lists\n-","depth":15,"bounds":{"left":0.35970744,"top":0.43176377,"width":0.27260637,"height":0.19952115},"on_screen":true,"value":"### JIRA: JY-20676\n\n#### Changes:\n\n- Add field has_reports to Activity search and Ask Jiminny prompts lists\n-","placeholder":" ","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXLink","text":"Markdown is supported","depth":14,"bounds":{"left":0.359375,"top":0.63846767,"width":0.057679523,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Markdown","depth":16,"bounds":{"left":0.36901596,"top":0.64365524,"width":0.019780586,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"is supported","depth":16,"bounds":{"left":0.38879654,"top":0.64365524,"width":0.025265958,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Paste, drop, or click to add files","depth":13,"bounds":{"left":0.42137632,"top":0.63846767,"width":0.07330452,"height":0.022346368},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Paste, drop, or click to add files","depth":15,"bounds":{"left":0.43101728,"top":0.64365524,"width":0.06067154,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Create pull request","depth":12,"bounds":{"left":0.56865025,"top":0.6743815,"width":0.053025264,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Select a type of pull request","depth":13,"bounds":{"left":0.62167555,"top":0.6743815,"width":0.013962766,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Remember, contributions to this repository should follow our","depth":12,"bounds":{"left":0.36303192,"top":0.7138867,"width":0.114527926,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub Community Guidelines","depth":12,"bounds":{"left":0.47755983,"top":0.7138867,"width":0.05651596,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
-5766357436933044175
|
8090280300504735116
|
idle
|
accessibility
|
NULL
|
Platform Sprint 4 Q2 - Platform Team - Scrum Board Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 4 Q2 - Platform Team - Scrum Board - Jira
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20725 add HS rate limit handling on activities rematching by LakyLak · Pull Request #12066 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
JY-20808 low priority indexing queue by Vasil-Jiminny · Pull Request #12082 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
New Tab
New Tab
Jiminny
Jiminny
Feed — jiminny — Sentry
Feed — jiminny — Sentry
Comparing master...JY-20676-delete-report-related-objects · jiminny/app
Comparing master...JY-20676-delete-report-related-objects · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
All issues(g then i)
All pull requests
All repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (29)
Pull requests
(
29
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality (1)
Security and quality
(
1
)
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Comparing changes
Comparing changes
Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also
compare across forks
or
learn more about diff comparisons
learn more about diff comparisons
.
base: master
base:
master
...
compare: JY-20676-delete-report-related-objects
compare:
JY-20676-delete-report-related-objects
Able to merge.
These branches can be automatically merged.
@LakyLak
Add a title
*
JY-20676 delete AJ reports related objects
Generate pull request title with Copilot
Add a description
Add a description
Comment
Write
Write
Preview
Preview
### JIRA: JY-20676
#### Changes:
- Add field has_reports to Activity search and Ask Jiminny prompts lists
-
Markdown is supported
Markdown
is supported
Paste, drop, or click to add files
Paste, drop, or click to add files
Create pull request
Select a type of pull request
Remember, contributions to this repository should follow our
GitHub Community Guidelines...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
57082
|
NULL
|
0
|
2026-05-19T08:53:43.146146+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779180823146_m2.jpg...
|
iTerm2
|
APP (-zsh)
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Last login: Mon May 18 09:17:28 on ttys007
Poetry Last login: Mon May 18 09:17:28 on ttys007
Poetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parents
Poetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parents
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ co master
error: Your local changes to the following files would be overwritten by checkout:
PIPEDRIVE_V2_MIGRATION_TICKETS.md
Please commit your changes or stash them before you switch branches.
Aborting
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ git pull
remote: Enumerating objects: 1047, done.
remote: Counting objects: 100% (832/832), done.
remote: Compressing objects: 100% (298/298), done.
remote: Total 1047 (delta 634), reused 596 (delta 534), pack-reused 215 (from 3)
Receiving objects: 100% (1047/1047), 353.16 KiB | 1.56 MiB/s, done.
Resolving deltas: 100% (687/687), completed with 107 local objects.
From github.com:jiminny/app
907c54896c..34656c53ed pipedrive-sdk-poc -> origin/pipedrive-sdk-poc
03325ec50f..4e7078fd8b JY-18091-upgrade-to-php-8-5 -> origin/JY-18091-upgrade-to-php-8-5
e7d231e163..bc6a3fce6b JY-20725-handle-HS-search-rate-limit -> origin/JY-20725-handle-HS-search-rate-limit
* [new branch] JY-20749-user-can-view-recorded-meetings -> origin/JY-20749-user-can-view-recorded-meetings
98ca281a04..e0351be069 JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue
569abb5149..3906a9238a JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details -> origin/JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details
ad6c2a86e8..50eb6afba9 JY-20846-mcp-enable-the-ai-to-know-details-about-the-user -> origin/JY-20846-mcp-enable-the-ai-to-know-details-about-the-user
* [new branch] JY-20893-chunk-control-per-update-target -> origin/JY-20893-chunk-control-per-update-target
31c62924a5..cb4ebf0c36 master -> origin/master
Updating 907c54896c..34656c53ed
Fast-forward
PIPEDRIVE_V2_MIGRATION_TICKETS.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 52 insertions(+)
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ co master
M .env.local
M config/logging.php
Switched to branch 'master'
Your branch is behind 'origin/master' by 31 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull
Updating 31c62924a5..cb4ebf0c36
Fast-forward
app/Component/ES/Processor/Traits/SelectEntityListTrait.php | 20 ------
app/Services/Calendar/CalendarActivityService.php | 46 +++++++++++++
app/Services/Calendar/Command/MapActivityData.php | 106 +++-------------------------
docs/mcp/explorer/explorer.html | 104 +++++++++++++++++++++++++---
docs/mcp/explorer/explorer.template.html | 102 ++++++++++++++++++++++++---
docs/mcp/tools-list.json | 373 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
docs/mcp/tools.md | 117 +++++++++++++++++++++++--------
tests/Unit/Component/ES/AsyncUpdateElasticSearchTest.php | 16 +----
tests/Unit/Component/ES/Listeners/UpdateMultipleTargetsListenerTest.php | 10 ---
tests/Unit/Component/ES/Listeners/UpdateSingleTargetListenerTest.php | 6 --
tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 9 ---
tests/Unit/Component/ES/Processor/Traits/SelectEntityListTraitTest.php | 15 ++--
tests/Unit/Component/ES/UpdateProcessManagerTest.php | 2 -
tests/Unit/Services/Calendar/CalendarActivityServiceTest.php | 150 ++++++++++++++++++++++++++++++++++++++--
tests/Unit/Services/Calendar/Command/MapActivityDataTest.php | 78 ++-------------------
15 files changed, 832 insertions(+), 322 deletions(-)
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20613-allow-owner-role-on-team-setup
Switched to a new branch 'JY-20613-allow-owner-role-on-team-setup'
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ csfix
docker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff
PHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.
PHP runtime: 8.3.30
Running analysis on 7 cores with 10 files per process.
Parallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!
Loaded config default from ".php-cs-fixer.dist.php".
5682/5682 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
Fixed 0 of 5682 files in 56.978 seconds, 67.00 MB memory used
What's next:
Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1
Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ csfix
docker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff
PHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.
PHP runtime: 8.3.30
Running analysis on 7 cores with 10 files per process.
Parallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!
Loaded config default from ".php-cs-fixer.dist.php".
5682/5682 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
Fixed 0 of 5682 files in 49.910 seconds, 60.00 MB memory used
What's next:
Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1
Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git pull
remote: Enumerating objects: 248, done.
remote: Counting objects: 100% (128/128), done.
remote: Compressing objects: 100% (23/23), done.
remote: Total 59 (delta 43), reused 44 (delta 33), pack-reused 0 (from 0)
Unpacking objects: 100% (59/59), 10.48 KiB | 228.00 KiB/s, done.
From github.com:jiminny/app
b7df560451..190239dfd4 JY-20613-allow-owner-role-on-team-setup -> origin/JY-20613-allow-owner-role-on-team-setup
e0351be069..d94a285ae7 JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue
* [new branch] JY-20920-fix-participant-matcher -> origin/JY-20920-fix-participant-matcher
cb4ebf0c36..90bca4e4b2 master -> origin/master
Merge made by the 'ort' strategy.
app/Component/ES/ChunkSize.php | 54 +++++++++++++++++++++++++++
app/Component/ES/Processor/DTOs/SelectionList.php | 4 +-
app/Component/ES/Processor/TargetEntitiesSelector.php | 19 ++++++----
app/Http/Middleware/McpTierMiddleware.php | 27 +++-----------
app/Mcp/Servers/JiminnyServer.php | 2 +
app/Mcp/Tools/GetMeTool.php | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
app/Models/Feature/FeatureEnum.php | 1 +
database/migrations/2026_05_13_124153_create_mcp_feature_flag.php | 25 +++++++++++++
front-end/src/components/Settings/Kiosk/modals/EditTeamModal/EditTeamModal.vue | 52 ++++++++++++++++++--------
front-end/src/components/Settings/Kiosk/modals/EditTeamModal/__tests__/EditTeamModal.spec.js | 14 +++++++
tests/Feature/Mcp/GetMeToolFeatureTest.php | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/Feature/Mcp/ListCallsToolFeatureTest.php | 2 +-
tests/Feature/Mcp/McpTestHelpersTrait.php | 19 +++++++++-
tests/Unit/Component/ES/ChunkSizeTest.php | 50 +++++++++++++++++++++++++
tests/Unit/Component/ES/Processor/DTOs/SelectionListTest.php | 27 ++++++++++----
tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 39 +++++++++++---------
16 files changed, 557 insertions(+), 75 deletions(-)
create mode 100644 app/Component/ES/ChunkSize.php
create mode 100644 app/Mcp/Tools/GetMeTool.php
create mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.php
create mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.php
create mode 100644 tests/Unit/Component/ES/ChunkSizeTest.php
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git push
Enumerating objects: 40, done.
Counting objects: 100% (34/34), done.
Delta compression using up to 8 threads
Compressing objects: 100% (18/18), done.
Writing objects: 100% (18/18), 1.58 KiB | 1.58 MiB/s, done.
Total 18 (delta 15), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (15/15), completed with 13 local objects.
To github.com:jiminny/app.git
190239dfd4..ec1b261264 JY-20613-allow-owner-role-on-team-setup -> JY-20613-allow-owner-role-on-team-setup
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ gbr
* JY-20613-allow-owner-role-on-team-setup
pipedrive-sdk-poc
master
JY-20903-update_activity-stage-on-opportunity-change
JY-20904-fix-update-es-on-activity-command
JY-20891-improve-sms-text-relays
JY-20725-handle-HS-search-rate-limit
JY-20818-move-AJ-reports-to-separated-datadog-metric
JY-20773-fix-automated-reports-user-pilot-tracking
JY-20157-AJ-report-not-send-notification
JY-20508-notify-before-AJ-report-expiration
JY-20372-ai-reports-promotion-pages
JY-20352-sync-opportunities-without-a-local-owner-user-id-is-null
JY-20738-debug-AJ-tracking-UP
a
JY-18909-automated-reports-ask-jiminny
JY-20692-fix-integration-app-[API_KEY]
JY-20553-debug-crm-sync-delays
JY-20698-fix-SF-activity-types-on-new-playbook
JY-20543-AJ-report-tracking
JY-20384-handle-auto-sync-with-no-access-to-event-type
JY-20458-ask-jiminny-user-definitions
JY-19666-fix-import-contacts-account-association
JY-19666-HS-import-contacts-and-accounts-batch-job
JY-20458-Ask-Jiminny-Reports
JY-20200-batch-update-CRM-objects-Salesforce
JY-19666-HS-webhooks-add-contact-and-company
JY-20348-trigger-setup-DI-layout-on-team-creation
JY-20326-refactor-info-message-in-command
JY-20317-fix-auto-log-delay-issue-on-all-channels-disabled
JY-20312-remove-on-update-change-last-synced-at-crm-configurations
JY-20306-SF-skip-auto-sync-for-task-based-playbook
JY-20192-remove-deleted-team-from-saved-search-filters
JY-20197-import-opportunity-batch-job
JY-20293-enable-status-field-for-pipedrive-deals
JY-20191-remove-commands-interactive-prompts
JY-20118-change-default-sync-strategy
JY-20183-add-cache-on-auto-log-delay
JY-20197-add-import-opportunity-batch-job
20118-hs-opportunity-make-webhook-strategy-default
JY-20118-make-default-hs-opportunity-sync-strategy-webhook-based
JY-20196-handle-opportunity-without-note
JY-20118-improve-opportunity-import
JY-20189-handle-activity-search-on-deleted-groups
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ co JY-20725-handle-HS-search-rate-limit
M .env.local
M config/logging.php
Switched to branch 'JY-20725-handle-HS-search-rate-limit'
Your branch is behind 'origin/JY-20725-handle-HS-search-rate-limit' by 439 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ git pull
Updating 0f3e438941..bc6a3fce6b
Fast-forward
.gitignore | 3 +-
.windsurfrules | 168 ++---
CLAUDE.md | 1 +
app/Component/ActivityAnalytics/Service/CalculateTalkTimeOffsetsFromTranscription.php | 24 +-
app/Component/AiActivityType/Services/AiActivityTypeEligibilityChecker.php | 28 +-
app/Component/AiAutomation/Actions/PrepareUpdateDtoAction.php | 32 +-
app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.php | 47 ++
app/Component/AiAutomation/TestCrmAiPromptService.php | 14 +
app/Component/AiCallScoring/Services/AiCallScoringEligibilityChecker.php | 9 +
app/Component/ES/ElasticSearchDocumentPartialUpdater.php | 13 +-
app/Component/ES/ElasticSearchWorkerManager.php | 86 ---
app/Component/ES/Processor/Actions/LoadDocumentsAction.php | 80 +--
app/Component/ES/Processor/EntityQueryBuilder.php | 12 +-
app/Component/ES/Processor/TargetEntitiesSelector.php | 2 +-
app/Component/ES/Processor/Traits/SkipActivityTrait.php | 25 -
app/Component/ES/Repositories/EsResetActivityRepository.php | 11 +-
app/Component/ES/Worker/ActivityWorker.php | 73 --
app/Component/ES/Worker/EntityWorker.php | 44 --
app/Component/ES/Worker/WorkerAmount.php | 60 --
app/Component/ES/Worker/WorkerInterface.php | 15 -
app/Component/ElasticSearch/Contract/Searchable.php | 4 +
app/Component/Encoding/Job/AnalyzeTrackChannelsJob.php | 20 +-
app/Component/Encoding/Service/GenerateSpeechFromSilenceService.php | 85 ++-
app/Component/FFMpeg/Services/GetSpeechIntervalsService.php | 18 +-
app/Component/LanguageDetection/Services/FindSpeechTimeService.php | 22 +-
app/Component/Nudge/Job/ProcessOrganisationImmediateNudgesJob.php | 218 +++++-
app/Component/ParagraphBreaker/Services/TranscriptionParagraphsService.php | 4 +
app/Component/ParticipantSpeech/Services/ParticipantSpeechesCreator.php | 33 +
app/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleter.php | 15 +
app/Component/ParticipantSpeech/Services/ParticipantSpeechesProvider.php | 51 +-
app/Component/ParticipantSpeech/Services/ParticipantSpeechesUploader.php | 36 +
app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.php | 11 +
app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/NoAssemblyIdException.php | 11 +
app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/SuccessfulResponse.php | 6 +
app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNotCorrectFormatException.php | 11 +
app/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeechesService.php | 23 +-
app/Component/Transcription/Diarization/Source/MeetingBotSource.php | 16 +-
app/Component/Transcription/TranscriptionProcessor/TranscriptionProcessor.php | 3 +
app/Console/Commands/Activities/ActivityHardDeleteCommand.php | 4 +-
app/Console/Commands/Activities/Copy.php | 2 +
app/Console/Commands/Activities/SetupIntegration/TwilioSetS3RecordingCredentialsCommand.php | 119 ++++
app/Console/Commands/Activities/UpdateActivityElasticSearchDocumentCommand.php | 10 +-
app/Console/Commands/Crm/BackfillOpportunityUserFromAccountCommand.php | 126 ++++
app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.php | 19 -
app/Console/Commands/Elasticsearch/AsyncUpdateEsEntities.php | 50 +-
app/Console/Commands/Elasticsearch/ResetAsyncElasticSearchCommand.php | 30 +-
app/Console/Commands/GeckoExport/GeckoExportParticipantSpeechesCommand.php | 14 +-
app/Console/Commands/IssueMcpTokenCommand.php | 84 +++
app/Console/Commands/JiminnyDebugCommand.php | 7 +-
app/Console/Commands/Tracks/CleanupActivityTracksCommand.php | 2 +-
app/Console/Kernel.php | 6 +-
app/Contracts/Services/Calendar/CalendarTrait.php | 80 ++-
app/Events/AutomatedReports/AutomatedReportGenerated.php | 3 +
app/Http/Controllers/API/AiCallScoring/AiScorecardController.php | 7 +-
app/Http/Controllers/API/TeamAiAutomationController.php | 8 +
app/Http/Controllers/CustomerApi/CustomerApiController.php | 4 +-
app/Http/Controllers/Kiosk/ActivityController.php | 58 +-
app/Http/Controllers/Settings/PlaybookController.php | 15 +-
app/Http/Kernel.php | 23 +
app/Http/Middleware/McpAuditMiddleware.php | 156 ++++
app/Http/Middleware/McpTierMiddleware.php | 54 ++
app/Http/Requests/API/V2/ZapierUploadActivityRequest.php | 28 +-
app/Jobs/Activity/Import/ImportTwilioVideoSpeechesJob.php | 25 +-
app/Jobs/Activity/Import/IsActivityReadyForProcessingJob.php | 10 +-
app/Jobs/Calendar/SetupCalendarSync.php | 21 +-
app/Jobs/ImportRemoteTrackJob.php | 96 ++-
app/Jobs/Mailbox/EmailTextRelay.php | 15 +-
app/Mcp/Contracts/McpCallRepositoryInterface.php | 30 +
app/Mcp/DTO/ListCallsFilters.php | 29 +
app/Mcp/Errors/McpError.php | 123 ++++
app/Mcp/Repositories/McpActivityHydrator.php | 145 ++++
app/Mcp/Repositories/McpCallRepository.php | 84 +++
app/Mcp/Repositories/McpElasticCallRepository.php | 171 +++++
app/Mcp/Servers/JiminnyServer.php | 38 +
app/Mcp/Tools/ListCallsTool.php | 205 ++++++
app/Models/Activity.php | 10 +-
app/Models/Activity/Transcription.php | 17 +-
app/Models/ElasticSearch/OpportunityElasticSearchTrait.php | 5 +
app/Models/Participant.php | 1 +
app/Providers/AppServiceProvider.php | 22 +
app/Repositories/Crm/ContactRepository.php | 69 +-
app/Repositories/ParticipantSpeechRepository.php | 13 +-
app/Services/Activity/ParticipantsService.php | 19 +-
app/Services/Activity/Twilio/S3RecordingCredentialsService.php | 82 +++
app/Services/ActivityService.php | 21 +-
app/Services/Calendar/CalendarActivityService.php | 46 ++
app/Services/Calendar/Command/ImportParticipants.php | 1 +
app/Services/Calendar/Command/MapActivityData.php | 106 +--
app/Services/Calendar/GoogleCalendarService.php | 12 +-
app/Services/Crm/Close/Processor/OpportunityProcessor.php | 2 +-
app/Services/Crm/Close/Service.php | 22 +-
app/Services/Crm/Copper/Service.php | 12 +-
app/Services/Crm/Hubspot/Service.php | 154 +++-
app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php | 88 ++-
app/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTrait.php | 22 +-
app/Services/Crm/Pipedrive/Service.php | 17 +-
app/Services/Crm/Salesforce/Service.php | 42 +-
app/Services/Mail/Office/EmailApiClient.php | 129 +---
app/Services/RecallAI/Commands/ScheduleBotCommand.php | 39 +-
app/Services/RecallAI/RecallAIService.php | 22 +-
composer.json | 3 +-
composer.lock | 87 ++-
config/mcp.php | 23 +
database/migrations/2026_04_30_120000_create_mcp_audit_log_table.php | 36 +
docs/mcp/explorer/explorer.html | 697 ++++++++++++++++++
docs/mcp/explorer/explorer.template.html | 697 ++++++++++++++++++
docs/mcp/explorer/generate.js | 215 ++++++
docs/mcp/explorer/tool-explorer-meta.json | 11 +
docs/mcp/tools-list.json | 2536 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
docs/mcp/tools.md | 621 ++++++++++++++++
front-end/package.json | 4 +-
front-end/src/components/Settings/OrgSettings/AiAutomation/CrmFilling/TemplateFieldForm.vue | 28 +-
front-end/src/components/Settings/OrgSettings/Playbooks/AddEditPlaybook.vue | 10 +
front-end/src/components/playback/comments/ActivityComment.less | 10 +-
front-end/src/components/shared/PromptTester/PromptTester.vue | 12 +-
front-end/src/components/shared/__tests__/PromptTester.spec.js | 35 +
front-end/src/components/shared/modals/EntityPickerModal/__tests__/useEntitiesCache.spec.ts | 37 +
front-end/src/components/shared/modals/EntityPickerModal/useEntitiesCache.ts | 9 +
front-end/yarn.lock | 16 +-
phpstan-baseline.neon | 50 --
routes/api.php | 11 +
sonar-project.properties | 91 ++-
tests/Feature/Component/Nudge/ProcessOrganisationImmediateNudgesJobTest.php | 534 ++++++++++++++
tests/Feature/Jobs/ImportRemoteTrackJobTest.php | 283 +++++++-
tests/Feature/Mcp/IssueMcpTokenCommandTest.php | 53 ++
tests/Feature/Mcp/ListCallsToolElasticFeatureTest.php | 155 ++++
tests/Feature/Mcp/ListCallsToolFeatureTest.php | 352 ++++++++++
tests/Feature/Mcp/McpTestHelpersTrait.php | 77 ++
tests/Feature/Services/Team/TeamDeleteHandlers/Retention/RetentionRepositoryHandlerTest.php | 1 +
tests/Stubs/SentryStub.php | 18 +
tests/Unit/Component/ActivityAnalytics/Service/CalculateTalkTimeOffsetFromTranscriptionTest.php | 28 +-
tests/Unit/Component/AiActivityType/Services/AiActivityTypeEligibilityCheckerTest.php | 103 ++-
tests/Unit/Component/AiAutomation/Actions/PrepareUpdateDtoActionTest.php | 91 +++
tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheckerTest.php | 124 ++++
tests/Unit/Component/AiAutomation/TestCrmAiPromptServiceTest.php | 67 +-
tests/Unit/Component/AiCallScoring/Services/AiCallScoringEligibilityCheckerTest.php | 55 ++
tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.php | 135 ----
tests/Unit/Component/ES/Processor/Actions/LoadDocumentsActionTest.php | 220 ++++++
tests/Unit/Component/ES/Processor/EntityQueryBuilderTest.php | 21 +-
tests/Unit/Component/ES/Processor/Traits/SkipActivityTraitTest.php | 51 --
tests/Unit/Component/ES/Worker/ActivityWorkerTest.php | 174 -----
tests/Unit/Component/ES/Worker/EntityWorkerTest.php | 97 ---
tests/Unit/Component/ES/Worker/WorkerAmountTest.php | 116 ---
tests/Unit/Component/Encoding/Job/AnalyzeTrackChannelsJobTest.php | 52 +-
tests/Unit/Component/Encoding/Service/GenerateSpeechFromSilenceServiceTest.php | 171 ++---
tests/Unit/Component/FFMpeg/Services/GetSpeechIntervalsTest.php | 36 +-
tests/Unit/Component/LanguageDetection/Services/FindSpeechTimeServiceTest.php | 20 +-
tests/Unit/Component/MobileSettings/MobileSettingsControllerTest.php | 5 +-
tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCreatorTest.php | 75 ++
tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleterTest.php | 63 ++
tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesProviderTest.php | 134 ++++
tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesUploaderTest.php | 57 ++
tests/Unit/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeechesServiceTest.php | 51 +-
tests/Unit/Component/Transcription/Diarization/Source/MeetingBotSourceTest.php | 29 +-
tests/Unit/Contracts/Services/Calendar/CalendarTraitTest.php | 58 +-
tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.php | 159 +++++
tests/Unit/Jobs/Activity/Import/ImportTwilioVideoSpeechesJobTest.php | 22 +-
tests/Unit/Jobs/Activity/Import/IsActivityReadyForProcessingJobTest.php | 26 +-
tests/Unit/Jobs/Calendar/SetupCalendarSyncTest.php | 25 -
tests/Unit/Services/Activity/ParticipantsServiceTest.php | 12 +-
tests/Unit/Services/Activity/Twilio/S3RecordingCredentialsServiceTest.php | 180 +++++
tests/Unit/Services/ActivityServiceTest.php | 132 ++++
tests/Unit/Services/Calendar/CalendarActivityServiceTest.php | 150 +++-
tests/Unit/Services/Calendar/Command/ImportParticipantsTest.php | 6 +-
tests/Unit/Services/Calendar/Command/MapActivityDataTest.php | 78 +-
tests/Unit/Services/Calendar/GoogleCalendarServiceTest.php | 116 +++
tests/Unit/Services/Crm/Close/ServiceTest.php | 165 +++++
tests/Unit/Services/Crm/Hubspot/ServiceTest.php | 272 ++++++-
tests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTest.php | 25 +-
tests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTraitMatchActivitiesTest.php | 3 +-
tests/Unit/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTraitOpportunitiesTest.php | 40 ++
tests/Unit/Services/Crm/Pipedrive/ImportOpportunityMatchActivitiesTest.php | 2 +
tests/Unit/Services/Crm/Salesforce/ServiceTest.php | 139 ++++
tests/Unit/Services/Mail/Office/EmailApiClientTest.php | 195 ++---
tests/Unit/Services/RecallAI/RecallAIServiceTest.php | 24 +-
175 files changed, 12562 insertions(+), 2162 deletions(-)
create mode 120000 CLAUDE.md
create mode 100644 app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.php
delete mode 100644 app/Component/ES/ElasticSearchWorkerManager.php
delete mode 100644 app/Component/ES/Processor/Traits/SkipActivityTrait.php
delete mode 100644 app/Component/ES/Worker/ActivityWorker.php
delete mode 100644 app/Component/ES/Worker/EntityWorker.php
delete mode 100644 app/Component/ES/Worker/WorkerAmount.php
delete mode 100644 app/Component/ES/Worker/WorkerInterface.php
create mode 100644 app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.php
create mode 100644 app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/NoAssemblyIdException.php
create mode 100644 app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNotCorrectFormatException.php
create mode 100644 app/Console/Commands/Activities/SetupIntegration/TwilioSetS3RecordingCredentialsCommand.php
create mode 100644 app/Console/Commands/Crm/BackfillOpportunityUserFromAccountCommand.php
delete mode 100644 app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.php
create mode 100644 app/Console/Commands/IssueMcpTokenCommand.php
create mode 100644 app/Http/Middleware/McpAuditMiddleware.php
create mode 100644 app/Http/Middleware/McpTierMiddleware.php
create mode 100644 app/Mcp/Contracts/McpCallRepositoryInterface.php
create mode 100644 app/Mcp/DTO/ListCallsFilters.php
create mode 100644 app/Mcp/Errors/McpError.php
create mode 100644 app/Mcp/Repositories/McpActivityHydrator.php
create mode 100644 app/Mcp/Repositories/McpCallRepository.php
create mode 100644 app/Mcp/Repositories/McpElasticCallRepository.php
create mode 100644 app/Mcp/Servers/JiminnyServer.php
create mode 100644 app/Mcp/Tools/ListCallsTool.php
create mode 100644 app/Services/Activity/Twilio/S3RecordingCredentialsService.php
create mode 100644 config/mcp.php
create mode 100644 database/migrations/2026_04_30_120000_create_mcp_audit_log_table.php
create mode 100644 docs/mcp/explorer/explorer.html
create mode 100644 docs/mcp/explorer/explorer.template.html
create mode 100644 docs/mcp/explorer/generate.js
create mode 100644 docs/mcp/explorer/tool-explorer-meta.json
create mode 100644 docs/mcp/tools-list.json
create mode 100644 docs/mcp/tools.md
create mode 100644 front-end/src/components/shared/modals/EntityPickerModal/__tests__/useEntitiesCache.spec.ts
create mode 100644 tests/Feature/Component/Nudge/ProcessOrganisationImmediateNudgesJobTest.php
create mode 100644 tests/Feature/Mcp/IssueMcpTokenCommandTest.php
create mode 100644 tests/Feature/Mcp/ListCallsToolElasticFeatureTest.php
create mode 100644 tests/Feature/Mcp/ListCallsToolFeatureTest.php
create mode 100644 tests/Feature/Mcp/McpTestHelpersTrait.php
create mode 100644 tests/Stubs/SentryStub.php
create mode 100644 tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheckerTest.php
delete mode 100644 tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.php
create mode 100644 tests/Unit/Component/ES/Processor/Actions/LoadDocumentsActionTest.php
delete mode 100644 tests/Unit/Component/ES/Processor/Traits/SkipActivityTraitTest.php
delete mode 100644 tests/Unit/Component/ES/Worker/ActivityWorkerTest.php
delete mode 100644 tests/Unit/Component/ES/Worker/EntityWorkerTest.php
delete mode 100644 tests/Unit/Component/ES/Worker/WorkerAmountTest.php
create mode 100644 tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCreatorTest.php
create mode 100644 tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.php
create mode 100644 tests/Unit/Services/Activity/Twilio/S3RecordingCredentialsServiceTest.php
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ git status
On branch master
Your branch is behind 'origin/master' by 114 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: .env.local
modified: app/Component/SCIM/Constants.php
modified: app/Component/SCIM/ScimProvisioning.php
modified: app/Component/Twilio/Conference/ConferenceManager/SoftPhoneManager.php
modified: app/Console/Commands/JiminnyDebugCommand.php
modified: app/DTO/SCIM/AAD/Request/CoreUserRequest.php
modified: app/DTO/SCIM/AAD/Response/CoreUser.php
modified: app/Services/Telephony/TextMessagingService.php
modified: config/logging.php
Untracked files:
(use "git add <file>..." to include in what will be committed)
.env.nikilocal
.env.other
WEBHOOK_FILTERING_IMPLEMENTATION.md
app/Component/SCIM/Mutators/Attributes/User/RoleAttr.php
app/Console/Commands/Crm/Hubspot/SimulateWebhooksCommand.php
app/Console/Commands/Reports/CreateMockAskJiminnyReportResultCommand.php
app/Rules/ListenerRoleCannotHaveAdminOrManagerPermissionRule.php
ids.txt
public/favicon.ico
raw_sql_query.sql
tests/Unit/Component/SCIM/Mutators/Attributes/User/RoleAttrTest.php
tests/Unit/Policies/CanAccessAiReportsTest.php
tests/Unit/Rules/ListenerRoleCannotHaveAdminOrManagerPermissionRuleTest.php
no changes added to commit (use "git add" and/or "git commit -a")
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull
remote: Enumerating objects: 306, done.
remote: Counting objects: 100% (299/299), done.
remote: Compressing objects: 100% (183/183), done.
remote: Total 306 (delta 213), reused 171 (delta 116), pack-reused 7 (from 1)
Receiving objects: 100% (306/306), 80.12 KiB | 1000.00 KiB/s, done.
Resolving deltas: 100% (213/213), completed with 53 local objects.
From github.com:jiminny/app
90bca4e4b2..5604af40cf master -> origin/master
4e7078fd8b..0b8343d179 JY-18091-upgrade-to-php-8-5 -> origin/JY-18091-upgrade-to-php-8-5
098eeaa087..d5a447e492 JY-20613-allow-owner-role-on-team-setup -> origin/JY-20613-allow-owner-role-on-team-setup
c3a76ace91..af65249d0f JY-20749-user-can-view-recorded-meetings -> origin/JY-20749-user-can-view-recorded-meetings
d94a285ae7..7ce96cb5fe JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue
* [new branch] JY-20842-remove-partial-updater -> origin/JY-20842-remove-partial-updater
* [new branch] JY-20920-fix-participant-flip -> origin/JY-20920-fix-participant-flip
* [new branch] secfix/npm-20260519 -> origin/secfix/npm-20260519
Updating cb4ebf0c36..5604af40cf
Fast-forward
app/Component/ES/ChunkSize.php | 54 +++++++++++++++++++
app/Component/ES/Processor/DTOs/SelectionList.php | 4 +-
app/Component/ES/Processor/TargetEntitiesSelector.php | 19 ++++---
app/Component/MeetingBot/Service/ParticipantMatcher.php | 46 ++++++++++++----
app/Exceptions/RateLimitException.php | 19 ++++++-
app/Http/Middleware/McpTierMiddleware.php | 27 ++--------
app/Jobs/Crm/MatchActivityCrmData.php | 47 ++++++++++++----
app/Jobs/Middleware/HandleHubspotRateLimit.php | 42 +++++++++++++++
app/Mcp/Servers/JiminnyServer.php | 2 +
app/Mcp/Tools/GetMeTool.php | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++
app/Models/Feature/FeatureEnum.php | 1 +
app/Services/Activity/HubSpot/ProviderResolver.php | 4 +-
app/Services/Activity/HubSpot/ProviderResolverInterface.php | 2 +-
app/Services/Activity/HubSpot/Providers/Provider.php | 2 +-
app/Services/Activity/HubSpot/Providers/ProviderKixie.php | 2 +-
app/Services/Activity/HubSpot/Providers/ProviderOrum.php | 2 +-
app/Services/Activity/HubSpot/Providers/ProviderTwilio.php | 2 +-
app/Services/Activity/HubSpot/Providers/ProviderTwilioFlex.php | 5 +-
app/Services/Activity/HubSpot/Service.php | 97 +++++++++++++++++++++++++++------
app/Services/Crm/Hubspot/Client.php | 132 +++++++++++++++++++++++++++++++++++++++++++++
app/Services/Crm/Hubspot/HubspotClientInterface.php | 15 ++++++
app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php | 21 ++++----
app/Services/Crm/Hubspot/Pagination/PaginationState.php | 2 +-
database/migrations/2026_05_13_124153_create_mcp_feature_flag.php | 25 +++++++++
tests/Feature/Mcp/GetMeToolFeatureTest.php | 140 +++++++++++++++++++++++++++++++++++++++++++++++
tests/Feature/Mcp/ListCallsToolFeatureTest.php | 2 +-
tests/Feature/Mcp/McpTestHelpersTrait.php | 19 ++++++-
tests/Unit/Component/ES/ChunkSizeTest.php | 50 +++++++++++++++++
tests/Unit/Component/ES/Processor/DTOs/SelectionListTest.php | 27 +++++++---
tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 39 ++++++++------
tests/Unit/Component/MeetingBot/Service/ParticipantMatcherTest.php | 68 ++++++++++++++++++++++-
tests/Unit/Exceptions/RateLimitExceptionTest.php | 56 +++++++++++++++++++
tests/Unit/Jobs/Crm/MatchActivityCrmDataTest.php | 8 +--
tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++
tests/Unit/Services/Activity/HubSpot/ServiceTest.php | 109 +++++++++++++++++++++++++++++++++++++
tests/Unit/Services/Crm/Hubspot/ClientTest.php | 250 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/Unit/Services/Crm/Hubspot/Pagination/HubspotPaginationServiceTest.php | 283 +++++++++++++++++++++---------------------------------------------------------------------------
37 files changed, 1587 insertions(+), 344 deletions(-)
create mode 100644 app/Component/ES/ChunkSize.php
create mode 100644 app/Jobs/Middleware/HandleHubspotRateLimit.php
create mode 100644 app/Mcp/Tools/GetMeTool.php
create mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.php
create mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.php
create mode 100644 tests/Unit/Component/ES/ChunkSizeTest.php
create mode 100644 tests/Unit/Exceptions/RateLimitExceptionTest.php
create mode 100644 tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull
Already up to date.
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20676-delete-report-related-objects
Switched to a new branch 'JY-20676-delete-report-related-objects'
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20676-delete-report-related-objects) $ csfix
docker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff
PHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.
PHP runtime: 8.3.30
Running analysis on 7 cores with 10 files per process.
Parallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!
Loaded config default from ".php-cs-fixer.dist.php".
5690/5690 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
1) app/Console/Commands/JiminnyDebugCommand.php (statement_indentation, blank_line_before_statement)
---------- begin diff ----------
--- /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php
+++ /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php
@@ -23,6 +23,7 @@
if ($action === 'redis-set') {
$this->testRedisSet();
+
return;
}
@@ -45,7 +46,7 @@
$ttl = 60;
try {
-// $result = Redis::set($testKey, $testValue, 'EX', $ttl, 'NX');
+ // $result = Redis::set($testKey, $testValue, 'EX', $ttl, 'NX');
$result = Redis::set($testKey, $testValue, ['nx', 'ex' => $ttl]);
if ($result) {
----------- end diff -----------
Fixed 1 of 5690 files i...
|
[{"role":"AXTextArea","text [{"role":"AXTextArea","text":"Last login: Mon May 18 09:17:28 on ttys007\n\nPoetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parents\n\nPoetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parents\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ co master\nerror: Your local changes to the following files would be overwritten by checkout:\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tPIPEDRIVE_V2_MIGRATION_TICKETS.md\nPlease commit your changes or stash them before you switch branches.\nAborting\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ git pull\nremote: Enumerating objects: 1047, done.\nremote: Counting objects: 100% (832/832), done.\nremote: Compressing objects: 100% (298/298), done.\nremote: Total 1047 (delta 634), reused 596 (delta 534), pack-reused 215 (from 3)\nReceiving objects: 100% (1047/1047), 353.16 KiB | 1.56 MiB/s, done.\nResolving deltas: 100% (687/687), completed with 107 local objects.\nFrom github.com:jiminny/app\n 907c54896c..34656c53ed pipedrive-sdk-poc -> origin/pipedrive-sdk-poc\n 03325ec50f..4e7078fd8b JY-18091-upgrade-to-php-8-5 -> origin/JY-18091-upgrade-to-php-8-5\n e7d231e163..bc6a3fce6b JY-20725-handle-HS-search-rate-limit -> origin/JY-20725-handle-HS-search-rate-limit\n * [new branch] JY-20749-user-can-view-recorded-meetings -> origin/JY-20749-user-can-view-recorded-meetings\n 98ca281a04..e0351be069 JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue\n 569abb5149..3906a9238a JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details -> origin/JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details\n ad6c2a86e8..50eb6afba9 JY-20846-mcp-enable-the-ai-to-know-details-about-the-user -> origin/JY-20846-mcp-enable-the-ai-to-know-details-about-the-user\n * [new branch] JY-20893-chunk-control-per-update-target -> origin/JY-20893-chunk-control-per-update-target\n 31c62924a5..cb4ebf0c36 master -> origin/master\nUpdating 907c54896c..34656c53ed\nFast-forward\n PIPEDRIVE_V2_MIGRATION_TICKETS.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 52 insertions(+)\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ co master\nM\u0000\u0000\u0000\u0000\u0000\u0000\t.env.local\nM\u0000\u0000\u0000\u0000\u0000\u0000\tconfig/logging.php\nSwitched to branch 'master'\nYour branch is behind 'origin/master' by 31 commits, and can be fast-forwarded.\n (use \"git pull\" to update your local branch)\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull\nUpdating 31c62924a5..cb4ebf0c36\nFast-forward\n app/Component/ES/Processor/Traits/SelectEntityListTrait.php | 20 ------\n app/Services/Calendar/CalendarActivityService.php | 46 +++++++++++++\n app/Services/Calendar/Command/MapActivityData.php | 106 +++-------------------------\n docs/mcp/explorer/explorer.html | 104 +++++++++++++++++++++++++---\n docs/mcp/explorer/explorer.template.html | 102 ++++++++++++++++++++++++---\n docs/mcp/tools-list.json | 373 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------\n docs/mcp/tools.md | 117 +++++++++++++++++++++++--------\n tests/Unit/Component/ES/AsyncUpdateElasticSearchTest.php | 16 +----\n tests/Unit/Component/ES/Listeners/UpdateMultipleTargetsListenerTest.php | 10 ---\n tests/Unit/Component/ES/Listeners/UpdateSingleTargetListenerTest.php | 6 --\n tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 9 ---\n tests/Unit/Component/ES/Processor/Traits/SelectEntityListTraitTest.php | 15 ++--\n tests/Unit/Component/ES/UpdateProcessManagerTest.php | 2 -\n tests/Unit/Services/Calendar/CalendarActivityServiceTest.php | 150 ++++++++++++++++++++++++++++++++++++++--\n tests/Unit/Services/Calendar/Command/MapActivityDataTest.php | 78 ++-------------------\n 15 files changed, 832 insertions(+), 322 deletions(-)\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20613-allow-owner-role-on-team-setup\nSwitched to a new branch 'JY-20613-allow-owner-role-on-team-setup'\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ csfix\ndocker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff \nPHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.\nPHP runtime: 8.3.30\nRunning analysis on 7 cores with 10 files per process.\nParallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!\nLoaded config default from \".php-cs-fixer.dist.php\".\n 5682/5682 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%\n\n\nFixed 0 of 5682 files in 56.978 seconds, 67.00 MB memory used\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ ;xd\ndocker exec -it docker_lamp_1 bash -c \"mv /usr/local/etc/php/conf.d/xdebug.ini ~/xdebug.ini\"\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\ndocker exec -it docker_lamp_1 supervisorctl restart all\njiminny-worker-processing-2:jiminny-worker-processing-2_00: stopped\njiminny-worker-processing-3:jiminny-worker-processing-3_00: stopped\njiminny-worker-processing-4:jiminny-worker-processing-4_00: stopped\njiminny-worker-processing-5:jiminny-worker-processing-5_00: stopped\njiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00: stopped\nworker-analytics:worker-analytics_00: stopped\nworker-crm-update:worker-crm-update_00: stopped\nworker-download:worker-download_00: stopped\nworker-nudges:worker-nudges_00: stopped\nartisan-schedule:artisan-schedule_00: stopped\nworker-emails:worker-emails_00: stopped\nworker-calendar:worker-calendar_00: stopped\nworker:worker_00: stopped\nworker-conferences:worker-conferences_00: stopped\nworker-crm-sync:worker-crm-sync_00: stopped\njiminny-worker-processing-1:jiminny-worker-processing-1_00: stopped\nworker-audio:worker-audio_00: stopped\nworker-es-update:worker-es-update_00: stopped\nartisan-schedule:artisan-schedule_00: started\njiminny-worker-processing-1:jiminny-worker-processing-1_00: started\njiminny-worker-processing-2:jiminny-worker-processing-2_00: started\njiminny-worker-processing-3:jiminny-worker-processing-3_00: started\njiminny-worker-processing-4:jiminny-worker-processing-4_00: started\njiminny-worker-processing-5:jiminny-worker-processing-5_00: started\njiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00: started\nworker:worker_00: started\nworker-analytics:worker-analytics_00: started\nworker-audio:worker-audio_00: started\nworker-calendar:worker-calendar_00: started\nworker-conferences:worker-conferences_00: started\nworker-crm-sync:worker-crm-sync_00: started\nworker-crm-update:worker-crm-update_00: started\nworker-download:worker-download_00: started\nworker-emails:worker-emails_00: started\nworker-es-update:worker-es-update_00: started\nworker-nudges:worker-nudges_00: started\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\ndocker exec -it docker_lamp_1 php -v\nPHP 8.3.30 (cli) (built: Mar 16 2026 22:32:32) (NTS)\nCopyright (c) The PHP Group\nZend Engine v4.3.30, Copyright (c) Zend Technologies\n with Zend OPcache v8.3.30, Copyright (c), by Zend Technologies\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ csfix\ndocker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff \nPHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.\nPHP runtime: 8.3.30\nRunning analysis on 7 cores with 10 files per process.\nParallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!\nLoaded config default from \".php-cs-fixer.dist.php\".\n 5682/5682 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%\n\n\nFixed 0 of 5682 files in 49.910 seconds, 60.00 MB memory used\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git status\nOn branch JY-20613-allow-owner-role-on-team-setup\nYour branch is ahead of 'origin/JY-20613-allow-owner-role-on-team-setup' by 1 commit.\n (use \"git push\" to publish your local commits)\n\nChanges not staged for commit:\n (use \"git add <file>...\" to update what will be committed)\n (use \"git restore <file>...\" to discard changes in working directory)\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: .env.local\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: config/logging.php\n\nUntracked files:\n (use \"git add <file>...\" to include in what will be committed)\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\t.env.nikilocal\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\t.env.other\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tWEBHOOK_FILTERING_IMPLEMENTATION.md\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Console/Commands/Crm/Hubspot/SimulateWebhooksCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Console/Commands/Reports/CreateMockAskJiminnyReportResultCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tids.txt\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tpublic/favicon.ico\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\traw_sql_query.sql\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ttests/Unit/Policies/CanAccessAiReportsTest.php\n\nno changes added to commit (use \"git add\" and/or \"git commit -a\")\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git pull\nremote: Enumerating objects: 248, done.\nremote: Counting objects: 100% (128/128), done.\nremote: Compressing objects: 100% (23/23), done.\nremote: Total 59 (delta 43), reused 44 (delta 33), pack-reused 0 (from 0)\nUnpacking objects: 100% (59/59), 10.48 KiB | 228.00 KiB/s, done.\nFrom github.com:jiminny/app\n b7df560451..190239dfd4 JY-20613-allow-owner-role-on-team-setup -> origin/JY-20613-allow-owner-role-on-team-setup\n e0351be069..d94a285ae7 JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue\n * [new branch] JY-20920-fix-participant-matcher -> origin/JY-20920-fix-participant-matcher\n cb4ebf0c36..90bca4e4b2 master -> origin/master\nMerge made by the 'ort' strategy.\n app/Component/ES/ChunkSize.php | 54 +++++++++++++++++++++++++++\n app/Component/ES/Processor/DTOs/SelectionList.php | 4 +-\n app/Component/ES/Processor/TargetEntitiesSelector.php | 19 ++++++----\n app/Http/Middleware/McpTierMiddleware.php | 27 +++-----------\n app/Mcp/Servers/JiminnyServer.php | 2 +\n app/Mcp/Tools/GetMeTool.php | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n app/Models/Feature/FeatureEnum.php | 1 +\n database/migrations/2026_05_13_124153_create_mcp_feature_flag.php | 25 +++++++++++++\n front-end/src/components/Settings/Kiosk/modals/EditTeamModal/EditTeamModal.vue | 52 ++++++++++++++++++--------\n front-end/src/components/Settings/Kiosk/modals/EditTeamModal/__tests__/EditTeamModal.spec.js | 14 +++++++\n tests/Feature/Mcp/GetMeToolFeatureTest.php | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n tests/Feature/Mcp/ListCallsToolFeatureTest.php | 2 +-\n tests/Feature/Mcp/McpTestHelpersTrait.php | 19 +++++++++-\n tests/Unit/Component/ES/ChunkSizeTest.php | 50 +++++++++++++++++++++++++\n tests/Unit/Component/ES/Processor/DTOs/SelectionListTest.php | 27 ++++++++++----\n tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 39 +++++++++++---------\n 16 files changed, 557 insertions(+), 75 deletions(-)\n create mode 100644 app/Component/ES/ChunkSize.php\n create mode 100644 app/Mcp/Tools/GetMeTool.php\n create mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.php\n create mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.php\n create mode 100644 tests/Unit/Component/ES/ChunkSizeTest.php\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git push\nEnumerating objects: 40, done.\nCounting objects: 100% (34/34), done.\nDelta compression using up to 8 threads\nCompressing objects: 100% (18/18), done.\nWriting objects: 100% (18/18), 1.58 KiB | 1.58 MiB/s, done.\nTotal 18 (delta 15), reused 0 (delta 0), pack-reused 0\nremote: Resolving deltas: 100% (15/15), completed with 13 local objects.\nTo github.com:jiminny/app.git\n 190239dfd4..ec1b261264 JY-20613-allow-owner-role-on-team-setup -> JY-20613-allow-owner-role-on-team-setup\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ gbr\n* JY-20613-allow-owner-role-on-team-setup\n pipedrive-sdk-poc\n master\n JY-20903-update_activity-stage-on-opportunity-change\n JY-20904-fix-update-es-on-activity-command\n JY-20891-improve-sms-text-relays\n JY-20725-handle-HS-search-rate-limit\n JY-20818-move-AJ-reports-to-separated-datadog-metric\n JY-20773-fix-automated-reports-user-pilot-tracking\n JY-20157-AJ-report-not-send-notification\n JY-20508-notify-before-AJ-report-expiration\n JY-20372-ai-reports-promotion-pages\n JY-20352-sync-opportunities-without-a-local-owner-user-id-is-null\n JY-20738-debug-AJ-tracking-UP\n a\n JY-18909-automated-reports-ask-jiminny\n JY-20692-fix-integration-app-token-auth-response-change\n JY-20553-debug-crm-sync-delays\n JY-20698-fix-SF-activity-types-on-new-playbook\n JY-20543-AJ-report-tracking\n JY-20384-handle-auto-sync-with-no-access-to-event-type\n JY-20458-ask-jiminny-user-definitions\n JY-19666-fix-import-contacts-account-association\n JY-19666-HS-import-contacts-and-accounts-batch-job\n JY-20458-Ask-Jiminny-Reports\n JY-20200-batch-update-CRM-objects-Salesforce\n JY-19666-HS-webhooks-add-contact-and-company\n JY-20348-trigger-setup-DI-layout-on-team-creation\n JY-20326-refactor-info-message-in-command\n JY-20317-fix-auto-log-delay-issue-on-all-channels-disabled\n JY-20312-remove-on-update-change-last-synced-at-crm-configurations\n JY-20306-SF-skip-auto-sync-for-task-based-playbook\n JY-20192-remove-deleted-team-from-saved-search-filters\n JY-20197-import-opportunity-batch-job\n JY-20293-enable-status-field-for-pipedrive-deals\n JY-20191-remove-commands-interactive-prompts\n JY-20118-change-default-sync-strategy\n JY-20183-add-cache-on-auto-log-delay\n JY-20197-add-import-opportunity-batch-job\n 20118-hs-opportunity-make-webhook-strategy-default\n JY-20118-make-default-hs-opportunity-sync-strategy-webhook-based\n JY-20196-handle-opportunity-without-note\n JY-20118-improve-opportunity-import\n JY-20189-handle-activity-search-on-deleted-groups\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ co JY-20725-handle-HS-search-rate-limit\nM\u0000\u0000\u0000\u0000\u0000\u0000\t.env.local\nM\u0000\u0000\u0000\u0000\u0000\u0000\tconfig/logging.php\nSwitched to branch 'JY-20725-handle-HS-search-rate-limit'\nYour branch is behind 'origin/JY-20725-handle-HS-search-rate-limit' by 439 commits, and can be fast-forwarded.\n (use \"git pull\" to update your local branch)\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ git pull\nUpdating 0f3e438941..bc6a3fce6b\nFast-forward\n .gitignore | 3 +-\n .windsurfrules | 168 ++---\n CLAUDE.md | 1 +\n app/Component/ActivityAnalytics/Service/CalculateTalkTimeOffsetsFromTranscription.php | 24 +-\n app/Component/AiActivityType/Services/AiActivityTypeEligibilityChecker.php | 28 +-\n app/Component/AiAutomation/Actions/PrepareUpdateDtoAction.php | 32 +-\n app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.php | 47 ++\n app/Component/AiAutomation/TestCrmAiPromptService.php | 14 +\n app/Component/AiCallScoring/Services/AiCallScoringEligibilityChecker.php | 9 +\n app/Component/ES/ElasticSearchDocumentPartialUpdater.php | 13 +-\n app/Component/ES/ElasticSearchWorkerManager.php | 86 ---\n app/Component/ES/Processor/Actions/LoadDocumentsAction.php | 80 +--\n app/Component/ES/Processor/EntityQueryBuilder.php | 12 +-\n app/Component/ES/Processor/TargetEntitiesSelector.php | 2 +-\n app/Component/ES/Processor/Traits/SkipActivityTrait.php | 25 -\n app/Component/ES/Repositories/EsResetActivityRepository.php | 11 +-\n app/Component/ES/Worker/ActivityWorker.php | 73 --\n app/Component/ES/Worker/EntityWorker.php | 44 --\n app/Component/ES/Worker/WorkerAmount.php | 60 --\n app/Component/ES/Worker/WorkerInterface.php | 15 -\n app/Component/ElasticSearch/Contract/Searchable.php | 4 +\n app/Component/Encoding/Job/AnalyzeTrackChannelsJob.php | 20 +-\n app/Component/Encoding/Service/GenerateSpeechFromSilenceService.php | 85 ++-\n app/Component/FFMpeg/Services/GetSpeechIntervalsService.php | 18 +-\n app/Component/LanguageDetection/Services/FindSpeechTimeService.php | 22 +-\n app/Component/Nudge/Job/ProcessOrganisationImmediateNudgesJob.php | 218 +++++-\n app/Component/ParagraphBreaker/Services/TranscriptionParagraphsService.php | 4 +\n app/Component/ParticipantSpeech/Services/ParticipantSpeechesCreator.php | 33 +\n app/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleter.php | 15 +\n app/Component/ParticipantSpeech/Services/ParticipantSpeechesProvider.php | 51 +-\n app/Component/ParticipantSpeech/Services/ParticipantSpeechesUploader.php | 36 +\n app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.php | 11 +\n app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/NoAssemblyIdException.php | 11 +\n app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/SuccessfulResponse.php | 6 +\n app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNotCorrectFormatException.php | 11 +\n app/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeechesService.php | 23 +-\n app/Component/Transcription/Diarization/Source/MeetingBotSource.php | 16 +-\n app/Component/Transcription/TranscriptionProcessor/TranscriptionProcessor.php | 3 +\n app/Console/Commands/Activities/ActivityHardDeleteCommand.php | 4 +-\n app/Console/Commands/Activities/Copy.php | 2 +\n app/Console/Commands/Activities/SetupIntegration/TwilioSetS3RecordingCredentialsCommand.php | 119 ++++\n app/Console/Commands/Activities/UpdateActivityElasticSearchDocumentCommand.php | 10 +-\n app/Console/Commands/Crm/BackfillOpportunityUserFromAccountCommand.php | 126 ++++\n app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.php | 19 -\n app/Console/Commands/Elasticsearch/AsyncUpdateEsEntities.php | 50 +-\n app/Console/Commands/Elasticsearch/ResetAsyncElasticSearchCommand.php | 30 +-\n app/Console/Commands/GeckoExport/GeckoExportParticipantSpeechesCommand.php | 14 +-\n app/Console/Commands/IssueMcpTokenCommand.php | 84 +++\n app/Console/Commands/JiminnyDebugCommand.php | 7 +-\n app/Console/Commands/Tracks/CleanupActivityTracksCommand.php | 2 +-\n app/Console/Kernel.php | 6 +-\n app/Contracts/Services/Calendar/CalendarTrait.php | 80 ++-\n app/Events/AutomatedReports/AutomatedReportGenerated.php | 3 +\n app/Http/Controllers/API/AiCallScoring/AiScorecardController.php | 7 +-\n app/Http/Controllers/API/TeamAiAutomationController.php | 8 +\n app/Http/Controllers/CustomerApi/CustomerApiController.php | 4 +-\n app/Http/Controllers/Kiosk/ActivityController.php | 58 +-\n app/Http/Controllers/Settings/PlaybookController.php | 15 +-\n app/Http/Kernel.php | 23 +\n app/Http/Middleware/McpAuditMiddleware.php | 156 ++++\n app/Http/Middleware/McpTierMiddleware.php | 54 ++\n app/Http/Requests/API/V2/ZapierUploadActivityRequest.php | 28 +-\n app/Jobs/Activity/Import/ImportTwilioVideoSpeechesJob.php | 25 +-\n app/Jobs/Activity/Import/IsActivityReadyForProcessingJob.php | 10 +-\n app/Jobs/Calendar/SetupCalendarSync.php | 21 +-\n app/Jobs/ImportRemoteTrackJob.php | 96 ++-\n app/Jobs/Mailbox/EmailTextRelay.php | 15 +-\n app/Mcp/Contracts/McpCallRepositoryInterface.php | 30 +\n app/Mcp/DTO/ListCallsFilters.php | 29 +\n app/Mcp/Errors/McpError.php | 123 ++++\n app/Mcp/Repositories/McpActivityHydrator.php | 145 ++++\n app/Mcp/Repositories/McpCallRepository.php | 84 +++\n app/Mcp/Repositories/McpElasticCallRepository.php | 171 +++++\n app/Mcp/Servers/JiminnyServer.php | 38 +\n app/Mcp/Tools/ListCallsTool.php | 205 ++++++\n app/Models/Activity.php | 10 +-\n app/Models/Activity/Transcription.php | 17 +-\n app/Models/ElasticSearch/OpportunityElasticSearchTrait.php | 5 +\n app/Models/Participant.php | 1 +\n app/Providers/AppServiceProvider.php | 22 +\n app/Repositories/Crm/ContactRepository.php | 69 +-\n app/Repositories/ParticipantSpeechRepository.php | 13 +-\n app/Services/Activity/ParticipantsService.php | 19 +-\n app/Services/Activity/Twilio/S3RecordingCredentialsService.php | 82 +++\n app/Services/ActivityService.php | 21 +-\n app/Services/Calendar/CalendarActivityService.php | 46 ++\n app/Services/Calendar/Command/ImportParticipants.php | 1 +\n app/Services/Calendar/Command/MapActivityData.php | 106 +--\n app/Services/Calendar/GoogleCalendarService.php | 12 +-\n app/Services/Crm/Close/Processor/OpportunityProcessor.php | 2 +-\n app/Services/Crm/Close/Service.php | 22 +-\n app/Services/Crm/Copper/Service.php | 12 +-\n app/Services/Crm/Hubspot/Service.php | 154 +++-\n app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php | 88 ++-\n app/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTrait.php | 22 +-\n app/Services/Crm/Pipedrive/Service.php | 17 +-\n app/Services/Crm/Salesforce/Service.php | 42 +-\n app/Services/Mail/Office/EmailApiClient.php | 129 +---\n app/Services/RecallAI/Commands/ScheduleBotCommand.php | 39 +-\n app/Services/RecallAI/RecallAIService.php | 22 +-\n composer.json | 3 +-\n composer.lock | 87 ++-\n config/mcp.php | 23 +\n database/migrations/2026_04_30_120000_create_mcp_audit_log_table.php | 36 +\n docs/mcp/explorer/explorer.html | 697 ++++++++++++++++++\n docs/mcp/explorer/explorer.template.html | 697 ++++++++++++++++++\n docs/mcp/explorer/generate.js | 215 ++++++\n docs/mcp/explorer/tool-explorer-meta.json | 11 +\n docs/mcp/tools-list.json | 2536 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n docs/mcp/tools.md | 621 ++++++++++++++++\n front-end/package.json | 4 +-\n front-end/src/components/Settings/OrgSettings/AiAutomation/CrmFilling/TemplateFieldForm.vue | 28 +-\n front-end/src/components/Settings/OrgSettings/Playbooks/AddEditPlaybook.vue | 10 +\n front-end/src/components/playback/comments/ActivityComment.less | 10 +-\n front-end/src/components/shared/PromptTester/PromptTester.vue | 12 +-\n front-end/src/components/shared/__tests__/PromptTester.spec.js | 35 +\n front-end/src/components/shared/modals/EntityPickerModal/__tests__/useEntitiesCache.spec.ts | 37 +\n front-end/src/components/shared/modals/EntityPickerModal/useEntitiesCache.ts | 9 +\n front-end/yarn.lock | 16 +-\n phpstan-baseline.neon | 50 --\n routes/api.php | 11 +\n sonar-project.properties | 91 ++-\n tests/Feature/Component/Nudge/ProcessOrganisationImmediateNudgesJobTest.php | 534 ++++++++++++++\n tests/Feature/Jobs/ImportRemoteTrackJobTest.php | 283 +++++++-\n tests/Feature/Mcp/IssueMcpTokenCommandTest.php | 53 ++\n tests/Feature/Mcp/ListCallsToolElasticFeatureTest.php | 155 ++++\n tests/Feature/Mcp/ListCallsToolFeatureTest.php | 352 ++++++++++\n tests/Feature/Mcp/McpTestHelpersTrait.php | 77 ++\n tests/Feature/Services/Team/TeamDeleteHandlers/Retention/RetentionRepositoryHandlerTest.php | 1 +\n tests/Stubs/SentryStub.php | 18 +\n tests/Unit/Component/ActivityAnalytics/Service/CalculateTalkTimeOffsetFromTranscriptionTest.php | 28 +-\n tests/Unit/Component/AiActivityType/Services/AiActivityTypeEligibilityCheckerTest.php | 103 ++-\n tests/Unit/Component/AiAutomation/Actions/PrepareUpdateDtoActionTest.php | 91 +++\n tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheckerTest.php | 124 ++++\n tests/Unit/Component/AiAutomation/TestCrmAiPromptServiceTest.php | 67 +-\n tests/Unit/Component/AiCallScoring/Services/AiCallScoringEligibilityCheckerTest.php | 55 ++\n tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.php | 135 ----\n tests/Unit/Component/ES/Processor/Actions/LoadDocumentsActionTest.php | 220 ++++++\n tests/Unit/Component/ES/Processor/EntityQueryBuilderTest.php | 21 +-\n tests/Unit/Component/ES/Processor/Traits/SkipActivityTraitTest.php | 51 --\n tests/Unit/Component/ES/Worker/ActivityWorkerTest.php | 174 -----\n tests/Unit/Component/ES/Worker/EntityWorkerTest.php | 97 ---\n tests/Unit/Component/ES/Worker/WorkerAmountTest.php | 116 ---\n tests/Unit/Component/Encoding/Job/AnalyzeTrackChannelsJobTest.php | 52 +-\n tests/Unit/Component/Encoding/Service/GenerateSpeechFromSilenceServiceTest.php | 171 ++---\n tests/Unit/Component/FFMpeg/Services/GetSpeechIntervalsTest.php | 36 +-\n tests/Unit/Component/LanguageDetection/Services/FindSpeechTimeServiceTest.php | 20 +-\n tests/Unit/Component/MobileSettings/MobileSettingsControllerTest.php | 5 +-\n tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCreatorTest.php | 75 ++\n tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleterTest.php | 63 ++\n tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesProviderTest.php | 134 ++++\n tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesUploaderTest.php | 57 ++\n tests/Unit/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeechesServiceTest.php | 51 +-\n tests/Unit/Component/Transcription/Diarization/Source/MeetingBotSourceTest.php | 29 +-\n tests/Unit/Contracts/Services/Calendar/CalendarTraitTest.php | 58 +-\n tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.php | 159 +++++\n tests/Unit/Jobs/Activity/Import/ImportTwilioVideoSpeechesJobTest.php | 22 +-\n tests/Unit/Jobs/Activity/Import/IsActivityReadyForProcessingJobTest.php | 26 +-\n tests/Unit/Jobs/Calendar/SetupCalendarSyncTest.php | 25 -\n tests/Unit/Services/Activity/ParticipantsServiceTest.php | 12 +-\n tests/Unit/Services/Activity/Twilio/S3RecordingCredentialsServiceTest.php | 180 +++++\n tests/Unit/Services/ActivityServiceTest.php | 132 ++++\n tests/Unit/Services/Calendar/CalendarActivityServiceTest.php | 150 +++-\n tests/Unit/Services/Calendar/Command/ImportParticipantsTest.php | 6 +-\n tests/Unit/Services/Calendar/Command/MapActivityDataTest.php | 78 +-\n tests/Unit/Services/Calendar/GoogleCalendarServiceTest.php | 116 +++\n tests/Unit/Services/Crm/Close/ServiceTest.php | 165 +++++\n tests/Unit/Services/Crm/Hubspot/ServiceTest.php | 272 ++++++-\n tests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTest.php | 25 +-\n tests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTraitMatchActivitiesTest.php | 3 +-\n tests/Unit/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTraitOpportunitiesTest.php | 40 ++\n tests/Unit/Services/Crm/Pipedrive/ImportOpportunityMatchActivitiesTest.php | 2 +\n tests/Unit/Services/Crm/Salesforce/ServiceTest.php | 139 ++++\n tests/Unit/Services/Mail/Office/EmailApiClientTest.php | 195 ++---\n tests/Unit/Services/RecallAI/RecallAIServiceTest.php | 24 +-\n 175 files changed, 12562 insertions(+), 2162 deletions(-)\n create mode 120000 CLAUDE.md\n create mode 100644 app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.php\n delete mode 100644 app/Component/ES/ElasticSearchWorkerManager.php\n delete mode 100644 app/Component/ES/Processor/Traits/SkipActivityTrait.php\n delete mode 100644 app/Component/ES/Worker/ActivityWorker.php\n delete mode 100644 app/Component/ES/Worker/EntityWorker.php\n delete mode 100644 app/Component/ES/Worker/WorkerAmount.php\n delete mode 100644 app/Component/ES/Worker/WorkerInterface.php\n create mode 100644 app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.php\n create mode 100644 app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/NoAssemblyIdException.php\n create mode 100644 app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNotCorrectFormatException.php\n create mode 100644 app/Console/Commands/Activities/SetupIntegration/TwilioSetS3RecordingCredentialsCommand.php\n create mode 100644 app/Console/Commands/Crm/BackfillOpportunityUserFromAccountCommand.php\n delete mode 100644 app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.php\n create mode 100644 app/Console/Commands/IssueMcpTokenCommand.php\n create mode 100644 app/Http/Middleware/McpAuditMiddleware.php\n create mode 100644 app/Http/Middleware/McpTierMiddleware.php\n create mode 100644 app/Mcp/Contracts/McpCallRepositoryInterface.php\n create mode 100644 app/Mcp/DTO/ListCallsFilters.php\n create mode 100644 app/Mcp/Errors/McpError.php\n create mode 100644 app/Mcp/Repositories/McpActivityHydrator.php\n create mode 100644 app/Mcp/Repositories/McpCallRepository.php\n create mode 100644 app/Mcp/Repositories/McpElasticCallRepository.php\n create mode 100644 app/Mcp/Servers/JiminnyServer.php\n create mode 100644 app/Mcp/Tools/ListCallsTool.php\n create mode 100644 app/Services/Activity/Twilio/S3RecordingCredentialsService.php\n create mode 100644 config/mcp.php\n create mode 100644 database/migrations/2026_04_30_120000_create_mcp_audit_log_table.php\n create mode 100644 docs/mcp/explorer/explorer.html\n create mode 100644 docs/mcp/explorer/explorer.template.html\n create mode 100644 docs/mcp/explorer/generate.js\n create mode 100644 docs/mcp/explorer/tool-explorer-meta.json\n create mode 100644 docs/mcp/tools-list.json\n create mode 100644 docs/mcp/tools.md\n create mode 100644 front-end/src/components/shared/modals/EntityPickerModal/__tests__/useEntitiesCache.spec.ts\n create mode 100644 tests/Feature/Component/Nudge/ProcessOrganisationImmediateNudgesJobTest.php\n create mode 100644 tests/Feature/Mcp/IssueMcpTokenCommandTest.php\n create mode 100644 tests/Feature/Mcp/ListCallsToolElasticFeatureTest.php\n create mode 100644 tests/Feature/Mcp/ListCallsToolFeatureTest.php\n create mode 100644 tests/Feature/Mcp/McpTestHelpersTrait.php\n create mode 100644 tests/Stubs/SentryStub.php\n create mode 100644 tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheckerTest.php\n delete mode 100644 tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.php\n create mode 100644 tests/Unit/Component/ES/Processor/Actions/LoadDocumentsActionTest.php\n delete mode 100644 tests/Unit/Component/ES/Processor/Traits/SkipActivityTraitTest.php\n delete mode 100644 tests/Unit/Component/ES/Worker/ActivityWorkerTest.php\n delete mode 100644 tests/Unit/Component/ES/Worker/EntityWorkerTest.php\n delete mode 100644 tests/Unit/Component/ES/Worker/WorkerAmountTest.php\n create mode 100644 tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCreatorTest.php\n create mode 100644 tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.php\n create mode 100644 tests/Unit/Services/Activity/Twilio/S3RecordingCredentialsServiceTest.php\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ git status\nOn branch master\nYour branch is behind 'origin/master' by 114 commits, and can be fast-forwarded.\n (use \"git pull\" to update your local branch)\n\nChanges not staged for commit:\n (use \"git add <file>...\" to update what will be committed)\n (use \"git restore <file>...\" to discard changes in working directory)\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: .env.local\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Component/SCIM/Constants.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Component/SCIM/ScimProvisioning.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Component/Twilio/Conference/ConferenceManager/SoftPhoneManager.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Console/Commands/JiminnyDebugCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/DTO/SCIM/AAD/Request/CoreUserRequest.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/DTO/SCIM/AAD/Response/CoreUser.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Services/Telephony/TextMessagingService.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: config/logging.php\n\nUntracked files:\n (use \"git add <file>...\" to include in what will be committed)\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\t.env.nikilocal\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\t.env.other\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tWEBHOOK_FILTERING_IMPLEMENTATION.md\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Component/SCIM/Mutators/Attributes/User/RoleAttr.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Console/Commands/Crm/Hubspot/SimulateWebhooksCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Console/Commands/Reports/CreateMockAskJiminnyReportResultCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Rules/ListenerRoleCannotHaveAdminOrManagerPermissionRule.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tids.txt\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tpublic/favicon.ico\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\traw_sql_query.sql\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ttests/Unit/Component/SCIM/Mutators/Attributes/User/RoleAttrTest.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ttests/Unit/Policies/CanAccessAiReportsTest.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ttests/Unit/Rules/ListenerRoleCannotHaveAdminOrManagerPermissionRuleTest.php\n\nno changes added to commit (use \"git add\" and/or \"git commit -a\")\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull\nremote: Enumerating objects: 306, done.\nremote: Counting objects: 100% (299/299), done.\nremote: Compressing objects: 100% (183/183), done.\nremote: Total 306 (delta 213), reused 171 (delta 116), pack-reused 7 (from 1)\nReceiving objects: 100% (306/306), 80.12 KiB | 1000.00 KiB/s, done.\nResolving deltas: 100% (213/213), completed with 53 local objects.\nFrom github.com:jiminny/app\n 90bca4e4b2..5604af40cf master -> origin/master\n 4e7078fd8b..0b8343d179 JY-18091-upgrade-to-php-8-5 -> origin/JY-18091-upgrade-to-php-8-5\n 098eeaa087..d5a447e492 JY-20613-allow-owner-role-on-team-setup -> origin/JY-20613-allow-owner-role-on-team-setup\n c3a76ace91..af65249d0f JY-20749-user-can-view-recorded-meetings -> origin/JY-20749-user-can-view-recorded-meetings\n d94a285ae7..7ce96cb5fe JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue\n * [new branch] JY-20842-remove-partial-updater -> origin/JY-20842-remove-partial-updater\n * [new branch] JY-20920-fix-participant-flip -> origin/JY-20920-fix-participant-flip\n * [new branch] secfix/npm-20260519 -> origin/secfix/npm-20260519\nUpdating cb4ebf0c36..5604af40cf\nFast-forward\n app/Component/ES/ChunkSize.php | 54 +++++++++++++++++++\n app/Component/ES/Processor/DTOs/SelectionList.php | 4 +-\n app/Component/ES/Processor/TargetEntitiesSelector.php | 19 ++++---\n app/Component/MeetingBot/Service/ParticipantMatcher.php | 46 ++++++++++++----\n app/Exceptions/RateLimitException.php | 19 ++++++-\n app/Http/Middleware/McpTierMiddleware.php | 27 ++--------\n app/Jobs/Crm/MatchActivityCrmData.php | 47 ++++++++++++----\n app/Jobs/Middleware/HandleHubspotRateLimit.php | 42 +++++++++++++++\n app/Mcp/Servers/JiminnyServer.php | 2 +\n app/Mcp/Tools/GetMeTool.php | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++\n app/Models/Feature/FeatureEnum.php | 1 +\n app/Services/Activity/HubSpot/ProviderResolver.php | 4 +-\n app/Services/Activity/HubSpot/ProviderResolverInterface.php | 2 +-\n app/Services/Activity/HubSpot/Providers/Provider.php | 2 +-\n app/Services/Activity/HubSpot/Providers/ProviderKixie.php | 2 +-\n app/Services/Activity/HubSpot/Providers/ProviderOrum.php | 2 +-\n app/Services/Activity/HubSpot/Providers/ProviderTwilio.php | 2 +-\n app/Services/Activity/HubSpot/Providers/ProviderTwilioFlex.php | 5 +-\n app/Services/Activity/HubSpot/Service.php | 97 +++++++++++++++++++++++++++------\n app/Services/Crm/Hubspot/Client.php | 132 +++++++++++++++++++++++++++++++++++++++++++++\n app/Services/Crm/Hubspot/HubspotClientInterface.php | 15 ++++++\n app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php | 21 ++++----\n app/Services/Crm/Hubspot/Pagination/PaginationState.php | 2 +-\n database/migrations/2026_05_13_124153_create_mcp_feature_flag.php | 25 +++++++++\n tests/Feature/Mcp/GetMeToolFeatureTest.php | 140 +++++++++++++++++++++++++++++++++++++++++++++++\n tests/Feature/Mcp/ListCallsToolFeatureTest.php | 2 +-\n tests/Feature/Mcp/McpTestHelpersTrait.php | 19 ++++++-\n tests/Unit/Component/ES/ChunkSizeTest.php | 50 +++++++++++++++++\n tests/Unit/Component/ES/Processor/DTOs/SelectionListTest.php | 27 +++++++---\n tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 39 ++++++++------\n tests/Unit/Component/MeetingBot/Service/ParticipantMatcherTest.php | 68 ++++++++++++++++++++++-\n tests/Unit/Exceptions/RateLimitExceptionTest.php | 56 +++++++++++++++++++\n tests/Unit/Jobs/Crm/MatchActivityCrmDataTest.php | 8 +--\n tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++\n tests/Unit/Services/Activity/HubSpot/ServiceTest.php | 109 +++++++++++++++++++++++++++++++++++++\n tests/Unit/Services/Crm/Hubspot/ClientTest.php | 250 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n tests/Unit/Services/Crm/Hubspot/Pagination/HubspotPaginationServiceTest.php | 283 +++++++++++++++++++++---------------------------------------------------------------------------\n 37 files changed, 1587 insertions(+), 344 deletions(-)\n create mode 100644 app/Component/ES/ChunkSize.php\n create mode 100644 app/Jobs/Middleware/HandleHubspotRateLimit.php\n create mode 100644 app/Mcp/Tools/GetMeTool.php\n create mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.php\n create mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.php\n create mode 100644 tests/Unit/Component/ES/ChunkSizeTest.php\n create mode 100644 tests/Unit/Exceptions/RateLimitExceptionTest.php\n create mode 100644 tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull\nAlready up to date.\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20676-delete-report-related-objects\nSwitched to a new branch 'JY-20676-delete-report-related-objects'\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20676-delete-report-related-objects) $ csfix\ndocker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff \nPHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.\nPHP runtime: 8.3.30\nRunning analysis on 7 cores with 10 files per process.\nParallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!\nLoaded config default from \".php-cs-fixer.dist.php\".\n 5690/5690 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%\n\n 1) app/Console/Commands/JiminnyDebugCommand.php (statement_indentation, blank_line_before_statement)\n ---------- begin diff ----------\n--- /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php\n+++ /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php\n@@ -23,6 +23,7 @@\n \n if ($action === 'redis-set') {\n $this->testRedisSet();\n+\n return;\n }\n \n@@ -45,7 +46,7 @@\n $ttl = 60;\n \n try {\n-// $result = Redis::set($testKey, $testValue, 'EX', $ttl, 'NX');\n+ // $result = Redis::set($testKey, $testValue, 'EX', $ttl, 'NX');\n $result = Redis::set($testKey, $testValue, ['nx', 'ex' => $ttl]);\n \n if ($result) {\n\n ----------- end diff -----------\n\n\nFixed 1 of 5690 files in 50.673 seconds, 67.00 MB memory used\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20676-delete-report-related-objects) $ ;xd\ndocker exec -it docker_lamp_1 bash -c \"mv /usr/local/etc/php/conf.d/xdebug.ini ~/xdebug.ini\"\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\ndocker exec -it docker_lamp_1 supervisorctl restart all\njiminny-worker-processing-2:jiminny-worker-processing-2_00: stopped\njiminny-worker-processing-3:jiminny-worker-processing-3_00: stopped\njiminny-worker-processing-4:jiminny-worker-processing-4_00: stopped\njiminny-worker-processing-5:jiminny-worker-processing-5_00: stopped\njiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00: stopped\nworker-analytics:worker-analytics_00: stopped\nworker-crm-update:worker-crm-update_00: stopped\nworker-download:worker-download_00: stopped\nworker-nudges:worker-nudges_00: stopped\nworker-calendar:worker-calendar_00: stopped\nworker-audio:worker-audio_00: stopped\njiminny-worker-processing-1:jiminny-worker-processing-1_00: stopped\nworker:worker_00: stopped\nworker-conferences:worker-conferences_00: stopped\nworker-crm-sync:worker-crm-sync_00: stopped\nworker-emails:worker-emails_00: stopped\nworker-es-update:worker-es-update_00: stopped\nartisan-schedule:artisan-schedule_00: stopped\nartisan-schedule:artisan-schedule_00: started\njiminny-worker-processing-1:jiminny-worker-processing-1_00: started\njiminny-worker-processing-2:jiminny-worker-processing-2_00: started\njiminny-worker-processing-3:jiminny-worker-processing-3_00: started\njiminny-worker-processing-4:jiminny-worker-processing-4_00: started\njiminny-worker-processing-5:jiminny-worker-processing-5_00: started\njiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00: started\nworker:worker_00: started\nworker-analytics:worker-analytics_00: started\nworker-audio:worker-audio_00: started\nworker-calendar:worker-calendar_00: started\nworker-conferences:worker-conferences_00: started\nworker-crm-sync:worker-crm-sync_00: started\nworker-crm-update:worker-crm-update_00: started\nworker-download:worker-download_00: started\nworker-emails:worker-emails_00: started\nworker-es-update:worker-es-update_00: started\nworker-nudges:worker-nudges_00: started\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\ndocker exec -it docker_lamp_1 php -v\nPHP 8.3.30 (cli) (built: Mar 16 2026 22:32:32) (NTS)\nCopyright (c) The PHP Group\nZend Engine v4.3.30, Copyright (c) Zend Technologies\n with Zend OPcache v8.3.30, Copyright (c), by Zend Technologies\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20676-delete-report-related-objects) $ git status","depth":4,"on_screen":true,"value":"Last login: Mon May 18 09:17:28 on ttys007\n\nPoetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parents\n\nPoetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parents\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ co master\nerror: Your local changes to the following files would be overwritten by checkout:\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tPIPEDRIVE_V2_MIGRATION_TICKETS.md\nPlease commit your changes or stash them before you switch branches.\nAborting\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ git pull\nremote: Enumerating objects: 1047, done.\nremote: Counting objects: 100% (832/832), done.\nremote: Compressing objects: 100% (298/298), done.\nremote: Total 1047 (delta 634), reused 596 (delta 534), pack-reused 215 (from 3)\nReceiving objects: 100% (1047/1047), 353.16 KiB | 1.56 MiB/s, done.\nResolving deltas: 100% (687/687), completed with 107 local objects.\nFrom github.com:jiminny/app\n 907c54896c..34656c53ed pipedrive-sdk-poc -> origin/pipedrive-sdk-poc\n 03325ec50f..4e7078fd8b JY-18091-upgrade-to-php-8-5 -> origin/JY-18091-upgrade-to-php-8-5\n e7d231e163..bc6a3fce6b JY-20725-handle-HS-search-rate-limit -> origin/JY-20725-handle-HS-search-rate-limit\n * [new branch] JY-20749-user-can-view-recorded-meetings -> origin/JY-20749-user-can-view-recorded-meetings\n 98ca281a04..e0351be069 JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue\n 569abb5149..3906a9238a JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details -> origin/JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details\n ad6c2a86e8..50eb6afba9 JY-20846-mcp-enable-the-ai-to-know-details-about-the-user -> origin/JY-20846-mcp-enable-the-ai-to-know-details-about-the-user\n * [new branch] JY-20893-chunk-control-per-update-target -> origin/JY-20893-chunk-control-per-update-target\n 31c62924a5..cb4ebf0c36 master -> origin/master\nUpdating 907c54896c..34656c53ed\nFast-forward\n PIPEDRIVE_V2_MIGRATION_TICKETS.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 52 insertions(+)\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ co master\nM\u0000\u0000\u0000\u0000\u0000\u0000\t.env.local\nM\u0000\u0000\u0000\u0000\u0000\u0000\tconfig/logging.php\nSwitched to branch 'master'\nYour branch is behind 'origin/master' by 31 commits, and can be fast-forwarded.\n (use \"git pull\" to update your local branch)\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull\nUpdating 31c62924a5..cb4ebf0c36\nFast-forward\n app/Component/ES/Processor/Traits/SelectEntityListTrait.php | 20 ------\n app/Services/Calendar/CalendarActivityService.php | 46 +++++++++++++\n app/Services/Calendar/Command/MapActivityData.php | 106 +++-------------------------\n docs/mcp/explorer/explorer.html | 104 +++++++++++++++++++++++++---\n docs/mcp/explorer/explorer.template.html | 102 ++++++++++++++++++++++++---\n docs/mcp/tools-list.json | 373 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------\n docs/mcp/tools.md | 117 +++++++++++++++++++++++--------\n tests/Unit/Component/ES/AsyncUpdateElasticSearchTest.php | 16 +----\n tests/Unit/Component/ES/Listeners/UpdateMultipleTargetsListenerTest.php | 10 ---\n tests/Unit/Component/ES/Listeners/UpdateSingleTargetListenerTest.php | 6 --\n tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 9 ---\n tests/Unit/Component/ES/Processor/Traits/SelectEntityListTraitTest.php | 15 ++--\n tests/Unit/Component/ES/UpdateProcessManagerTest.php | 2 -\n tests/Unit/Services/Calendar/CalendarActivityServiceTest.php | 150 ++++++++++++++++++++++++++++++++++++++--\n tests/Unit/Services/Calendar/Command/MapActivityDataTest.php | 78 ++-------------------\n 15 files changed, 832 insertions(+), 322 deletions(-)\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20613-allow-owner-role-on-team-setup\nSwitched to a new branch 'JY-20613-allow-owner-role-on-team-setup'\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ csfix\ndocker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff \nPHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.\nPHP runtime: 8.3.30\nRunning analysis on 7 cores with 10 files per process.\nParallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!\nLoaded config default from \".php-cs-fixer.dist.php\".\n 5682/5682 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%\n\n\nFixed 0 of 5682 files in 56.978 seconds, 67.00 MB memory used\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ ;xd\ndocker exec -it docker_lamp_1 bash -c \"mv /usr/local/etc/php/conf.d/xdebug.ini ~/xdebug.ini\"\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\ndocker exec -it docker_lamp_1 supervisorctl restart all\njiminny-worker-processing-2:jiminny-worker-processing-2_00: stopped\njiminny-worker-processing-3:jiminny-worker-processing-3_00: stopped\njiminny-worker-processing-4:jiminny-worker-processing-4_00: stopped\njiminny-worker-processing-5:jiminny-worker-processing-5_00: stopped\njiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00: stopped\nworker-analytics:worker-analytics_00: stopped\nworker-crm-update:worker-crm-update_00: stopped\nworker-download:worker-download_00: stopped\nworker-nudges:worker-nudges_00: stopped\nartisan-schedule:artisan-schedule_00: stopped\nworker-emails:worker-emails_00: stopped\nworker-calendar:worker-calendar_00: stopped\nworker:worker_00: stopped\nworker-conferences:worker-conferences_00: stopped\nworker-crm-sync:worker-crm-sync_00: stopped\njiminny-worker-processing-1:jiminny-worker-processing-1_00: stopped\nworker-audio:worker-audio_00: stopped\nworker-es-update:worker-es-update_00: stopped\nartisan-schedule:artisan-schedule_00: started\njiminny-worker-processing-1:jiminny-worker-processing-1_00: started\njiminny-worker-processing-2:jiminny-worker-processing-2_00: started\njiminny-worker-processing-3:jiminny-worker-processing-3_00: started\njiminny-worker-processing-4:jiminny-worker-processing-4_00: started\njiminny-worker-processing-5:jiminny-worker-processing-5_00: started\njiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00: started\nworker:worker_00: started\nworker-analytics:worker-analytics_00: started\nworker-audio:worker-audio_00: started\nworker-calendar:worker-calendar_00: started\nworker-conferences:worker-conferences_00: started\nworker-crm-sync:worker-crm-sync_00: started\nworker-crm-update:worker-crm-update_00: started\nworker-download:worker-download_00: started\nworker-emails:worker-emails_00: started\nworker-es-update:worker-es-update_00: started\nworker-nudges:worker-nudges_00: started\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\ndocker exec -it docker_lamp_1 php -v\nPHP 8.3.30 (cli) (built: Mar 16 2026 22:32:32) (NTS)\nCopyright (c) The PHP Group\nZend Engine v4.3.30, Copyright (c) Zend Technologies\n with Zend OPcache v8.3.30, Copyright (c), by Zend Technologies\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ csfix\ndocker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff \nPHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.\nPHP runtime: 8.3.30\nRunning analysis on 7 cores with 10 files per process.\nParallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!\nLoaded config default from \".php-cs-fixer.dist.php\".\n 5682/5682 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%\n\n\nFixed 0 of 5682 files in 49.910 seconds, 60.00 MB memory used\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git status\nOn branch JY-20613-allow-owner-role-on-team-setup\nYour branch is ahead of 'origin/JY-20613-allow-owner-role-on-team-setup' by 1 commit.\n (use \"git push\" to publish your local commits)\n\nChanges not staged for commit:\n (use \"git add <file>...\" to update what will be committed)\n (use \"git restore <file>...\" to discard changes in working directory)\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: .env.local\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: config/logging.php\n\nUntracked files:\n (use \"git add <file>...\" to include in what will be committed)\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\t.env.nikilocal\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\t.env.other\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tWEBHOOK_FILTERING_IMPLEMENTATION.md\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Console/Commands/Crm/Hubspot/SimulateWebhooksCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Console/Commands/Reports/CreateMockAskJiminnyReportResultCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tids.txt\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tpublic/favicon.ico\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\traw_sql_query.sql\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ttests/Unit/Policies/CanAccessAiReportsTest.php\n\nno changes added to commit (use \"git add\" and/or \"git commit -a\")\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git pull\nremote: Enumerating objects: 248, done.\nremote: Counting objects: 100% (128/128), done.\nremote: Compressing objects: 100% (23/23), done.\nremote: Total 59 (delta 43), reused 44 (delta 33), pack-reused 0 (from 0)\nUnpacking objects: 100% (59/59), 10.48 KiB | 228.00 KiB/s, done.\nFrom github.com:jiminny/app\n b7df560451..190239dfd4 JY-20613-allow-owner-role-on-team-setup -> origin/JY-20613-allow-owner-role-on-team-setup\n e0351be069..d94a285ae7 JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue\n * [new branch] JY-20920-fix-participant-matcher -> origin/JY-20920-fix-participant-matcher\n cb4ebf0c36..90bca4e4b2 master -> origin/master\nMerge made by the 'ort' strategy.\n app/Component/ES/ChunkSize.php | 54 +++++++++++++++++++++++++++\n app/Component/ES/Processor/DTOs/SelectionList.php | 4 +-\n app/Component/ES/Processor/TargetEntitiesSelector.php | 19 ++++++----\n app/Http/Middleware/McpTierMiddleware.php | 27 +++-----------\n app/Mcp/Servers/JiminnyServer.php | 2 +\n app/Mcp/Tools/GetMeTool.php | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n app/Models/Feature/FeatureEnum.php | 1 +\n database/migrations/2026_05_13_124153_create_mcp_feature_flag.php | 25 +++++++++++++\n front-end/src/components/Settings/Kiosk/modals/EditTeamModal/EditTeamModal.vue | 52 ++++++++++++++++++--------\n front-end/src/components/Settings/Kiosk/modals/EditTeamModal/__tests__/EditTeamModal.spec.js | 14 +++++++\n tests/Feature/Mcp/GetMeToolFeatureTest.php | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n tests/Feature/Mcp/ListCallsToolFeatureTest.php | 2 +-\n tests/Feature/Mcp/McpTestHelpersTrait.php | 19 +++++++++-\n tests/Unit/Component/ES/ChunkSizeTest.php | 50 +++++++++++++++++++++++++\n tests/Unit/Component/ES/Processor/DTOs/SelectionListTest.php | 27 ++++++++++----\n tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 39 +++++++++++---------\n 16 files changed, 557 insertions(+), 75 deletions(-)\n create mode 100644 app/Component/ES/ChunkSize.php\n create mode 100644 app/Mcp/Tools/GetMeTool.php\n create mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.php\n create mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.php\n create mode 100644 tests/Unit/Component/ES/ChunkSizeTest.php\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git push\nEnumerating objects: 40, done.\nCounting objects: 100% (34/34), done.\nDelta compression using up to 8 threads\nCompressing objects: 100% (18/18), done.\nWriting objects: 100% (18/18), 1.58 KiB | 1.58 MiB/s, done.\nTotal 18 (delta 15), reused 0 (delta 0), pack-reused 0\nremote: Resolving deltas: 100% (15/15), completed with 13 local objects.\nTo github.com:jiminny/app.git\n 190239dfd4..ec1b261264 JY-20613-allow-owner-role-on-team-setup -> JY-20613-allow-owner-role-on-team-setup\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ gbr\n* JY-20613-allow-owner-role-on-team-setup\n pipedrive-sdk-poc\n master\n JY-20903-update_activity-stage-on-opportunity-change\n JY-20904-fix-update-es-on-activity-command\n JY-20891-improve-sms-text-relays\n JY-20725-handle-HS-search-rate-limit\n JY-20818-move-AJ-reports-to-separated-datadog-metric\n JY-20773-fix-automated-reports-user-pilot-tracking\n JY-20157-AJ-report-not-send-notification\n JY-20508-notify-before-AJ-report-expiration\n JY-20372-ai-reports-promotion-pages\n JY-20352-sync-opportunities-without-a-local-owner-user-id-is-null\n JY-20738-debug-AJ-tracking-UP\n a\n JY-18909-automated-reports-ask-jiminny\n JY-20692-fix-integration-app-token-auth-response-change\n JY-20553-debug-crm-sync-delays\n JY-20698-fix-SF-activity-types-on-new-playbook\n JY-20543-AJ-report-tracking\n JY-20384-handle-auto-sync-with-no-access-to-event-type\n JY-20458-ask-jiminny-user-definitions\n JY-19666-fix-import-contacts-account-association\n JY-19666-HS-import-contacts-and-accounts-batch-job\n JY-20458-Ask-Jiminny-Reports\n JY-20200-batch-update-CRM-objects-Salesforce\n JY-19666-HS-webhooks-add-contact-and-company\n JY-20348-trigger-setup-DI-layout-on-team-creation\n JY-20326-refactor-info-message-in-command\n JY-20317-fix-auto-log-delay-issue-on-all-channels-disabled\n JY-20312-remove-on-update-change-last-synced-at-crm-configurations\n JY-20306-SF-skip-auto-sync-for-task-based-playbook\n JY-20192-remove-deleted-team-from-saved-search-filters\n JY-20197-import-opportunity-batch-job\n JY-20293-enable-status-field-for-pipedrive-deals\n JY-20191-remove-commands-interactive-prompts\n JY-20118-change-default-sync-strategy\n JY-20183-add-cache-on-auto-log-delay\n JY-20197-add-import-opportunity-batch-job\n 20118-hs-opportunity-make-webhook-strategy-default\n JY-20118-make-default-hs-opportunity-sync-strategy-webhook-based\n JY-20196-handle-opportunity-without-note\n JY-20118-improve-opportunity-import\n JY-20189-handle-activity-search-on-deleted-groups\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ co JY-20725-handle-HS-search-rate-limit\nM\u0000\u0000\u0000\u0000\u0000\u0000\t.env.local\nM\u0000\u0000\u0000\u0000\u0000\u0000\tconfig/logging.php\nSwitched to branch 'JY-20725-handle-HS-search-rate-limit'\nYour branch is behind 'origin/JY-20725-handle-HS-search-rate-limit' by 439 commits, and can be fast-forwarded.\n (use \"git pull\" to update your local branch)\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ git pull\nUpdating 0f3e438941..bc6a3fce6b\nFast-forward\n .gitignore | 3 +-\n .windsurfrules | 168 ++---\n CLAUDE.md | 1 +\n app/Component/ActivityAnalytics/Service/CalculateTalkTimeOffsetsFromTranscription.php | 24 +-\n app/Component/AiActivityType/Services/AiActivityTypeEligibilityChecker.php | 28 +-\n app/Component/AiAutomation/Actions/PrepareUpdateDtoAction.php | 32 +-\n app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.php | 47 ++\n app/Component/AiAutomation/TestCrmAiPromptService.php | 14 +\n app/Component/AiCallScoring/Services/AiCallScoringEligibilityChecker.php | 9 +\n app/Component/ES/ElasticSearchDocumentPartialUpdater.php | 13 +-\n app/Component/ES/ElasticSearchWorkerManager.php | 86 ---\n app/Component/ES/Processor/Actions/LoadDocumentsAction.php | 80 +--\n app/Component/ES/Processor/EntityQueryBuilder.php | 12 +-\n app/Component/ES/Processor/TargetEntitiesSelector.php | 2 +-\n app/Component/ES/Processor/Traits/SkipActivityTrait.php | 25 -\n app/Component/ES/Repositories/EsResetActivityRepository.php | 11 +-\n app/Component/ES/Worker/ActivityWorker.php | 73 --\n app/Component/ES/Worker/EntityWorker.php | 44 --\n app/Component/ES/Worker/WorkerAmount.php | 60 --\n app/Component/ES/Worker/WorkerInterface.php | 15 -\n app/Component/ElasticSearch/Contract/Searchable.php | 4 +\n app/Component/Encoding/Job/AnalyzeTrackChannelsJob.php | 20 +-\n app/Component/Encoding/Service/GenerateSpeechFromSilenceService.php | 85 ++-\n app/Component/FFMpeg/Services/GetSpeechIntervalsService.php | 18 +-\n app/Component/LanguageDetection/Services/FindSpeechTimeService.php | 22 +-\n app/Component/Nudge/Job/ProcessOrganisationImmediateNudgesJob.php | 218 +++++-\n app/Component/ParagraphBreaker/Services/TranscriptionParagraphsService.php | 4 +\n app/Component/ParticipantSpeech/Services/ParticipantSpeechesCreator.php | 33 +\n app/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleter.php | 15 +\n app/Component/ParticipantSpeech/Services/ParticipantSpeechesProvider.php | 51 +-\n app/Component/ParticipantSpeech/Services/ParticipantSpeechesUploader.php | 36 +\n app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.php | 11 +\n app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/NoAssemblyIdException.php | 11 +\n app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/SuccessfulResponse.php | 6 +\n app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNotCorrectFormatException.php | 11 +\n app/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeechesService.php | 23 +-\n app/Component/Transcription/Diarization/Source/MeetingBotSource.php | 16 +-\n app/Component/Transcription/TranscriptionProcessor/TranscriptionProcessor.php | 3 +\n app/Console/Commands/Activities/ActivityHardDeleteCommand.php | 4 +-\n app/Console/Commands/Activities/Copy.php | 2 +\n app/Console/Commands/Activities/SetupIntegration/TwilioSetS3RecordingCredentialsCommand.php | 119 ++++\n app/Console/Commands/Activities/UpdateActivityElasticSearchDocumentCommand.php | 10 +-\n app/Console/Commands/Crm/BackfillOpportunityUserFromAccountCommand.php | 126 ++++\n app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.php | 19 -\n app/Console/Commands/Elasticsearch/AsyncUpdateEsEntities.php | 50 +-\n app/Console/Commands/Elasticsearch/ResetAsyncElasticSearchCommand.php | 30 +-\n app/Console/Commands/GeckoExport/GeckoExportParticipantSpeechesCommand.php | 14 +-\n app/Console/Commands/IssueMcpTokenCommand.php | 84 +++\n app/Console/Commands/JiminnyDebugCommand.php | 7 +-\n app/Console/Commands/Tracks/CleanupActivityTracksCommand.php | 2 +-\n app/Console/Kernel.php | 6 +-\n app/Contracts/Services/Calendar/CalendarTrait.php | 80 ++-\n app/Events/AutomatedReports/AutomatedReportGenerated.php | 3 +\n app/Http/Controllers/API/AiCallScoring/AiScorecardController.php | 7 +-\n app/Http/Controllers/API/TeamAiAutomationController.php | 8 +\n app/Http/Controllers/CustomerApi/CustomerApiController.php | 4 +-\n app/Http/Controllers/Kiosk/ActivityController.php | 58 +-\n app/Http/Controllers/Settings/PlaybookController.php | 15 +-\n app/Http/Kernel.php | 23 +\n app/Http/Middleware/McpAuditMiddleware.php | 156 ++++\n app/Http/Middleware/McpTierMiddleware.php | 54 ++\n app/Http/Requests/API/V2/ZapierUploadActivityRequest.php | 28 +-\n app/Jobs/Activity/Import/ImportTwilioVideoSpeechesJob.php | 25 +-\n app/Jobs/Activity/Import/IsActivityReadyForProcessingJob.php | 10 +-\n app/Jobs/Calendar/SetupCalendarSync.php | 21 +-\n app/Jobs/ImportRemoteTrackJob.php | 96 ++-\n app/Jobs/Mailbox/EmailTextRelay.php | 15 +-\n app/Mcp/Contracts/McpCallRepositoryInterface.php | 30 +\n app/Mcp/DTO/ListCallsFilters.php | 29 +\n app/Mcp/Errors/McpError.php | 123 ++++\n app/Mcp/Repositories/McpActivityHydrator.php | 145 ++++\n app/Mcp/Repositories/McpCallRepository.php | 84 +++\n app/Mcp/Repositories/McpElasticCallRepository.php | 171 +++++\n app/Mcp/Servers/JiminnyServer.php | 38 +\n app/Mcp/Tools/ListCallsTool.php | 205 ++++++\n app/Models/Activity.php | 10 +-\n app/Models/Activity/Transcription.php | 17 +-\n app/Models/ElasticSearch/OpportunityElasticSearchTrait.php | 5 +\n app/Models/Participant.php | 1 +\n app/Providers/AppServiceProvider.php | 22 +\n app/Repositories/Crm/ContactRepository.php | 69 +-\n app/Repositories/ParticipantSpeechRepository.php | 13 +-\n app/Services/Activity/ParticipantsService.php | 19 +-\n app/Services/Activity/Twilio/S3RecordingCredentialsService.php | 82 +++\n app/Services/ActivityService.php | 21 +-\n app/Services/Calendar/CalendarActivityService.php | 46 ++\n app/Services/Calendar/Command/ImportParticipants.php | 1 +\n app/Services/Calendar/Command/MapActivityData.php | 106 +--\n app/Services/Calendar/GoogleCalendarService.php | 12 +-\n app/Services/Crm/Close/Processor/OpportunityProcessor.php | 2 +-\n app/Services/Crm/Close/Service.php | 22 +-\n app/Services/Crm/Copper/Service.php | 12 +-\n app/Services/Crm/Hubspot/Service.php | 154 +++-\n app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php | 88 ++-\n app/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTrait.php | 22 +-\n app/Services/Crm/Pipedrive/Service.php | 17 +-\n app/Services/Crm/Salesforce/Service.php | 42 +-\n app/Services/Mail/Office/EmailApiClient.php | 129 +---\n app/Services/RecallAI/Commands/ScheduleBotCommand.php | 39 +-\n app/Services/RecallAI/RecallAIService.php | 22 +-\n composer.json | 3 +-\n composer.lock | 87 ++-\n config/mcp.php | 23 +\n database/migrations/2026_04_30_120000_create_mcp_audit_log_table.php | 36 +\n docs/mcp/explorer/explorer.html | 697 ++++++++++++++++++\n docs/mcp/explorer/explorer.template.html | 697 ++++++++++++++++++\n docs/mcp/explorer/generate.js | 215 ++++++\n docs/mcp/explorer/tool-explorer-meta.json | 11 +\n docs/mcp/tools-list.json | 2536 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n docs/mcp/tools.md | 621 ++++++++++++++++\n front-end/package.json | 4 +-\n front-end/src/components/Settings/OrgSettings/AiAutomation/CrmFilling/TemplateFieldForm.vue | 28 +-\n front-end/src/components/Settings/OrgSettings/Playbooks/AddEditPlaybook.vue | 10 +\n front-end/src/components/playback/comments/ActivityComment.less | 10 +-\n front-end/src/components/shared/PromptTester/PromptTester.vue | 12 +-\n front-end/src/components/shared/__tests__/PromptTester.spec.js | 35 +\n front-end/src/components/shared/modals/EntityPickerModal/__tests__/useEntitiesCache.spec.ts | 37 +\n front-end/src/components/shared/modals/EntityPickerModal/useEntitiesCache.ts | 9 +\n front-end/yarn.lock | 16 +-\n phpstan-baseline.neon | 50 --\n routes/api.php | 11 +\n sonar-project.properties | 91 ++-\n tests/Feature/Component/Nudge/ProcessOrganisationImmediateNudgesJobTest.php | 534 ++++++++++++++\n tests/Feature/Jobs/ImportRemoteTrackJobTest.php | 283 +++++++-\n tests/Feature/Mcp/IssueMcpTokenCommandTest.php | 53 ++\n tests/Feature/Mcp/ListCallsToolElasticFeatureTest.php | 155 ++++\n tests/Feature/Mcp/ListCallsToolFeatureTest.php | 352 ++++++++++\n tests/Feature/Mcp/McpTestHelpersTrait.php | 77 ++\n tests/Feature/Services/Team/TeamDeleteHandlers/Retention/RetentionRepositoryHandlerTest.php | 1 +\n tests/Stubs/SentryStub.php | 18 +\n tests/Unit/Component/ActivityAnalytics/Service/CalculateTalkTimeOffsetFromTranscriptionTest.php | 28 +-\n tests/Unit/Component/AiActivityType/Services/AiActivityTypeEligibilityCheckerTest.php | 103 ++-\n tests/Unit/Component/AiAutomation/Actions/PrepareUpdateDtoActionTest.php | 91 +++\n tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheckerTest.php | 124 ++++\n tests/Unit/Component/AiAutomation/TestCrmAiPromptServiceTest.php | 67 +-\n tests/Unit/Component/AiCallScoring/Services/AiCallScoringEligibilityCheckerTest.php | 55 ++\n tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.php | 135 ----\n tests/Unit/Component/ES/Processor/Actions/LoadDocumentsActionTest.php | 220 ++++++\n tests/Unit/Component/ES/Processor/EntityQueryBuilderTest.php | 21 +-\n tests/Unit/Component/ES/Processor/Traits/SkipActivityTraitTest.php | 51 --\n tests/Unit/Component/ES/Worker/ActivityWorkerTest.php | 174 -----\n tests/Unit/Component/ES/Worker/EntityWorkerTest.php | 97 ---\n tests/Unit/Component/ES/Worker/WorkerAmountTest.php | 116 ---\n tests/Unit/Component/Encoding/Job/AnalyzeTrackChannelsJobTest.php | 52 +-\n tests/Unit/Component/Encoding/Service/GenerateSpeechFromSilenceServiceTest.php | 171 ++---\n tests/Unit/Component/FFMpeg/Services/GetSpeechIntervalsTest.php | 36 +-\n tests/Unit/Component/LanguageDetection/Services/FindSpeechTimeServiceTest.php | 20 +-\n tests/Unit/Component/MobileSettings/MobileSettingsControllerTest.php | 5 +-\n tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCreatorTest.php | 75 ++\n tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleterTest.php | 63 ++\n tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesProviderTest.php | 134 ++++\n tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesUploaderTest.php | 57 ++\n tests/Unit/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeechesServiceTest.php | 51 +-\n tests/Unit/Component/Transcription/Diarization/Source/MeetingBotSourceTest.php | 29 +-\n tests/Unit/Contracts/Services/Calendar/CalendarTraitTest.php | 58 +-\n tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.php | 159 +++++\n tests/Unit/Jobs/Activity/Import/ImportTwilioVideoSpeechesJobTest.php | 22 +-\n tests/Unit/Jobs/Activity/Import/IsActivityReadyForProcessingJobTest.php | 26 +-\n tests/Unit/Jobs/Calendar/SetupCalendarSyncTest.php | 25 -\n tests/Unit/Services/Activity/ParticipantsServiceTest.php | 12 +-\n tests/Unit/Services/Activity/Twilio/S3RecordingCredentialsServiceTest.php | 180 +++++\n tests/Unit/Services/ActivityServiceTest.php | 132 ++++\n tests/Unit/Services/Calendar/CalendarActivityServiceTest.php | 150 +++-\n tests/Unit/Services/Calendar/Command/ImportParticipantsTest.php | 6 +-\n tests/Unit/Services/Calendar/Command/MapActivityDataTest.php | 78 +-\n tests/Unit/Services/Calendar/GoogleCalendarServiceTest.php | 116 +++\n tests/Unit/Services/Crm/Close/ServiceTest.php | 165 +++++\n tests/Unit/Services/Crm/Hubspot/ServiceTest.php | 272 ++++++-\n tests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTest.php | 25 +-\n tests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTraitMatchActivitiesTest.php | 3 +-\n tests/Unit/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTraitOpportunitiesTest.php | 40 ++\n tests/Unit/Services/Crm/Pipedrive/ImportOpportunityMatchActivitiesTest.php | 2 +\n tests/Unit/Services/Crm/Salesforce/ServiceTest.php | 139 ++++\n tests/Unit/Services/Mail/Office/EmailApiClientTest.php | 195 ++---\n tests/Unit/Services/RecallAI/RecallAIServiceTest.php | 24 +-\n 175 files changed, 12562 insertions(+), 2162 deletions(-)\n create mode 120000 CLAUDE.md\n create mode 100644 app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.php\n delete mode 100644 app/Component/ES/ElasticSearchWorkerManager.php\n delete mode 100644 app/Component/ES/Processor/Traits/SkipActivityTrait.php\n delete mode 100644 app/Component/ES/Worker/ActivityWorker.php\n delete mode 100644 app/Component/ES/Worker/EntityWorker.php\n delete mode 100644 app/Component/ES/Worker/WorkerAmount.php\n delete mode 100644 app/Component/ES/Worker/WorkerInterface.php\n create mode 100644 app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.php\n create mode 100644 app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/NoAssemblyIdException.php\n create mode 100644 app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNotCorrectFormatException.php\n create mode 100644 app/Console/Commands/Activities/SetupIntegration/TwilioSetS3RecordingCredentialsCommand.php\n create mode 100644 app/Console/Commands/Crm/BackfillOpportunityUserFromAccountCommand.php\n delete mode 100644 app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.php\n create mode 100644 app/Console/Commands/IssueMcpTokenCommand.php\n create mode 100644 app/Http/Middleware/McpAuditMiddleware.php\n create mode 100644 app/Http/Middleware/McpTierMiddleware.php\n create mode 100644 app/Mcp/Contracts/McpCallRepositoryInterface.php\n create mode 100644 app/Mcp/DTO/ListCallsFilters.php\n create mode 100644 app/Mcp/Errors/McpError.php\n create mode 100644 app/Mcp/Repositories/McpActivityHydrator.php\n create mode 100644 app/Mcp/Repositories/McpCallRepository.php\n create mode 100644 app/Mcp/Repositories/McpElasticCallRepository.php\n create mode 100644 app/Mcp/Servers/JiminnyServer.php\n create mode 100644 app/Mcp/Tools/ListCallsTool.php\n create mode 100644 app/Services/Activity/Twilio/S3RecordingCredentialsService.php\n create mode 100644 config/mcp.php\n create mode 100644 database/migrations/2026_04_30_120000_create_mcp_audit_log_table.php\n create mode 100644 docs/mcp/explorer/explorer.html\n create mode 100644 docs/mcp/explorer/explorer.template.html\n create mode 100644 docs/mcp/explorer/generate.js\n create mode 100644 docs/mcp/explorer/tool-explorer-meta.json\n create mode 100644 docs/mcp/tools-list.json\n create mode 100644 docs/mcp/tools.md\n create mode 100644 front-end/src/components/shared/modals/EntityPickerModal/__tests__/useEntitiesCache.spec.ts\n create mode 100644 tests/Feature/Component/Nudge/ProcessOrganisationImmediateNudgesJobTest.php\n create mode 100644 tests/Feature/Mcp/IssueMcpTokenCommandTest.php\n create mode 100644 tests/Feature/Mcp/ListCallsToolElasticFeatureTest.php\n create mode 100644 tests/Feature/Mcp/ListCallsToolFeatureTest.php\n create mode 100644 tests/Feature/Mcp/McpTestHelpersTrait.php\n create mode 100644 tests/Stubs/SentryStub.php\n create mode 100644 tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheckerTest.php\n delete mode 100644 tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.php\n create mode 100644 tests/Unit/Component/ES/Processor/Actions/LoadDocumentsActionTest.php\n delete mode 100644 tests/Unit/Component/ES/Processor/Traits/SkipActivityTraitTest.php\n delete mode 100644 tests/Unit/Component/ES/Worker/ActivityWorkerTest.php\n delete mode 100644 tests/Unit/Component/ES/Worker/EntityWorkerTest.php\n delete mode 100644 tests/Unit/Component/ES/Worker/WorkerAmountTest.php\n create mode 100644 tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCreatorTest.php\n create mode 100644 tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.php\n create mode 100644 tests/Unit/Services/Activity/Twilio/S3RecordingCredentialsServiceTest.php\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ git status\nOn branch master\nYour branch is behind 'origin/master' by 114 commits, and can be fast-forwarded.\n (use \"git pull\" to update your local branch)\n\nChanges not staged for commit:\n (use \"git add <file>...\" to update what will be committed)\n (use \"git restore <file>...\" to discard changes in working directory)\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: .env.local\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Component/SCIM/Constants.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Component/SCIM/ScimProvisioning.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Component/Twilio/Conference/ConferenceManager/SoftPhoneManager.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Console/Commands/JiminnyDebugCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/DTO/SCIM/AAD/Request/CoreUserRequest.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/DTO/SCIM/AAD/Response/CoreUser.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Services/Telephony/TextMessagingService.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: config/logging.php\n\nUntracked files:\n (use \"git add <file>...\" to include in what will be committed)\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\t.env.nikilocal\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\t.env.other\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tWEBHOOK_FILTERING_IMPLEMENTATION.md\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Component/SCIM/Mutators/Attributes/User/RoleAttr.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Console/Commands/Crm/Hubspot/SimulateWebhooksCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Console/Commands/Reports/CreateMockAskJiminnyReportResultCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Rules/ListenerRoleCannotHaveAdminOrManagerPermissionRule.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tids.txt\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tpublic/favicon.ico\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\traw_sql_query.sql\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ttests/Unit/Component/SCIM/Mutators/Attributes/User/RoleAttrTest.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ttests/Unit/Policies/CanAccessAiReportsTest.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ttests/Unit/Rules/ListenerRoleCannotHaveAdminOrManagerPermissionRuleTest.php\n\nno changes added to commit (use \"git add\" and/or \"git commit -a\")\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull\nremote: Enumerating objects: 306, done.\nremote: Counting objects: 100% (299/299), done.\nremote: Compressing objects: 100% (183/183), done.\nremote: Total 306 (delta 213), reused 171 (delta 116), pack-reused 7 (from 1)\nReceiving objects: 100% (306/306), 80.12 KiB | 1000.00 KiB/s, done.\nResolving deltas: 100% (213/213), completed with 53 local objects.\nFrom github.com:jiminny/app\n 90bca4e4b2..5604af40cf master -> origin/master\n 4e7078fd8b..0b8343d179 JY-18091-upgrade-to-php-8-5 -> origin/JY-18091-upgrade-to-php-8-5\n 098eeaa087..d5a447e492 JY-20613-allow-owner-role-on-team-setup -> origin/JY-20613-allow-owner-role-on-team-setup\n c3a76ace91..af65249d0f JY-20749-user-can-view-recorded-meetings -> origin/JY-20749-user-can-view-recorded-meetings\n d94a285ae7..7ce96cb5fe JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue\n * [new branch] JY-20842-remove-partial-updater -> origin/JY-20842-remove-partial-updater\n * [new branch] JY-20920-fix-participant-flip -> origin/JY-20920-fix-participant-flip\n * [new branch] secfix/npm-20260519 -> origin/secfix/npm-20260519\nUpdating cb4ebf0c36..5604af40cf\nFast-forward\n app/Component/ES/ChunkSize.php | 54 +++++++++++++++++++\n app/Component/ES/Processor/DTOs/SelectionList.php | 4 +-\n app/Component/ES/Processor/TargetEntitiesSelector.php | 19 ++++---\n app/Component/MeetingBot/Service/ParticipantMatcher.php | 46 ++++++++++++----\n app/Exceptions/RateLimitException.php | 19 ++++++-\n app/Http/Middleware/McpTierMiddleware.php | 27 ++--------\n app/Jobs/Crm/MatchActivityCrmData.php | 47 ++++++++++++----\n app/Jobs/Middleware/HandleHubspotRateLimit.php | 42 +++++++++++++++\n app/Mcp/Servers/JiminnyServer.php | 2 +\n app/Mcp/Tools/GetMeTool.php | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++\n app/Models/Feature/FeatureEnum.php | 1 +\n app/Services/Activity/HubSpot/ProviderResolver.php | 4 +-\n app/Services/Activity/HubSpot/ProviderResolverInterface.php | 2 +-\n app/Services/Activity/HubSpot/Providers/Provider.php | 2 +-\n app/Services/Activity/HubSpot/Providers/ProviderKixie.php | 2 +-\n app/Services/Activity/HubSpot/Providers/ProviderOrum.php | 2 +-\n app/Services/Activity/HubSpot/Providers/ProviderTwilio.php | 2 +-\n app/Services/Activity/HubSpot/Providers/ProviderTwilioFlex.php | 5 +-\n app/Services/Activity/HubSpot/Service.php | 97 +++++++++++++++++++++++++++------\n app/Services/Crm/Hubspot/Client.php | 132 +++++++++++++++++++++++++++++++++++++++++++++\n app/Services/Crm/Hubspot/HubspotClientInterface.php | 15 ++++++\n app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php | 21 ++++----\n app/Services/Crm/Hubspot/Pagination/PaginationState.php | 2 +-\n database/migrations/2026_05_13_124153_create_mcp_feature_flag.php | 25 +++++++++\n tests/Feature/Mcp/GetMeToolFeatureTest.php | 140 +++++++++++++++++++++++++++++++++++++++++++++++\n tests/Feature/Mcp/ListCallsToolFeatureTest.php | 2 +-\n tests/Feature/Mcp/McpTestHelpersTrait.php | 19 ++++++-\n tests/Unit/Component/ES/ChunkSizeTest.php | 50 +++++++++++++++++\n tests/Unit/Component/ES/Processor/DTOs/SelectionListTest.php | 27 +++++++---\n tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 39 ++++++++------\n tests/Unit/Component/MeetingBot/Service/ParticipantMatcherTest.php | 68 ++++++++++++++++++++++-\n tests/Unit/Exceptions/RateLimitExceptionTest.php | 56 +++++++++++++++++++\n tests/Unit/Jobs/Crm/MatchActivityCrmDataTest.php | 8 +--\n tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++\n tests/Unit/Services/Activity/HubSpot/ServiceTest.php | 109 +++++++++++++++++++++++++++++++++++++\n tests/Unit/Services/Crm/Hubspot/ClientTest.php | 250 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n tests/Unit/Services/Crm/Hubspot/Pagination/HubspotPaginationServiceTest.php | 283 +++++++++++++++++++++---------------------------------------------------------------------------\n 37 files changed, 1587 insertions(+), 344 deletions(-)\n create mode 100644 app/Component/ES/ChunkSize.php\n create mode 100644 app/Jobs/Middleware/HandleHubspotRateLimit.php\n create mode 100644 app/Mcp/Tools/GetMeTool.php\n create mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.php\n create mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.php\n create mode 100644 tests/Unit/Component/ES/ChunkSizeTest.php\n create mode 100644 tests/Unit/Exceptions/RateLimitExceptionTest.php\n create mode 100644 tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull\nAlready up to date.\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20676-delete-report-related-objects\nSwitched to a new branch 'JY-20676-delete-report-related-objects'\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20676-delete-report-related-objects) $ csfix\ndocker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff \nPHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.\nPHP runtime: 8.3.30\nRunning analysis on 7 cores with 10 files per process.\nParallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!\nLoaded config default from \".php-cs-fixer.dist.php\".\n 5690/5690 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%\n\n 1) app/Console/Commands/JiminnyDebugCommand.php (statement_indentation, blank_line_before_statement)\n ---------- begin diff ----------\n--- /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php\n+++ /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php\n@@ -23,6 +23,7 @@\n \n if ($action === 'redis-set') {\n $this->testRedisSet();\n+\n return;\n }\n \n@@ -45,7 +46,7 @@\n $ttl = 60;\n \n try {\n-// $result = Redis::set($testKey, $testValue, 'EX', $ttl, 'NX');\n+ // $result = Redis::set($testKey, $testValue, 'EX', $ttl, 'NX');\n $result = Redis::set($testKey, $testValue, ['nx', 'ex' => $ttl]);\n \n if ($result) {\n\n ----------- end diff -----------\n\n\nFixed 1 of 5690 files in 50.673 seconds, 67.00 MB memory used\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20676-delete-report-related-objects) $ ;xd\ndocker exec -it docker_lamp_1 bash -c \"mv /usr/local/etc/php/conf.d/xdebug.ini ~/xdebug.ini\"\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\ndocker exec -it docker_lamp_1 supervisorctl restart all\njiminny-worker-processing-2:jiminny-worker-processing-2_00: stopped\njiminny-worker-processing-3:jiminny-worker-processing-3_00: stopped\njiminny-worker-processing-4:jiminny-worker-processing-4_00: stopped\njiminny-worker-processing-5:jiminny-worker-processing-5_00: stopped\njiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00: stopped\nworker-analytics:worker-analytics_00: stopped\nworker-crm-update:worker-crm-update_00: stopped\nworker-download:worker-download_00: stopped\nworker-nudges:worker-nudges_00: stopped\nworker-calendar:worker-calendar_00: stopped\nworker-audio:worker-audio_00: stopped\njiminny-worker-processing-1:jiminny-worker-processing-1_00: stopped\nworker:worker_00: stopped\nworker-conferences:worker-conferences_00: stopped\nworker-crm-sync:worker-crm-sync_00: stopped\nworker-emails:worker-emails_00: stopped\nworker-es-update:worker-es-update_00: stopped\nartisan-schedule:artisan-schedule_00: stopped\nartisan-schedule:artisan-schedule_00: started\njiminny-worker-processing-1:jiminny-worker-processing-1_00: started\njiminny-worker-processing-2:jiminny-worker-processing-2_00: started\njiminny-worker-processing-3:jiminny-worker-processing-3_00: started\njiminny-worker-processing-4:jiminny-worker-processing-4_00: started\njiminny-worker-processing-5:jiminny-worker-processing-5_00: started\njiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00: started\nworker:worker_00: started\nworker-analytics:worker-analytics_00: started\nworker-audio:worker-audio_00: started\nworker-calendar:worker-calendar_00: started\nworker-conferences:worker-conferences_00: started\nworker-crm-sync:worker-crm-sync_00: started\nworker-crm-update:worker-crm-update_00: started\nworker-download:worker-download_00: started\nworker-emails:worker-emails_00: started\nworker-es-update:worker-es-update_00: started\nworker-nudges:worker-nudges_00: started\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\ndocker exec -it docker_lamp_1 php -v\nPHP 8.3.30 (cli) (built: Mar 16 2026 22:32:32) (NTS)\nCopyright (c) The PHP Group\nZend Engine v4.3.30, Copyright (c) Zend Technologies\n with Zend OPcache v8.3.30, Copyright (c), by Zend Technologies\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20676-delete-report-related-objects) $ git status","is_focused":true},{"role":"AXRadioButton","text":"DOCKER","depth":2,"bounds":{"left":0.27027926,"top":1.0,"width":0.094913565,"height":-0.042298436},"on_screen":true,"role_description":"radio button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close Tab","depth":3,"bounds":{"left":0.27227393,"top":1.0,"width":0.005319149,"height":-0.04549086},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"DEV (docker)","depth":2,"bounds":{"left":0.36519283,"top":1.0,"width":0.094913565,"height":-0.042298436},"on_screen":true,"role_description":"radio button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close Tab","depth":3,"bounds":{"left":0.3671875,"top":1.0,"width":0.005319149,"height":-0.04549086},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"APP (git)","depth":2,"bounds":{"left":0.46010637,"top":1.0,"width":0.09474734,"height":-0.042298436},"on_screen":true,"role_description":"radio button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close Tab","depth":3,"bounds":{"left":0.46210107,"top":1.0,"width":0.005319149,"height":-0.04549086},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"ffmpeg","depth":2,"bounds":{"left":0.55485374,"top":1.0,"width":0.09474734,"height":-0.042298436},"on_screen":true,"role_description":"radio button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close Tab","depth":3,"bounds":{"left":0.5568484,"top":1.0,"width":0.005319149,"height":-0.04549086},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"-zsh","depth":2,"bounds":{"left":0.64960104,"top":1.0,"width":0.09474734,"height":-0.042298436},"on_screen":true,"role_description":"radio button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close Tab","depth":3,"bounds":{"left":0.6515958,"top":1.0,"width":0.005319149,"height":-0.04549086},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"⌥⌘1","depth":1,"bounds":{"left":0.7307181,"top":1.0,"width":0.01861702,"height":-0.023144484},"on_screen":true,"automation_id":"_NS:8","role_description":"text"},{"role":"AXStaticText","text":"APP (git)","depth":1,"bounds":{"left":0.5006649,"top":1.0,"width":0.020944148,"height":-0.02394259},"on_screen":true,"role_description":"text"}]...
|
2802650493718167367
|
-1358120912881272742
|
click
|
accessibility
|
NULL
|
Last login: Mon May 18 09:17:28 on ttys007
Poetry Last login: Mon May 18 09:17:28 on ttys007
Poetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parents
Poetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parents
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ co master
error: Your local changes to the following files would be overwritten by checkout:
PIPEDRIVE_V2_MIGRATION_TICKETS.md
Please commit your changes or stash them before you switch branches.
Aborting
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ git pull
remote: Enumerating objects: 1047, done.
remote: Counting objects: 100% (832/832), done.
remote: Compressing objects: 100% (298/298), done.
remote: Total 1047 (delta 634), reused 596 (delta 534), pack-reused 215 (from 3)
Receiving objects: 100% (1047/1047), 353.16 KiB | 1.56 MiB/s, done.
Resolving deltas: 100% (687/687), completed with 107 local objects.
From github.com:jiminny/app
907c54896c..34656c53ed pipedrive-sdk-poc -> origin/pipedrive-sdk-poc
03325ec50f..4e7078fd8b JY-18091-upgrade-to-php-8-5 -> origin/JY-18091-upgrade-to-php-8-5
e7d231e163..bc6a3fce6b JY-20725-handle-HS-search-rate-limit -> origin/JY-20725-handle-HS-search-rate-limit
* [new branch] JY-20749-user-can-view-recorded-meetings -> origin/JY-20749-user-can-view-recorded-meetings
98ca281a04..e0351be069 JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue
569abb5149..3906a9238a JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details -> origin/JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details
ad6c2a86e8..50eb6afba9 JY-20846-mcp-enable-the-ai-to-know-details-about-the-user -> origin/JY-20846-mcp-enable-the-ai-to-know-details-about-the-user
* [new branch] JY-20893-chunk-control-per-update-target -> origin/JY-20893-chunk-control-per-update-target
31c62924a5..cb4ebf0c36 master -> origin/master
Updating 907c54896c..34656c53ed
Fast-forward
PIPEDRIVE_V2_MIGRATION_TICKETS.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 52 insertions(+)
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ co master
M .env.local
M config/logging.php
Switched to branch 'master'
Your branch is behind 'origin/master' by 31 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull
Updating 31c62924a5..cb4ebf0c36
Fast-forward
app/Component/ES/Processor/Traits/SelectEntityListTrait.php | 20 ------
app/Services/Calendar/CalendarActivityService.php | 46 +++++++++++++
app/Services/Calendar/Command/MapActivityData.php | 106 +++-------------------------
docs/mcp/explorer/explorer.html | 104 +++++++++++++++++++++++++---
docs/mcp/explorer/explorer.template.html | 102 ++++++++++++++++++++++++---
docs/mcp/tools-list.json | 373 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
docs/mcp/tools.md | 117 +++++++++++++++++++++++--------
tests/Unit/Component/ES/AsyncUpdateElasticSearchTest.php | 16 +----
tests/Unit/Component/ES/Listeners/UpdateMultipleTargetsListenerTest.php | 10 ---
tests/Unit/Component/ES/Listeners/UpdateSingleTargetListenerTest.php | 6 --
tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 9 ---
tests/Unit/Component/ES/Processor/Traits/SelectEntityListTraitTest.php | 15 ++--
tests/Unit/Component/ES/UpdateProcessManagerTest.php | 2 -
tests/Unit/Services/Calendar/CalendarActivityServiceTest.php | 150 ++++++++++++++++++++++++++++++++++++++--
tests/Unit/Services/Calendar/Command/MapActivityDataTest.php | 78 ++-------------------
15 files changed, 832 insertions(+), 322 deletions(-)
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20613-allow-owner-role-on-team-setup
Switched to a new branch 'JY-20613-allow-owner-role-on-team-setup'
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ csfix
docker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff
PHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.
PHP runtime: 8.3.30
Running analysis on 7 cores with 10 files per process.
Parallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!
Loaded config default from ".php-cs-fixer.dist.php".
5682/5682 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
Fixed 0 of 5682 files in 56.978 seconds, 67.00 MB memory used
What's next:
Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1
Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ csfix
docker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff
PHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.
PHP runtime: 8.3.30
Running analysis on 7 cores with 10 files per process.
Parallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!
Loaded config default from ".php-cs-fixer.dist.php".
5682/5682 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
Fixed 0 of 5682 files in 49.910 seconds, 60.00 MB memory used
What's next:
Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1
Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git pull
remote: Enumerating objects: 248, done.
remote: Counting objects: 100% (128/128), done.
remote: Compressing objects: 100% (23/23), done.
remote: Total 59 (delta 43), reused 44 (delta 33), pack-reused 0 (from 0)
Unpacking objects: 100% (59/59), 10.48 KiB | 228.00 KiB/s, done.
From github.com:jiminny/app
b7df560451..190239dfd4 JY-20613-allow-owner-role-on-team-setup -> origin/JY-20613-allow-owner-role-on-team-setup
e0351be069..d94a285ae7 JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue
* [new branch] JY-20920-fix-participant-matcher -> origin/JY-20920-fix-participant-matcher
cb4ebf0c36..90bca4e4b2 master -> origin/master
Merge made by the 'ort' strategy.
app/Component/ES/ChunkSize.php | 54 +++++++++++++++++++++++++++
app/Component/ES/Processor/DTOs/SelectionList.php | 4 +-
app/Component/ES/Processor/TargetEntitiesSelector.php | 19 ++++++----
app/Http/Middleware/McpTierMiddleware.php | 27 +++-----------
app/Mcp/Servers/JiminnyServer.php | 2 +
app/Mcp/Tools/GetMeTool.php | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
app/Models/Feature/FeatureEnum.php | 1 +
database/migrations/2026_05_13_124153_create_mcp_feature_flag.php | 25 +++++++++++++
front-end/src/components/Settings/Kiosk/modals/EditTeamModal/EditTeamModal.vue | 52 ++++++++++++++++++--------
front-end/src/components/Settings/Kiosk/modals/EditTeamModal/__tests__/EditTeamModal.spec.js | 14 +++++++
tests/Feature/Mcp/GetMeToolFeatureTest.php | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/Feature/Mcp/ListCallsToolFeatureTest.php | 2 +-
tests/Feature/Mcp/McpTestHelpersTrait.php | 19 +++++++++-
tests/Unit/Component/ES/ChunkSizeTest.php | 50 +++++++++++++++++++++++++
tests/Unit/Component/ES/Processor/DTOs/SelectionListTest.php | 27 ++++++++++----
tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 39 +++++++++++---------
16 files changed, 557 insertions(+), 75 deletions(-)
create mode 100644 app/Component/ES/ChunkSize.php
create mode 100644 app/Mcp/Tools/GetMeTool.php
create mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.php
create mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.php
create mode 100644 tests/Unit/Component/ES/ChunkSizeTest.php
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git push
Enumerating objects: 40, done.
Counting objects: 100% (34/34), done.
Delta compression using up to 8 threads
Compressing objects: 100% (18/18), done.
Writing objects: 100% (18/18), 1.58 KiB | 1.58 MiB/s, done.
Total 18 (delta 15), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (15/15), completed with 13 local objects.
To github.com:jiminny/app.git
190239dfd4..ec1b261264 JY-20613-allow-owner-role-on-team-setup -> JY-20613-allow-owner-role-on-team-setup
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ gbr
* JY-20613-allow-owner-role-on-team-setup
pipedrive-sdk-poc
master
JY-20903-update_activity-stage-on-opportunity-change
JY-20904-fix-update-es-on-activity-command
JY-20891-improve-sms-text-relays
JY-20725-handle-HS-search-rate-limit
JY-20818-move-AJ-reports-to-separated-datadog-metric
JY-20773-fix-automated-reports-user-pilot-tracking
JY-20157-AJ-report-not-send-notification
JY-20508-notify-before-AJ-report-expiration
JY-20372-ai-reports-promotion-pages
JY-20352-sync-opportunities-without-a-local-owner-user-id-is-null
JY-20738-debug-AJ-tracking-UP
a
JY-18909-automated-reports-ask-jiminny
JY-20692-fix-integration-app-[API_KEY]
JY-20553-debug-crm-sync-delays
JY-20698-fix-SF-activity-types-on-new-playbook
JY-20543-AJ-report-tracking
JY-20384-handle-auto-sync-with-no-access-to-event-type
JY-20458-ask-jiminny-user-definitions
JY-19666-fix-import-contacts-account-association
JY-19666-HS-import-contacts-and-accounts-batch-job
JY-20458-Ask-Jiminny-Reports
JY-20200-batch-update-CRM-objects-Salesforce
JY-19666-HS-webhooks-add-contact-and-company
JY-20348-trigger-setup-DI-layout-on-team-creation
JY-20326-refactor-info-message-in-command
JY-20317-fix-auto-log-delay-issue-on-all-channels-disabled
JY-20312-remove-on-update-change-last-synced-at-crm-configurations
JY-20306-SF-skip-auto-sync-for-task-based-playbook
JY-20192-remove-deleted-team-from-saved-search-filters
JY-20197-import-opportunity-batch-job
JY-20293-enable-status-field-for-pipedrive-deals
JY-20191-remove-commands-interactive-prompts
JY-20118-change-default-sync-strategy
JY-20183-add-cache-on-auto-log-delay
JY-20197-add-import-opportunity-batch-job
20118-hs-opportunity-make-webhook-strategy-default
JY-20118-make-default-hs-opportunity-sync-strategy-webhook-based
JY-20196-handle-opportunity-without-note
JY-20118-improve-opportunity-import
JY-20189-handle-activity-search-on-deleted-groups
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ co JY-20725-handle-HS-search-rate-limit
M .env.local
M config/logging.php
Switched to branch 'JY-20725-handle-HS-search-rate-limit'
Your branch is behind 'origin/JY-20725-handle-HS-search-rate-limit' by 439 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ git pull
Updating 0f3e438941..bc6a3fce6b
Fast-forward
.gitignore | 3 +-
.windsurfrules | 168 ++---
CLAUDE.md | 1 +
app/Component/ActivityAnalytics/Service/CalculateTalkTimeOffsetsFromTranscription.php | 24 +-
app/Component/AiActivityType/Services/AiActivityTypeEligibilityChecker.php | 28 +-
app/Component/AiAutomation/Actions/PrepareUpdateDtoAction.php | 32 +-
app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.php | 47 ++
app/Component/AiAutomation/TestCrmAiPromptService.php | 14 +
app/Component/AiCallScoring/Services/AiCallScoringEligibilityChecker.php | 9 +
app/Component/ES/ElasticSearchDocumentPartialUpdater.php | 13 +-
app/Component/ES/ElasticSearchWorkerManager.php | 86 ---
app/Component/ES/Processor/Actions/LoadDocumentsAction.php | 80 +--
app/Component/ES/Processor/EntityQueryBuilder.php | 12 +-
app/Component/ES/Processor/TargetEntitiesSelector.php | 2 +-
app/Component/ES/Processor/Traits/SkipActivityTrait.php | 25 -
app/Component/ES/Repositories/EsResetActivityRepository.php | 11 +-
app/Component/ES/Worker/ActivityWorker.php | 73 --
app/Component/ES/Worker/EntityWorker.php | 44 --
app/Component/ES/Worker/WorkerAmount.php | 60 --
app/Component/ES/Worker/WorkerInterface.php | 15 -
app/Component/ElasticSearch/Contract/Searchable.php | 4 +
app/Component/Encoding/Job/AnalyzeTrackChannelsJob.php | 20 +-
app/Component/Encoding/Service/GenerateSpeechFromSilenceService.php | 85 ++-
app/Component/FFMpeg/Services/GetSpeechIntervalsService.php | 18 +-
app/Component/LanguageDetection/Services/FindSpeechTimeService.php | 22 +-
app/Component/Nudge/Job/ProcessOrganisationImmediateNudgesJob.php | 218 +++++-
app/Component/ParagraphBreaker/Services/TranscriptionParagraphsService.php | 4 +
app/Component/ParticipantSpeech/Services/ParticipantSpeechesCreator.php | 33 +
app/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleter.php | 15 +
app/Component/ParticipantSpeech/Services/ParticipantSpeechesProvider.php | 51 +-
app/Component/ParticipantSpeech/Services/ParticipantSpeechesUploader.php | 36 +
app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.php | 11 +
app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/NoAssemblyIdException.php | 11 +
app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/SuccessfulResponse.php | 6 +
app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNotCorrectFormatException.php | 11 +
app/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeechesService.php | 23 +-
app/Component/Transcription/Diarization/Source/MeetingBotSource.php | 16 +-
app/Component/Transcription/TranscriptionProcessor/TranscriptionProcessor.php | 3 +
app/Console/Commands/Activities/ActivityHardDeleteCommand.php | 4 +-
app/Console/Commands/Activities/Copy.php | 2 +
app/Console/Commands/Activities/SetupIntegration/TwilioSetS3RecordingCredentialsCommand.php | 119 ++++
app/Console/Commands/Activities/UpdateActivityElasticSearchDocumentCommand.php | 10 +-
app/Console/Commands/Crm/BackfillOpportunityUserFromAccountCommand.php | 126 ++++
app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.php | 19 -
app/Console/Commands/Elasticsearch/AsyncUpdateEsEntities.php | 50 +-
app/Console/Commands/Elasticsearch/ResetAsyncElasticSearchCommand.php | 30 +-
app/Console/Commands/GeckoExport/GeckoExportParticipantSpeechesCommand.php | 14 +-
app/Console/Commands/IssueMcpTokenCommand.php | 84 +++
app/Console/Commands/JiminnyDebugCommand.php | 7 +-
app/Console/Commands/Tracks/CleanupActivityTracksCommand.php | 2 +-
app/Console/Kernel.php | 6 +-
app/Contracts/Services/Calendar/CalendarTrait.php | 80 ++-
app/Events/AutomatedReports/AutomatedReportGenerated.php | 3 +
app/Http/Controllers/API/AiCallScoring/AiScorecardController.php | 7 +-
app/Http/Controllers/API/TeamAiAutomationController.php | 8 +
app/Http/Controllers/CustomerApi/CustomerApiController.php | 4 +-
app/Http/Controllers/Kiosk/ActivityController.php | 58 +-
app/Http/Controllers/Settings/PlaybookController.php | 15 +-
app/Http/Kernel.php | 23 +
app/Http/Middleware/McpAuditMiddleware.php | 156 ++++
app/Http/Middleware/McpTierMiddleware.php | 54 ++
app/Http/Requests/API/V2/ZapierUploadActivityRequest.php | 28 +-
app/Jobs/Activity/Import/ImportTwilioVideoSpeechesJob.php | 25 +-
app/Jobs/Activity/Import/IsActivityReadyForProcessingJob.php | 10 +-
app/Jobs/Calendar/SetupCalendarSync.php | 21 +-
app/Jobs/ImportRemoteTrackJob.php | 96 ++-
app/Jobs/Mailbox/EmailTextRelay.php | 15 +-
app/Mcp/Contracts/McpCallRepositoryInterface.php | 30 +
app/Mcp/DTO/ListCallsFilters.php | 29 +
app/Mcp/Errors/McpError.php | 123 ++++
app/Mcp/Repositories/McpActivityHydrator.php | 145 ++++
app/Mcp/Repositories/McpCallRepository.php | 84 +++
app/Mcp/Repositories/McpElasticCallRepository.php | 171 +++++
app/Mcp/Servers/JiminnyServer.php | 38 +
app/Mcp/Tools/ListCallsTool.php | 205 ++++++
app/Models/Activity.php | 10 +-
app/Models/Activity/Transcription.php | 17 +-
app/Models/ElasticSearch/OpportunityElasticSearchTrait.php | 5 +
app/Models/Participant.php | 1 +
app/Providers/AppServiceProvider.php | 22 +
app/Repositories/Crm/ContactRepository.php | 69 +-
app/Repositories/ParticipantSpeechRepository.php | 13 +-
app/Services/Activity/ParticipantsService.php | 19 +-
app/Services/Activity/Twilio/S3RecordingCredentialsService.php | 82 +++
app/Services/ActivityService.php | 21 +-
app/Services/Calendar/CalendarActivityService.php | 46 ++
app/Services/Calendar/Command/ImportParticipants.php | 1 +
app/Services/Calendar/Command/MapActivityData.php | 106 +--
app/Services/Calendar/GoogleCalendarService.php | 12 +-
app/Services/Crm/Close/Processor/OpportunityProcessor.php | 2 +-
app/Services/Crm/Close/Service.php | 22 +-
app/Services/Crm/Copper/Service.php | 12 +-
app/Services/Crm/Hubspot/Service.php | 154 +++-
app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php | 88 ++-
app/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTrait.php | 22 +-
app/Services/Crm/Pipedrive/Service.php | 17 +-
app/Services/Crm/Salesforce/Service.php | 42 +-
app/Services/Mail/Office/EmailApiClient.php | 129 +---
app/Services/RecallAI/Commands/ScheduleBotCommand.php | 39 +-
app/Services/RecallAI/RecallAIService.php | 22 +-
composer.json | 3 +-
composer.lock | 87 ++-
config/mcp.php | 23 +
database/migrations/2026_04_30_120000_create_mcp_audit_log_table.php | 36 +
docs/mcp/explorer/explorer.html | 697 ++++++++++++++++++
docs/mcp/explorer/explorer.template.html | 697 ++++++++++++++++++
docs/mcp/explorer/generate.js | 215 ++++++
docs/mcp/explorer/tool-explorer-meta.json | 11 +
docs/mcp/tools-list.json | 2536 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
docs/mcp/tools.md | 621 ++++++++++++++++
front-end/package.json | 4 +-
front-end/src/components/Settings/OrgSettings/AiAutomation/CrmFilling/TemplateFieldForm.vue | 28 +-
front-end/src/components/Settings/OrgSettings/Playbooks/AddEditPlaybook.vue | 10 +
front-end/src/components/playback/comments/ActivityComment.less | 10 +-
front-end/src/components/shared/PromptTester/PromptTester.vue | 12 +-
front-end/src/components/shared/__tests__/PromptTester.spec.js | 35 +
front-end/src/components/shared/modals/EntityPickerModal/__tests__/useEntitiesCache.spec.ts | 37 +
front-end/src/components/shared/modals/EntityPickerModal/useEntitiesCache.ts | 9 +
front-end/yarn.lock | 16 +-
phpstan-baseline.neon | 50 --
routes/api.php | 11 +
sonar-project.properties | 91 ++-
tests/Feature/Component/Nudge/ProcessOrganisationImmediateNudgesJobTest.php | 534 ++++++++++++++
tests/Feature/Jobs/ImportRemoteTrackJobTest.php | 283 +++++++-
tests/Feature/Mcp/IssueMcpTokenCommandTest.php | 53 ++
tests/Feature/Mcp/ListCallsToolElasticFeatureTest.php | 155 ++++
tests/Feature/Mcp/ListCallsToolFeatureTest.php | 352 ++++++++++
tests/Feature/Mcp/McpTestHelpersTrait.php | 77 ++
tests/Feature/Services/Team/TeamDeleteHandlers/Retention/RetentionRepositoryHandlerTest.php | 1 +
tests/Stubs/SentryStub.php | 18 +
tests/Unit/Component/ActivityAnalytics/Service/CalculateTalkTimeOffsetFromTranscriptionTest.php | 28 +-
tests/Unit/Component/AiActivityType/Services/AiActivityTypeEligibilityCheckerTest.php | 103 ++-
tests/Unit/Component/AiAutomation/Actions/PrepareUpdateDtoActionTest.php | 91 +++
tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheckerTest.php | 124 ++++
tests/Unit/Component/AiAutomation/TestCrmAiPromptServiceTest.php | 67 +-
tests/Unit/Component/AiCallScoring/Services/AiCallScoringEligibilityCheckerTest.php | 55 ++
tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.php | 135 ----
tests/Unit/Component/ES/Processor/Actions/LoadDocumentsActionTest.php | 220 ++++++
tests/Unit/Component/ES/Processor/EntityQueryBuilderTest.php | 21 +-
tests/Unit/Component/ES/Processor/Traits/SkipActivityTraitTest.php | 51 --
tests/Unit/Component/ES/Worker/ActivityWorkerTest.php | 174 -----
tests/Unit/Component/ES/Worker/EntityWorkerTest.php | 97 ---
tests/Unit/Component/ES/Worker/WorkerAmountTest.php | 116 ---
tests/Unit/Component/Encoding/Job/AnalyzeTrackChannelsJobTest.php | 52 +-
tests/Unit/Component/Encoding/Service/GenerateSpeechFromSilenceServiceTest.php | 171 ++---
tests/Unit/Component/FFMpeg/Services/GetSpeechIntervalsTest.php | 36 +-
tests/Unit/Component/LanguageDetection/Services/FindSpeechTimeServiceTest.php | 20 +-
tests/Unit/Component/MobileSettings/MobileSettingsControllerTest.php | 5 +-
tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCreatorTest.php | 75 ++
tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleterTest.php | 63 ++
tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesProviderTest.php | 134 ++++
tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesUploaderTest.php | 57 ++
tests/Unit/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeechesServiceTest.php | 51 +-
tests/Unit/Component/Transcription/Diarization/Source/MeetingBotSourceTest.php | 29 +-
tests/Unit/Contracts/Services/Calendar/CalendarTraitTest.php | 58 +-
tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.php | 159 +++++
tests/Unit/Jobs/Activity/Import/ImportTwilioVideoSpeechesJobTest.php | 22 +-
tests/Unit/Jobs/Activity/Import/IsActivityReadyForProcessingJobTest.php | 26 +-
tests/Unit/Jobs/Calendar/SetupCalendarSyncTest.php | 25 -
tests/Unit/Services/Activity/ParticipantsServiceTest.php | 12 +-
tests/Unit/Services/Activity/Twilio/S3RecordingCredentialsServiceTest.php | 180 +++++
tests/Unit/Services/ActivityServiceTest.php | 132 ++++
tests/Unit/Services/Calendar/CalendarActivityServiceTest.php | 150 +++-
tests/Unit/Services/Calendar/Command/ImportParticipantsTest.php | 6 +-
tests/Unit/Services/Calendar/Command/MapActivityDataTest.php | 78 +-
tests/Unit/Services/Calendar/GoogleCalendarServiceTest.php | 116 +++
tests/Unit/Services/Crm/Close/ServiceTest.php | 165 +++++
tests/Unit/Services/Crm/Hubspot/ServiceTest.php | 272 ++++++-
tests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTest.php | 25 +-
tests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTraitMatchActivitiesTest.php | 3 +-
tests/Unit/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTraitOpportunitiesTest.php | 40 ++
tests/Unit/Services/Crm/Pipedrive/ImportOpportunityMatchActivitiesTest.php | 2 +
tests/Unit/Services/Crm/Salesforce/ServiceTest.php | 139 ++++
tests/Unit/Services/Mail/Office/EmailApiClientTest.php | 195 ++---
tests/Unit/Services/RecallAI/RecallAIServiceTest.php | 24 +-
175 files changed, 12562 insertions(+), 2162 deletions(-)
create mode 120000 CLAUDE.md
create mode 100644 app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.php
delete mode 100644 app/Component/ES/ElasticSearchWorkerManager.php
delete mode 100644 app/Component/ES/Processor/Traits/SkipActivityTrait.php
delete mode 100644 app/Component/ES/Worker/ActivityWorker.php
delete mode 100644 app/Component/ES/Worker/EntityWorker.php
delete mode 100644 app/Component/ES/Worker/WorkerAmount.php
delete mode 100644 app/Component/ES/Worker/WorkerInterface.php
create mode 100644 app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.php
create mode 100644 app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/NoAssemblyIdException.php
create mode 100644 app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNotCorrectFormatException.php
create mode 100644 app/Console/Commands/Activities/SetupIntegration/TwilioSetS3RecordingCredentialsCommand.php
create mode 100644 app/Console/Commands/Crm/BackfillOpportunityUserFromAccountCommand.php
delete mode 100644 app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.php
create mode 100644 app/Console/Commands/IssueMcpTokenCommand.php
create mode 100644 app/Http/Middleware/McpAuditMiddleware.php
create mode 100644 app/Http/Middleware/McpTierMiddleware.php
create mode 100644 app/Mcp/Contracts/McpCallRepositoryInterface.php
create mode 100644 app/Mcp/DTO/ListCallsFilters.php
create mode 100644 app/Mcp/Errors/McpError.php
create mode 100644 app/Mcp/Repositories/McpActivityHydrator.php
create mode 100644 app/Mcp/Repositories/McpCallRepository.php
create mode 100644 app/Mcp/Repositories/McpElasticCallRepository.php
create mode 100644 app/Mcp/Servers/JiminnyServer.php
create mode 100644 app/Mcp/Tools/ListCallsTool.php
create mode 100644 app/Services/Activity/Twilio/S3RecordingCredentialsService.php
create mode 100644 config/mcp.php
create mode 100644 database/migrations/2026_04_30_120000_create_mcp_audit_log_table.php
create mode 100644 docs/mcp/explorer/explorer.html
create mode 100644 docs/mcp/explorer/explorer.template.html
create mode 100644 docs/mcp/explorer/generate.js
create mode 100644 docs/mcp/explorer/tool-explorer-meta.json
create mode 100644 docs/mcp/tools-list.json
create mode 100644 docs/mcp/tools.md
create mode 100644 front-end/src/components/shared/modals/EntityPickerModal/__tests__/useEntitiesCache.spec.ts
create mode 100644 tests/Feature/Component/Nudge/ProcessOrganisationImmediateNudgesJobTest.php
create mode 100644 tests/Feature/Mcp/IssueMcpTokenCommandTest.php
create mode 100644 tests/Feature/Mcp/ListCallsToolElasticFeatureTest.php
create mode 100644 tests/Feature/Mcp/ListCallsToolFeatureTest.php
create mode 100644 tests/Feature/Mcp/McpTestHelpersTrait.php
create mode 100644 tests/Stubs/SentryStub.php
create mode 100644 tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheckerTest.php
delete mode 100644 tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.php
create mode 100644 tests/Unit/Component/ES/Processor/Actions/LoadDocumentsActionTest.php
delete mode 100644 tests/Unit/Component/ES/Processor/Traits/SkipActivityTraitTest.php
delete mode 100644 tests/Unit/Component/ES/Worker/ActivityWorkerTest.php
delete mode 100644 tests/Unit/Component/ES/Worker/EntityWorkerTest.php
delete mode 100644 tests/Unit/Component/ES/Worker/WorkerAmountTest.php
create mode 100644 tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCreatorTest.php
create mode 100644 tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.php
create mode 100644 tests/Unit/Services/Activity/Twilio/S3RecordingCredentialsServiceTest.php
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ git status
On branch master
Your branch is behind 'origin/master' by 114 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: .env.local
modified: app/Component/SCIM/Constants.php
modified: app/Component/SCIM/ScimProvisioning.php
modified: app/Component/Twilio/Conference/ConferenceManager/SoftPhoneManager.php
modified: app/Console/Commands/JiminnyDebugCommand.php
modified: app/DTO/SCIM/AAD/Request/CoreUserRequest.php
modified: app/DTO/SCIM/AAD/Response/CoreUser.php
modified: app/Services/Telephony/TextMessagingService.php
modified: config/logging.php
Untracked files:
(use "git add <file>..." to include in what will be committed)
.env.nikilocal
.env.other
WEBHOOK_FILTERING_IMPLEMENTATION.md
app/Component/SCIM/Mutators/Attributes/User/RoleAttr.php
app/Console/Commands/Crm/Hubspot/SimulateWebhooksCommand.php
app/Console/Commands/Reports/CreateMockAskJiminnyReportResultCommand.php
app/Rules/ListenerRoleCannotHaveAdminOrManagerPermissionRule.php
ids.txt
public/favicon.ico
raw_sql_query.sql
tests/Unit/Component/SCIM/Mutators/Attributes/User/RoleAttrTest.php
tests/Unit/Policies/CanAccessAiReportsTest.php
tests/Unit/Rules/ListenerRoleCannotHaveAdminOrManagerPermissionRuleTest.php
no changes added to commit (use "git add" and/or "git commit -a")
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull
remote: Enumerating objects: 306, done.
remote: Counting objects: 100% (299/299), done.
remote: Compressing objects: 100% (183/183), done.
remote: Total 306 (delta 213), reused 171 (delta 116), pack-reused 7 (from 1)
Receiving objects: 100% (306/306), 80.12 KiB | 1000.00 KiB/s, done.
Resolving deltas: 100% (213/213), completed with 53 local objects.
From github.com:jiminny/app
90bca4e4b2..5604af40cf master -> origin/master
4e7078fd8b..0b8343d179 JY-18091-upgrade-to-php-8-5 -> origin/JY-18091-upgrade-to-php-8-5
098eeaa087..d5a447e492 JY-20613-allow-owner-role-on-team-setup -> origin/JY-20613-allow-owner-role-on-team-setup
c3a76ace91..af65249d0f JY-20749-user-can-view-recorded-meetings -> origin/JY-20749-user-can-view-recorded-meetings
d94a285ae7..7ce96cb5fe JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue
* [new branch] JY-20842-remove-partial-updater -> origin/JY-20842-remove-partial-updater
* [new branch] JY-20920-fix-participant-flip -> origin/JY-20920-fix-participant-flip
* [new branch] secfix/npm-20260519 -> origin/secfix/npm-20260519
Updating cb4ebf0c36..5604af40cf
Fast-forward
app/Component/ES/ChunkSize.php | 54 +++++++++++++++++++
app/Component/ES/Processor/DTOs/SelectionList.php | 4 +-
app/Component/ES/Processor/TargetEntitiesSelector.php | 19 ++++---
app/Component/MeetingBot/Service/ParticipantMatcher.php | 46 ++++++++++++----
app/Exceptions/RateLimitException.php | 19 ++++++-
app/Http/Middleware/McpTierMiddleware.php | 27 ++--------
app/Jobs/Crm/MatchActivityCrmData.php | 47 ++++++++++++----
app/Jobs/Middleware/HandleHubspotRateLimit.php | 42 +++++++++++++++
app/Mcp/Servers/JiminnyServer.php | 2 +
app/Mcp/Tools/GetMeTool.php | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++
app/Models/Feature/FeatureEnum.php | 1 +
app/Services/Activity/HubSpot/ProviderResolver.php | 4 +-
app/Services/Activity/HubSpot/ProviderResolverInterface.php | 2 +-
app/Services/Activity/HubSpot/Providers/Provider.php | 2 +-
app/Services/Activity/HubSpot/Providers/ProviderKixie.php | 2 +-
app/Services/Activity/HubSpot/Providers/ProviderOrum.php | 2 +-
app/Services/Activity/HubSpot/Providers/ProviderTwilio.php | 2 +-
app/Services/Activity/HubSpot/Providers/ProviderTwilioFlex.php | 5 +-
app/Services/Activity/HubSpot/Service.php | 97 +++++++++++++++++++++++++++------
app/Services/Crm/Hubspot/Client.php | 132 +++++++++++++++++++++++++++++++++++++++++++++
app/Services/Crm/Hubspot/HubspotClientInterface.php | 15 ++++++
app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php | 21 ++++----
app/Services/Crm/Hubspot/Pagination/PaginationState.php | 2 +-
database/migrations/2026_05_13_124153_create_mcp_feature_flag.php | 25 +++++++++
tests/Feature/Mcp/GetMeToolFeatureTest.php | 140 +++++++++++++++++++++++++++++++++++++++++++++++
tests/Feature/Mcp/ListCallsToolFeatureTest.php | 2 +-
tests/Feature/Mcp/McpTestHelpersTrait.php | 19 ++++++-
tests/Unit/Component/ES/ChunkSizeTest.php | 50 +++++++++++++++++
tests/Unit/Component/ES/Processor/DTOs/SelectionListTest.php | 27 +++++++---
tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 39 ++++++++------
tests/Unit/Component/MeetingBot/Service/ParticipantMatcherTest.php | 68 ++++++++++++++++++++++-
tests/Unit/Exceptions/RateLimitExceptionTest.php | 56 +++++++++++++++++++
tests/Unit/Jobs/Crm/MatchActivityCrmDataTest.php | 8 +--
tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++
tests/Unit/Services/Activity/HubSpot/ServiceTest.php | 109 +++++++++++++++++++++++++++++++++++++
tests/Unit/Services/Crm/Hubspot/ClientTest.php | 250 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/Unit/Services/Crm/Hubspot/Pagination/HubspotPaginationServiceTest.php | 283 +++++++++++++++++++++---------------------------------------------------------------------------
37 files changed, 1587 insertions(+), 344 deletions(-)
create mode 100644 app/Component/ES/ChunkSize.php
create mode 100644 app/Jobs/Middleware/HandleHubspotRateLimit.php
create mode 100644 app/Mcp/Tools/GetMeTool.php
create mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.php
create mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.php
create mode 100644 tests/Unit/Component/ES/ChunkSizeTest.php
create mode 100644 tests/Unit/Exceptions/RateLimitExceptionTest.php
create mode 100644 tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull
Already up to date.
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20676-delete-report-related-objects
Switched to a new branch 'JY-20676-delete-report-related-objects'
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20676-delete-report-related-objects) $ csfix
docker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff
PHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.
PHP runtime: 8.3.30
Running analysis on 7 cores with 10 files per process.
Parallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!
Loaded config default from ".php-cs-fixer.dist.php".
5690/5690 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
1) app/Console/Commands/JiminnyDebugCommand.php (statement_indentation, blank_line_before_statement)
---------- begin diff ----------
--- /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php
+++ /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php
@@ -23,6 +23,7 @@
if ($action === 'redis-set') {
$this->testRedisSet();
+
return;
}
@@ -45,7 +46,7 @@
$ttl = 60;
try {
-// $result = Redis::set($testKey, $testValue, 'EX', $ttl, 'NX');
+ // $result = Redis::set($testKey, $testValue, 'EX', $ttl, 'NX');
$result = Redis::set($testKey, $testValue, ['nx', 'ex' => $ttl]);
if ($result) {
----------- end diff -----------
Fixed 1 of 5690 files i...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
57080
|
NULL
|
0
|
2026-05-19T08:53:42.022696+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779180822022_m1.jpg...
|
iTerm2
|
APP (-zsh)
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Last login: Mon May 18 09:17:28 on ttys007
Poetry Last login: Mon May 18 09:17:28 on ttys007
Poetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parents
Poetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parents
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ co master
error: Your local changes to the following files would be overwritten by checkout:
PIPEDRIVE_V2_MIGRATION_TICKETS.md
Please commit your changes or stash them before you switch branches.
Aborting
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ git pull
remote: Enumerating objects: 1047, done.
remote: Counting objects: 100% (832/832), done.
remote: Compressing objects: 100% (298/298), done.
remote: Total 1047 (delta 634), reused 596 (delta 534), pack-reused 215 (from 3)
Receiving objects: 100% (1047/1047), 353.16 KiB | 1.56 MiB/s, done.
Resolving deltas: 100% (687/687), completed with 107 local objects.
From github.com:jiminny/app
907c54896c..34656c53ed pipedrive-sdk-poc -> origin/pipedrive-sdk-poc
03325ec50f..4e7078fd8b JY-18091-upgrade-to-php-8-5 -> origin/JY-18091-upgrade-to-php-8-5
e7d231e163..bc6a3fce6b JY-20725-handle-HS-search-rate-limit -> origin/JY-20725-handle-HS-search-rate-limit
* [new branch] JY-20749-user-can-view-recorded-meetings -> origin/JY-20749-user-can-view-recorded-meetings
98ca281a04..e0351be069 JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue
569abb5149..3906a9238a JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details -> origin/JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details
ad6c2a86e8..50eb6afba9 JY-20846-mcp-enable-the-ai-to-know-details-about-the-user -> origin/JY-20846-mcp-enable-the-ai-to-know-details-about-the-user
* [new branch] JY-20893-chunk-control-per-update-target -> origin/JY-20893-chunk-control-per-update-target
31c62924a5..cb4ebf0c36 master -> origin/master
Updating 907c54896c..34656c53ed
Fast-forward
PIPEDRIVE_V2_MIGRATION_TICKETS.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 52 insertions(+)
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ co master
M .env.local
M config/logging.php
Switched to branch 'master'
Your branch is behind 'origin/master' by 31 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull
Updating 31c62924a5..cb4ebf0c36
Fast-forward
app/Component/ES/Processor/Traits/SelectEntityListTrait.php | 20 ------
app/Services/Calendar/CalendarActivityService.php | 46 +++++++++++++
app/Services/Calendar/Command/MapActivityData.php | 106 +++-------------------------
docs/mcp/explorer/explorer.html | 104 +++++++++++++++++++++++++---
docs/mcp/explorer/explorer.template.html | 102 ++++++++++++++++++++++++---
docs/mcp/tools-list.json | 373 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
docs/mcp/tools.md | 117 +++++++++++++++++++++++--------
tests/Unit/Component/ES/AsyncUpdateElasticSearchTest.php | 16 +----
tests/Unit/Component/ES/Listeners/UpdateMultipleTargetsListenerTest.php | 10 ---
tests/Unit/Component/ES/Listeners/UpdateSingleTargetListenerTest.php | 6 --
tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 9 ---
tests/Unit/Component/ES/Processor/Traits/SelectEntityListTraitTest.php | 15 ++--
tests/Unit/Component/ES/UpdateProcessManagerTest.php | 2 -
tests/Unit/Services/Calendar/CalendarActivityServiceTest.php | 150 ++++++++++++++++++++++++++++++++++++++--
tests/Unit/Services/Calendar/Command/MapActivityDataTest.php | 78 ++-------------------
15 files changed, 832 insertions(+), 322 deletions(-)
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20613-allow-owner-role-on-team-setup
Switched to a new branch 'JY-20613-allow-owner-role-on-team-setup'
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ csfix
docker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff
PHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.
PHP runtime: 8.3.30
Running analysis on 7 cores with 10 files per process.
Parallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!
Loaded config default from ".php-cs-fixer.dist.php".
5682/5682 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
Fixed 0 of 5682 files in 56.978 seconds, 67.00 MB memory used
What's next:
Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1
Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ csfix
docker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff
PHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.
PHP runtime: 8.3.30
Running analysis on 7 cores with 10 files per process.
Parallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!
Loaded config default from ".php-cs-fixer.dist.php".
5682/5682 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
Fixed 0 of 5682 files in 49.910 seconds, 60.00 MB memory used
What's next:
Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1
Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git pull
remote: Enumerating objects: 248, done.
remote: Counting objects: 100% (128/128), done.
remote: Compressing objects: 100% (23/23), done.
remote: Total 59 (delta 43), reused 44 (delta 33), pack-reused 0 (from 0)
Unpacking objects: 100% (59/59), 10.48 KiB | 228.00 KiB/s, done.
From github.com:jiminny/app
b7df560451..190239dfd4 JY-20613-allow-owner-role-on-team-setup -> origin/JY-20613-allow-owner-role-on-team-setup
e0351be069..d94a285ae7 JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue
* [new branch] JY-20920-fix-participant-matcher -> origin/JY-20920-fix-participant-matcher
cb4ebf0c36..90bca4e4b2 master -> origin/master
Merge made by the 'ort' strategy.
app/Component/ES/ChunkSize.php | 54 +++++++++++++++++++++++++++
app/Component/ES/Processor/DTOs/SelectionList.php | 4 +-
app/Component/ES/Processor/TargetEntitiesSelector.php | 19 ++++++----
app/Http/Middleware/McpTierMiddleware.php | 27 +++-----------
app/Mcp/Servers/JiminnyServer.php | 2 +
app/Mcp/Tools/GetMeTool.php | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
app/Models/Feature/FeatureEnum.php | 1 +
database/migrations/2026_05_13_124153_create_mcp_feature_flag.php | 25 +++++++++++++
front-end/src/components/Settings/Kiosk/modals/EditTeamModal/EditTeamModal.vue | 52 ++++++++++++++++++--------
front-end/src/components/Settings/Kiosk/modals/EditTeamModal/__tests__/EditTeamModal.spec.js | 14 +++++++
tests/Feature/Mcp/GetMeToolFeatureTest.php | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/Feature/Mcp/ListCallsToolFeatureTest.php | 2 +-
tests/Feature/Mcp/McpTestHelpersTrait.php | 19 +++++++++-
tests/Unit/Component/ES/ChunkSizeTest.php | 50 +++++++++++++++++++++++++
tests/Unit/Component/ES/Processor/DTOs/SelectionListTest.php | 27 ++++++++++----
tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 39 +++++++++++---------
16 files changed, 557 insertions(+), 75 deletions(-)
create mode 100644 app/Component/ES/ChunkSize.php
create mode 100644 app/Mcp/Tools/GetMeTool.php
create mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.php
create mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.php
create mode 100644 tests/Unit/Component/ES/ChunkSizeTest.php
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git push
Enumerating objects: 40, done.
Counting objects: 100% (34/34), done.
Delta compression using up to 8 threads
Compressing objects: 100% (18/18), done.
Writing objects: 100% (18/18), 1.58 KiB | 1.58 MiB/s, done.
Total 18 (delta 15), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (15/15), completed with 13 local objects.
To github.com:jiminny/app.git
190239dfd4..ec1b261264 JY-20613-allow-owner-role-on-team-setup -> JY-20613-allow-owner-role-on-team-setup
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ gbr
* JY-20613-allow-owner-role-on-team-setup
pipedrive-sdk-poc
master
JY-20903-update_activity-stage-on-opportunity-change
JY-20904-fix-update-es-on-activity-command
JY-20891-improve-sms-text-relays
JY-20725-handle-HS-search-rate-limit
JY-20818-move-AJ-reports-to-separated-datadog-metric
JY-20773-fix-automated-reports-user-pilot-tracking
JY-20157-AJ-report-not-send-notification
JY-20508-notify-before-AJ-report-expiration
JY-20372-ai-reports-promotion-pages
JY-20352-sync-opportunities-without-a-local-owner-user-id-is-null
JY-20738-debug-AJ-tracking-UP
a
JY-18909-automated-reports-ask-jiminny
JY-20692-fix-integration-app-[API_KEY]
JY-20553-debug-crm-sync-delays
JY-20698-fix-SF-activity-types-on-new-playbook
JY-20543-AJ-report-tracking
JY-20384-handle-auto-sync-with-no-access-to-event-type
JY-20458-ask-jiminny-user-definitions
JY-19666-fix-import-contacts-account-association
JY-19666-HS-import-contacts-and-accounts-batch-job
JY-20458-Ask-Jiminny-Reports
JY-20200-batch-update-CRM-objects-Salesforce
JY-19666-HS-webhooks-add-contact-and-company
JY-20348-trigger-setup-DI-layout-on-team-creation
JY-20326-refactor-info-message-in-command
JY-20317-fix-auto-log-delay-issue-on-all-channels-disabled
JY-20312-remove-on-update-change-last-synced-at-crm-configurations
JY-20306-SF-skip-auto-sync-for-task-based-playbook
JY-20192-remove-deleted-team-from-saved-search-filters
JY-20197-import-opportunity-batch-job
JY-20293-enable-status-field-for-pipedrive-deals
JY-20191-remove-commands-interactive-prompts
JY-20118-change-default-sync-strategy
JY-20183-add-cache-on-auto-log-delay
JY-20197-add-import-opportunity-batch-job
20118-hs-opportunity-make-webhook-strategy-default
JY-20118-make-default-hs-opportunity-sync-strategy-webhook-based
JY-20196-handle-opportunity-without-note
JY-20118-improve-opportunity-import
JY-20189-handle-activity-search-on-deleted-groups
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ co JY-20725-handle-HS-search-rate-limit
M .env.local
M config/logging.php
Switched to branch 'JY-20725-handle-HS-search-rate-limit'
Your branch is behind 'origin/JY-20725-handle-HS-search-rate-limit' by 439 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ git pull
Updating 0f3e438941..bc6a3fce6b
Fast-forward
.gitignore | 3 +-
.windsurfrules | 168 ++---
CLAUDE.md | 1 +
app/Component/ActivityAnalytics/Service/CalculateTalkTimeOffsetsFromTranscription.php | 24 +-
app/Component/AiActivityType/Services/AiActivityTypeEligibilityChecker.php | 28 +-
app/Component/AiAutomation/Actions/PrepareUpdateDtoAction.php | 32 +-
app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.php | 47 ++
app/Component/AiAutomation/TestCrmAiPromptService.php | 14 +
app/Component/AiCallScoring/Services/AiCallScoringEligibilityChecker.php | 9 +
app/Component/ES/ElasticSearchDocumentPartialUpdater.php | 13 +-
app/Component/ES/ElasticSearchWorkerManager.php | 86 ---
app/Component/ES/Processor/Actions/LoadDocumentsAction.php | 80 +--
app/Component/ES/Processor/EntityQueryBuilder.php | 12 +-
app/Component/ES/Processor/TargetEntitiesSelector.php | 2 +-
app/Component/ES/Processor/Traits/SkipActivityTrait.php | 25 -
app/Component/ES/Repositories/EsResetActivityRepository.php | 11 +-
app/Component/ES/Worker/ActivityWorker.php | 73 --
app/Component/ES/Worker/EntityWorker.php | 44 --
app/Component/ES/Worker/WorkerAmount.php | 60 --
app/Component/ES/Worker/WorkerInterface.php | 15 -
app/Component/ElasticSearch/Contract/Searchable.php | 4 +
app/Component/Encoding/Job/AnalyzeTrackChannelsJob.php | 20 +-
app/Component/Encoding/Service/GenerateSpeechFromSilenceService.php | 85 ++-
app/Component/FFMpeg/Services/GetSpeechIntervalsService.php | 18 +-
app/Component/LanguageDetection/Services/FindSpeechTimeService.php | 22 +-
app/Component/Nudge/Job/ProcessOrganisationImmediateNudgesJob.php | 218 +++++-
app/Component/ParagraphBreaker/Services/TranscriptionParagraphsService.php | 4 +
app/Component/ParticipantSpeech/Services/ParticipantSpeechesCreator.php | 33 +
app/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleter.php | 15 +
app/Component/ParticipantSpeech/Services/ParticipantSpeechesProvider.php | 51 +-
app/Component/ParticipantSpeech/Services/ParticipantSpeechesUploader.php | 36 +
app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.php | 11 +
app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/NoAssemblyIdException.php | 11 +
app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/SuccessfulResponse.php | 6 +
app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNotCorrectFormatException.php | 11 +
app/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeechesService.php | 23 +-
app/Component/Transcription/Diarization/Source/MeetingBotSource.php | 16 +-
app/Component/Transcription/TranscriptionProcessor/TranscriptionProcessor.php | 3 +
app/Console/Commands/Activities/ActivityHardDeleteCommand.php | 4 +-
app/Console/Commands/Activities/Copy.php | 2 +
app/Console/Commands/Activities/SetupIntegration/TwilioSetS3RecordingCredentialsCommand.php | 119 ++++
app/Console/Commands/Activities/UpdateActivityElasticSearchDocumentCommand.php | 10 +-
app/Console/Commands/Crm/BackfillOpportunityUserFromAccountCommand.php | 126 ++++
app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.php | 19 -
app/Console/Commands/Elasticsearch/AsyncUpdateEsEntities.php | 50 +-
app/Console/Commands/Elasticsearch/ResetAsyncElasticSearchCommand.php | 30 +-
app/Console/Commands/GeckoExport/GeckoExportParticipantSpeechesCommand.php | 14 +-
app/Console/Commands/IssueMcpTokenCommand.php | 84 +++
app/Console/Commands/JiminnyDebugCommand.php | 7 +-
app/Console/Commands/Tracks/CleanupActivityTracksCommand.php | 2 +-
app/Console/Kernel.php | 6 +-
app/Contracts/Services/Calendar/CalendarTrait.php | 80 ++-
app/Events/AutomatedReports/AutomatedReportGenerated.php | 3 +
app/Http/Controllers/API/AiCallScoring/AiScorecardController.php | 7 +-
app/Http/Controllers/API/TeamAiAutomationController.php | 8 +
app/Http/Controllers/CustomerApi/CustomerApiController.php | 4 +-
app/Http/Controllers/Kiosk/ActivityController.php | 58 +-
app/Http/Controllers/Settings/PlaybookController.php | 15 +-
app/Http/Kernel.php | 23 +
app/Http/Middleware/McpAuditMiddleware.php | 156 ++++
app/Http/Middleware/McpTierMiddleware.php | 54 ++
app/Http/Requests/API/V2/ZapierUploadActivityRequest.php | 28 +-
app/Jobs/Activity/Import/ImportTwilioVideoSpeechesJob.php | 25 +-
app/Jobs/Activity/Import/IsActivityReadyForProcessingJob.php | 10 +-
app/Jobs/Calendar/SetupCalendarSync.php | 21 +-
app/Jobs/ImportRemoteTrackJob.php | 96 ++-
app/Jobs/Mailbox/EmailTextRelay.php | 15 +-
app/Mcp/Contracts/McpCallRepositoryInterface.php | 30 +
app/Mcp/DTO/ListCallsFilters.php | 29 +
app/Mcp/Errors/McpError.php | 123 ++++
app/Mcp/Repositories/McpActivityHydrator.php | 145 ++++
app/Mcp/Repositories/McpCallRepository.php | 84 +++
app/Mcp/Repositories/McpElasticCallRepository.php | 171 +++++
app/Mcp/Servers/JiminnyServer.php | 38 +
app/Mcp/Tools/ListCallsTool.php | 205 ++++++
app/Models/Activity.php | 10 +-
app/Models/Activity/Transcription.php | 17 +-
app/Models/ElasticSearch/OpportunityElasticSearchTrait.php | 5 +
app/Models/Participant.php | 1 +
app/Providers/AppServiceProvider.php | 22 +
app/Repositories/Crm/ContactRepository.php | 69 +-
app/Repositories/ParticipantSpeechRepository.php | 13 +-
app/Services/Activity/ParticipantsService.php | 19 +-
app/Services/Activity/Twilio/S3RecordingCredentialsService.php | 82 +++
app/Services/ActivityService.php | 21 +-
app/Services/Calendar/CalendarActivityService.php | 46 ++
app/Services/Calendar/Command/ImportParticipants.php | 1 +
app/Services/Calendar/Command/MapActivityData.php | 106 +--
app/Services/Calendar/GoogleCalendarService.php | 12 +-
app/Services/Crm/Close/Processor/OpportunityProcessor.php | 2 +-
app/Services/Crm/Close/Service.php | 22 +-
app/Services/Crm/Copper/Service.php | 12 +-
app/Services/Crm/Hubspot/Service.php | 154 +++-
app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php | 88 ++-
app/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTrait.php | 22 +-
app/Services/Crm/Pipedrive/Service.php | 17 +-
app/Services/Crm/Salesforce/Service.php | 42 +-
app/Services/Mail/Office/EmailApiClient.php | 129 +---
app/Services/RecallAI/Commands/ScheduleBotCommand.php | 39 +-
app/Services/RecallAI/RecallAIService.php | 22 +-
composer.json | 3 +-
composer.lock | 87 ++-
config/mcp.php | 23 +
database/migrations/2026_04_30_120000_create_mcp_audit_log_table.php | 36 +
docs/mcp/explorer/explorer.html | 697 ++++++++++++++++++
docs/mcp/explorer/explorer.template.html | 697 ++++++++++++++++++
docs/mcp/explorer/generate.js | 215 ++++++
docs/mcp/explorer/tool-explorer-meta.json | 11 +
docs/mcp/tools-list.json | 2536 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
docs/mcp/tools.md | 621 ++++++++++++++++
front-end/package.json | 4 +-
front-end/src/components/Settings/OrgSettings/AiAutomation/CrmFilling/TemplateFieldForm.vue | 28 +-
front-end/src/components/Settings/OrgSettings/Playbooks/AddEditPlaybook.vue | 10 +
front-end/src/components/playback/comments/ActivityComment.less | 10 +-
front-end/src/components/shared/PromptTester/PromptTester.vue | 12 +-
front-end/src/components/shared/__tests__/PromptTester.spec.js | 35 +
front-end/src/components/shared/modals/EntityPickerModal/__tests__/useEntitiesCache.spec.ts | 37 +
front-end/src/components/shared/modals/EntityPickerModal/useEntitiesCache.ts | 9 +
front-end/yarn.lock | 16 +-
phpstan-baseline.neon | 50 --
routes/api.php | 11 +
sonar-project.properties | 91 ++-
tests/Feature/Component/Nudge/ProcessOrganisationImmediateNudgesJobTest.php | 534 ++++++++++++++
tests/Feature/Jobs/ImportRemoteTrackJobTest.php | 283 +++++++-
tests/Feature/Mcp/IssueMcpTokenCommandTest.php | 53 ++
tests/Feature/Mcp/ListCallsToolElasticFeatureTest.php | 155 ++++
tests/Feature/Mcp/ListCallsToolFeatureTest.php | 352 ++++++++++
tests/Feature/Mcp/McpTestHelpersTrait.php | 77 ++
tests/Feature/Services/Team/TeamDeleteHandlers/Retention/RetentionRepositoryHandlerTest.php | 1 +
tests/Stubs/SentryStub.php | 18 +
tests/Unit/Component/ActivityAnalytics/Service/CalculateTalkTimeOffsetFromTranscriptionTest.php | 28 +-
tests/Unit/Component/AiActivityType/Services/AiActivityTypeEligibilityCheckerTest.php | 103 ++-
tests/Unit/Component/AiAutomation/Actions/PrepareUpdateDtoActionTest.php | 91 +++
tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheckerTest.php | 124 ++++
tests/Unit/Component/AiAutomation/TestCrmAiPromptServiceTest.php | 67 +-
tests/Unit/Component/AiCallScoring/Services/AiCallScoringEligibilityCheckerTest.php | 55 ++
tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.php | 135 ----
tests/Unit/Component/ES/Processor/Actions/LoadDocumentsActionTest.php | 220 ++++++
tests/Unit/Component/ES/Processor/EntityQueryBuilderTest.php | 21 +-
tests/Unit/Component/ES/Processor/Traits/SkipActivityTraitTest.php | 51 --
tests/Unit/Component/ES/Worker/ActivityWorkerTest.php | 174 -----
tests/Unit/Component/ES/Worker/EntityWorkerTest.php | 97 ---
tests/Unit/Component/ES/Worker/WorkerAmountTest.php | 116 ---
tests/Unit/Component/Encoding/Job/AnalyzeTrackChannelsJobTest.php | 52 +-
tests/Unit/Component/Encoding/Service/GenerateSpeechFromSilenceServiceTest.php | 171 ++---
tests/Unit/Component/FFMpeg/Services/GetSpeechIntervalsTest.php | 36 +-
tests/Unit/Component/LanguageDetection/Services/FindSpeechTimeServiceTest.php | 20 +-
tests/Unit/Component/MobileSettings/MobileSettingsControllerTest.php | 5 +-
tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCreatorTest.php | 75 ++
tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleterTest.php | 63 ++
tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesProviderTest.php | 134 ++++
tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesUploaderTest.php | 57 ++
tests/Unit/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeechesServiceTest.php | 51 +-
tests/Unit/Component/Transcription/Diarization/Source/MeetingBotSourceTest.php | 29 +-
tests/Unit/Contracts/Services/Calendar/CalendarTraitTest.php | 58 +-
tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.php | 159 +++++
tests/Unit/Jobs/Activity/Import/ImportTwilioVideoSpeechesJobTest.php | 22 +-
tests/Unit/Jobs/Activity/Import/IsActivityReadyForProcessingJobTest.php | 26 +-
tests/Unit/Jobs/Calendar/SetupCalendarSyncTest.php | 25 -
tests/Unit/Services/Activity/ParticipantsServiceTest.php | 12 +-
tests/Unit/Services/Activity/Twilio/S3RecordingCredentialsServiceTest.php | 180 +++++
tests/Unit/Services/ActivityServiceTest.php | 132 ++++
tests/Unit/Services/Calendar/CalendarActivityServiceTest.php | 150 +++-
tests/Unit/Services/Calendar/Command/ImportParticipantsTest.php | 6 +-
tests/Unit/Services/Calendar/Command/MapActivityDataTest.php | 78 +-
tests/Unit/Services/Calendar/GoogleCalendarServiceTest.php | 116 +++
tests/Unit/Services/Crm/Close/ServiceTest.php | 165 +++++
tests/Unit/Services/Crm/Hubspot/ServiceTest.php | 272 ++++++-
tests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTest.php | 25 +-
tests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTraitMatchActivitiesTest.php | 3 +-
tests/Unit/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTraitOpportunitiesTest.php | 40 ++
tests/Unit/Services/Crm/Pipedrive/ImportOpportunityMatchActivitiesTest.php | 2 +
tests/Unit/Services/Crm/Salesforce/ServiceTest.php | 139 ++++
tests/Unit/Services/Mail/Office/EmailApiClientTest.php | 195 ++---
tests/Unit/Services/RecallAI/RecallAIServiceTest.php | 24 +-
175 files changed, 12562 insertions(+), 2162 deletions(-)
create mode 120000 CLAUDE.md
create mode 100644 app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.php
delete mode 100644 app/Component/ES/ElasticSearchWorkerManager.php
delete mode 100644 app/Component/ES/Processor/Traits/SkipActivityTrait.php
delete mode 100644 app/Component/ES/Worker/ActivityWorker.php
delete mode 100644 app/Component/ES/Worker/EntityWorker.php
delete mode 100644 app/Component/ES/Worker/WorkerAmount.php
delete mode 100644 app/Component/ES/Worker/WorkerInterface.php
create mode 100644 app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.php
create mode 100644 app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/NoAssemblyIdException.php
create mode 100644 app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNotCorrectFormatException.php
create mode 100644 app/Console/Commands/Activities/SetupIntegration/TwilioSetS3RecordingCredentialsCommand.php
create mode 100644 app/Console/Commands/Crm/BackfillOpportunityUserFromAccountCommand.php
delete mode 100644 app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.php
create mode 100644 app/Console/Commands/IssueMcpTokenCommand.php
create mode 100644 app/Http/Middleware/McpAuditMiddleware.php
create mode 100644 app/Http/Middleware/McpTierMiddleware.php
create mode 100644 app/Mcp/Contracts/McpCallRepositoryInterface.php
create mode 100644 app/Mcp/DTO/ListCallsFilters.php
create mode 100644 app/Mcp/Errors/McpError.php
create mode 100644 app/Mcp/Repositories/McpActivityHydrator.php
create mode 100644 app/Mcp/Repositories/McpCallRepository.php
create mode 100644 app/Mcp/Repositories/McpElasticCallRepository.php
create mode 100644 app/Mcp/Servers/JiminnyServer.php
create mode 100644 app/Mcp/Tools/ListCallsTool.php
create mode 100644 app/Services/Activity/Twilio/S3RecordingCredentialsService.php
create mode 100644 config/mcp.php
create mode 100644 database/migrations/2026_04_30_120000_create_mcp_audit_log_table.php
create mode 100644 docs/mcp/explorer/explorer.html
create mode 100644 docs/mcp/explorer/explorer.template.html
create mode 100644 docs/mcp/explorer/generate.js
create mode 100644 docs/mcp/explorer/tool-explorer-meta.json
create mode 100644 docs/mcp/tools-list.json
create mode 100644 docs/mcp/tools.md
create mode 100644 front-end/src/components/shared/modals/EntityPickerModal/__tests__/useEntitiesCache.spec.ts
create mode 100644 tests/Feature/Component/Nudge/ProcessOrganisationImmediateNudgesJobTest.php
create mode 100644 tests/Feature/Mcp/IssueMcpTokenCommandTest.php
create mode 100644 tests/Feature/Mcp/ListCallsToolElasticFeatureTest.php
create mode 100644 tests/Feature/Mcp/ListCallsToolFeatureTest.php
create mode 100644 tests/Feature/Mcp/McpTestHelpersTrait.php
create mode 100644 tests/Stubs/SentryStub.php
create mode 100644 tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheckerTest.php
delete mode 100644 tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.php
create mode 100644 tests/Unit/Component/ES/Processor/Actions/LoadDocumentsActionTest.php
delete mode 100644 tests/Unit/Component/ES/Processor/Traits/SkipActivityTraitTest.php
delete mode 100644 tests/Unit/Component/ES/Worker/ActivityWorkerTest.php
delete mode 100644 tests/Unit/Component/ES/Worker/EntityWorkerTest.php
delete mode 100644 tests/Unit/Component/ES/Worker/WorkerAmountTest.php
create mode 100644 tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCreatorTest.php
create mode 100644 tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.php
create mode 100644 tests/Unit/Services/Activity/Twilio/S3RecordingCredentialsServiceTest.php
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ git status
On branch master
Your branch is behind 'origin/master' by 114 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: .env.local
modified: app/Component/SCIM/Constants.php
modified: app/Component/SCIM/ScimProvisioning.php
modified: app/Component/Twilio/Conference/ConferenceManager/SoftPhoneManager.php
modified: app/Console/Commands/JiminnyDebugCommand.php
modified: app/DTO/SCIM/AAD/Request/CoreUserRequest.php
modified: app/DTO/SCIM/AAD/Response/CoreUser.php
modified: app/Services/Telephony/TextMessagingService.php
modified: config/logging.php
Untracked files:
(use "git add <file>..." to include in what will be committed)
.env.nikilocal
.env.other
WEBHOOK_FILTERING_IMPLEMENTATION.md
app/Component/SCIM/Mutators/Attributes/User/RoleAttr.php
app/Console/Commands/Crm/Hubspot/SimulateWebhooksCommand.php
app/Console/Commands/Reports/CreateMockAskJiminnyReportResultCommand.php
app/Rules/ListenerRoleCannotHaveAdminOrManagerPermissionRule.php
ids.txt
public/favicon.ico
raw_sql_query.sql
tests/Unit/Component/SCIM/Mutators/Attributes/User/RoleAttrTest.php
tests/Unit/Policies/CanAccessAiReportsTest.php
tests/Unit/Rules/ListenerRoleCannotHaveAdminOrManagerPermissionRuleTest.php
no changes added to commit (use "git add" and/or "git commit -a")
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull
remote: Enumerating objects: 306, done.
remote: Counting objects: 100% (299/299), done.
remote: Compressing objects: 100% (183/183), done.
remote: Total 306 (delta 213), reused 171 (delta 116), pack-reused 7 (from 1)
Receiving objects: 100% (306/306), 80.12 KiB | 1000.00 KiB/s, done.
Resolving deltas: 100% (213/213), completed with 53 local objects.
From github.com:jiminny/app
90bca4e4b2..5604af40cf master -> origin/master
4e7078fd8b..0b8343d179 JY-18091-upgrade-to-php-8-5 -> origin/JY-18091-upgrade-to-php-8-5
098eeaa087..d5a447e492 JY-20613-allow-owner-role-on-team-setup -> origin/JY-20613-allow-owner-role-on-team-setup
c3a76ace91..af65249d0f JY-20749-user-can-view-recorded-meetings -> origin/JY-20749-user-can-view-recorded-meetings
d94a285ae7..7ce96cb5fe JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue
* [new branch] JY-20842-remove-partial-updater -> origin/JY-20842-remove-partial-updater
* [new branch] JY-20920-fix-participant-flip -> origin/JY-20920-fix-participant-flip
* [new branch] secfix/npm-20260519 -> origin/secfix/npm-20260519
Updating cb4ebf0c36..5604af40cf
Fast-forward
app/Component/ES/ChunkSize.php | 54 +++++++++++++++++++
app/Component/ES/Processor/DTOs/SelectionList.php | 4 +-
app/Component/ES/Processor/TargetEntitiesSelector.php | 19 ++++---
app/Component/MeetingBot/Service/ParticipantMatcher.php | 46 ++++++++++++----
app/Exceptions/RateLimitException.php | 19 ++++++-
app/Http/Middleware/McpTierMiddleware.php | 27 ++--------
app/Jobs/Crm/MatchActivityCrmData.php | 47 ++++++++++++----
app/Jobs/Middleware/HandleHubspotRateLimit.php | 42 +++++++++++++++
app/Mcp/Servers/JiminnyServer.php | 2 +
app/Mcp/Tools/GetMeTool.php | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++
app/Models/Feature/FeatureEnum.php | 1 +
app/Services/Activity/HubSpot/ProviderResolver.php | 4 +-
app/Services/Activity/HubSpot/ProviderResolverInterface.php | 2 +-
app/Services/Activity/HubSpot/Providers/Provider.php | 2 +-
app/Services/Activity/HubSpot/Providers/ProviderKixie.php | 2 +-
app/Services/Activity/HubSpot/Providers/ProviderOrum.php | 2 +-
app/Services/Activity/HubSpot/Providers/ProviderTwilio.php | 2 +-
app/Services/Activity/HubSpot/Providers/ProviderTwilioFlex.php | 5 +-
app/Services/Activity/HubSpot/Service.php | 97 +++++++++++++++++++++++++++------
app/Services/Crm/Hubspot/Client.php | 132 +++++++++++++++++++++++++++++++++++++++++++++
app/Services/Crm/Hubspot/HubspotClientInterface.php | 15 ++++++
app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php | 21 ++++----
app/Services/Crm/Hubspot/Pagination/PaginationState.php | 2 +-
database/migrations/2026_05_13_124153_create_mcp_feature_flag.php | 25 +++++++++
tests/Feature/Mcp/GetMeToolFeatureTest.php | 140 +++++++++++++++++++++++++++++++++++++++++++++++
tests/Feature/Mcp/ListCallsToolFeatureTest.php | 2 +-
tests/Feature/Mcp/McpTestHelpersTrait.php | 19 ++++++-
tests/Unit/Component/ES/ChunkSizeTest.php | 50 +++++++++++++++++
tests/Unit/Component/ES/Processor/DTOs/SelectionListTest.php | 27 +++++++---
tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 39 ++++++++------
tests/Unit/Component/MeetingBot/Service/ParticipantMatcherTest.php | 68 ++++++++++++++++++++++-
tests/Unit/Exceptions/RateLimitExceptionTest.php | 56 +++++++++++++++++++
tests/Unit/Jobs/Crm/MatchActivityCrmDataTest.php | 8 +--
tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++
tests/Unit/Services/Activity/HubSpot/ServiceTest.php | 109 +++++++++++++++++++++++++++++++++++++
tests/Unit/Services/Crm/Hubspot/ClientTest.php | 250 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/Unit/Services/Crm/Hubspot/Pagination/HubspotPaginationServiceTest.php | 283 +++++++++++++++++++++---------------------------------------------------------------------------
37 files changed, 1587 insertions(+), 344 deletions(-)
create mode 100644 app/Component/ES/ChunkSize.php
create mode 100644 app/Jobs/Middleware/HandleHubspotRateLimit.php
create mode 100644 app/Mcp/Tools/GetMeTool.php
create mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.php
create mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.php
create mode 100644 tests/Unit/Component/ES/ChunkSizeTest.php
create mode 100644 tests/Unit/Exceptions/RateLimitExceptionTest.php
create mode 100644 tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull
Already up to date.
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20676-delete-report-related-objects
Switched to a new branch 'JY-20676-delete-report-related-objects'
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20676-delete-report-related-objects) $ csfix
docker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff
PHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.
PHP runtime: 8.3.30
Running analysis on 7 cores with 10 files per process.
Parallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!
Loaded config default from ".php-cs-fixer.dist.php".
5690/5690 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
1) app/Console/Commands/JiminnyDebugCommand.php (statement_indentation, blank_line_before_statement)
---------- begin diff ----------
--- /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php
+++ /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php
@@ -23,6 +23,7 @@
if ($action === 'redis-set') {
$this->testRedisSet();
+
return;
}
@@ -45,7 +46,7 @@
$ttl = 60;
try {
-// $result = Redis::set($testKey, $testValue, 'EX', $ttl, 'NX');
+ // $result = Redis::set($testKey, $testValue, 'EX', $ttl, 'NX');
$result = Redis::set($testKey, $testValue, ['nx', 'ex' => $ttl]);
if ($result) {
----------- end diff -----------
Fixed 1 of 5690 files i...
|
[{"role":"AXTextArea","text [{"role":"AXTextArea","text":"Last login: Mon May 18 09:17:28 on ttys007\n\nPoetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parents\n\nPoetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parents\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ co master\nerror: Your local changes to the following files would be overwritten by checkout:\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tPIPEDRIVE_V2_MIGRATION_TICKETS.md\nPlease commit your changes or stash them before you switch branches.\nAborting\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ git pull\nremote: Enumerating objects: 1047, done.\nremote: Counting objects: 100% (832/832), done.\nremote: Compressing objects: 100% (298/298), done.\nremote: Total 1047 (delta 634), reused 596 (delta 534), pack-reused 215 (from 3)\nReceiving objects: 100% (1047/1047), 353.16 KiB | 1.56 MiB/s, done.\nResolving deltas: 100% (687/687), completed with 107 local objects.\nFrom github.com:jiminny/app\n 907c54896c..34656c53ed pipedrive-sdk-poc -> origin/pipedrive-sdk-poc\n 03325ec50f..4e7078fd8b JY-18091-upgrade-to-php-8-5 -> origin/JY-18091-upgrade-to-php-8-5\n e7d231e163..bc6a3fce6b JY-20725-handle-HS-search-rate-limit -> origin/JY-20725-handle-HS-search-rate-limit\n * [new branch] JY-20749-user-can-view-recorded-meetings -> origin/JY-20749-user-can-view-recorded-meetings\n 98ca281a04..e0351be069 JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue\n 569abb5149..3906a9238a JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details -> origin/JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details\n ad6c2a86e8..50eb6afba9 JY-20846-mcp-enable-the-ai-to-know-details-about-the-user -> origin/JY-20846-mcp-enable-the-ai-to-know-details-about-the-user\n * [new branch] JY-20893-chunk-control-per-update-target -> origin/JY-20893-chunk-control-per-update-target\n 31c62924a5..cb4ebf0c36 master -> origin/master\nUpdating 907c54896c..34656c53ed\nFast-forward\n PIPEDRIVE_V2_MIGRATION_TICKETS.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 52 insertions(+)\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ co master\nM\u0000\u0000\u0000\u0000\u0000\u0000\t.env.local\nM\u0000\u0000\u0000\u0000\u0000\u0000\tconfig/logging.php\nSwitched to branch 'master'\nYour branch is behind 'origin/master' by 31 commits, and can be fast-forwarded.\n (use \"git pull\" to update your local branch)\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull\nUpdating 31c62924a5..cb4ebf0c36\nFast-forward\n app/Component/ES/Processor/Traits/SelectEntityListTrait.php | 20 ------\n app/Services/Calendar/CalendarActivityService.php | 46 +++++++++++++\n app/Services/Calendar/Command/MapActivityData.php | 106 +++-------------------------\n docs/mcp/explorer/explorer.html | 104 +++++++++++++++++++++++++---\n docs/mcp/explorer/explorer.template.html | 102 ++++++++++++++++++++++++---\n docs/mcp/tools-list.json | 373 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------\n docs/mcp/tools.md | 117 +++++++++++++++++++++++--------\n tests/Unit/Component/ES/AsyncUpdateElasticSearchTest.php | 16 +----\n tests/Unit/Component/ES/Listeners/UpdateMultipleTargetsListenerTest.php | 10 ---\n tests/Unit/Component/ES/Listeners/UpdateSingleTargetListenerTest.php | 6 --\n tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 9 ---\n tests/Unit/Component/ES/Processor/Traits/SelectEntityListTraitTest.php | 15 ++--\n tests/Unit/Component/ES/UpdateProcessManagerTest.php | 2 -\n tests/Unit/Services/Calendar/CalendarActivityServiceTest.php | 150 ++++++++++++++++++++++++++++++++++++++--\n tests/Unit/Services/Calendar/Command/MapActivityDataTest.php | 78 ++-------------------\n 15 files changed, 832 insertions(+), 322 deletions(-)\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20613-allow-owner-role-on-team-setup\nSwitched to a new branch 'JY-20613-allow-owner-role-on-team-setup'\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ csfix\ndocker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff \nPHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.\nPHP runtime: 8.3.30\nRunning analysis on 7 cores with 10 files per process.\nParallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!\nLoaded config default from \".php-cs-fixer.dist.php\".\n 5682/5682 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%\n\n\nFixed 0 of 5682 files in 56.978 seconds, 67.00 MB memory used\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ ;xd\ndocker exec -it docker_lamp_1 bash -c \"mv /usr/local/etc/php/conf.d/xdebug.ini ~/xdebug.ini\"\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\ndocker exec -it docker_lamp_1 supervisorctl restart all\njiminny-worker-processing-2:jiminny-worker-processing-2_00: stopped\njiminny-worker-processing-3:jiminny-worker-processing-3_00: stopped\njiminny-worker-processing-4:jiminny-worker-processing-4_00: stopped\njiminny-worker-processing-5:jiminny-worker-processing-5_00: stopped\njiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00: stopped\nworker-analytics:worker-analytics_00: stopped\nworker-crm-update:worker-crm-update_00: stopped\nworker-download:worker-download_00: stopped\nworker-nudges:worker-nudges_00: stopped\nartisan-schedule:artisan-schedule_00: stopped\nworker-emails:worker-emails_00: stopped\nworker-calendar:worker-calendar_00: stopped\nworker:worker_00: stopped\nworker-conferences:worker-conferences_00: stopped\nworker-crm-sync:worker-crm-sync_00: stopped\njiminny-worker-processing-1:jiminny-worker-processing-1_00: stopped\nworker-audio:worker-audio_00: stopped\nworker-es-update:worker-es-update_00: stopped\nartisan-schedule:artisan-schedule_00: started\njiminny-worker-processing-1:jiminny-worker-processing-1_00: started\njiminny-worker-processing-2:jiminny-worker-processing-2_00: started\njiminny-worker-processing-3:jiminny-worker-processing-3_00: started\njiminny-worker-processing-4:jiminny-worker-processing-4_00: started\njiminny-worker-processing-5:jiminny-worker-processing-5_00: started\njiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00: started\nworker:worker_00: started\nworker-analytics:worker-analytics_00: started\nworker-audio:worker-audio_00: started\nworker-calendar:worker-calendar_00: started\nworker-conferences:worker-conferences_00: started\nworker-crm-sync:worker-crm-sync_00: started\nworker-crm-update:worker-crm-update_00: started\nworker-download:worker-download_00: started\nworker-emails:worker-emails_00: started\nworker-es-update:worker-es-update_00: started\nworker-nudges:worker-nudges_00: started\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\ndocker exec -it docker_lamp_1 php -v\nPHP 8.3.30 (cli) (built: Mar 16 2026 22:32:32) (NTS)\nCopyright (c) The PHP Group\nZend Engine v4.3.30, Copyright (c) Zend Technologies\n with Zend OPcache v8.3.30, Copyright (c), by Zend Technologies\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ csfix\ndocker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff \nPHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.\nPHP runtime: 8.3.30\nRunning analysis on 7 cores with 10 files per process.\nParallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!\nLoaded config default from \".php-cs-fixer.dist.php\".\n 5682/5682 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%\n\n\nFixed 0 of 5682 files in 49.910 seconds, 60.00 MB memory used\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git status\nOn branch JY-20613-allow-owner-role-on-team-setup\nYour branch is ahead of 'origin/JY-20613-allow-owner-role-on-team-setup' by 1 commit.\n (use \"git push\" to publish your local commits)\n\nChanges not staged for commit:\n (use \"git add <file>...\" to update what will be committed)\n (use \"git restore <file>...\" to discard changes in working directory)\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: .env.local\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: config/logging.php\n\nUntracked files:\n (use \"git add <file>...\" to include in what will be committed)\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\t.env.nikilocal\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\t.env.other\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tWEBHOOK_FILTERING_IMPLEMENTATION.md\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Console/Commands/Crm/Hubspot/SimulateWebhooksCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Console/Commands/Reports/CreateMockAskJiminnyReportResultCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tids.txt\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tpublic/favicon.ico\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\traw_sql_query.sql\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ttests/Unit/Policies/CanAccessAiReportsTest.php\n\nno changes added to commit (use \"git add\" and/or \"git commit -a\")\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git pull\nremote: Enumerating objects: 248, done.\nremote: Counting objects: 100% (128/128), done.\nremote: Compressing objects: 100% (23/23), done.\nremote: Total 59 (delta 43), reused 44 (delta 33), pack-reused 0 (from 0)\nUnpacking objects: 100% (59/59), 10.48 KiB | 228.00 KiB/s, done.\nFrom github.com:jiminny/app\n b7df560451..190239dfd4 JY-20613-allow-owner-role-on-team-setup -> origin/JY-20613-allow-owner-role-on-team-setup\n e0351be069..d94a285ae7 JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue\n * [new branch] JY-20920-fix-participant-matcher -> origin/JY-20920-fix-participant-matcher\n cb4ebf0c36..90bca4e4b2 master -> origin/master\nMerge made by the 'ort' strategy.\n app/Component/ES/ChunkSize.php | 54 +++++++++++++++++++++++++++\n app/Component/ES/Processor/DTOs/SelectionList.php | 4 +-\n app/Component/ES/Processor/TargetEntitiesSelector.php | 19 ++++++----\n app/Http/Middleware/McpTierMiddleware.php | 27 +++-----------\n app/Mcp/Servers/JiminnyServer.php | 2 +\n app/Mcp/Tools/GetMeTool.php | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n app/Models/Feature/FeatureEnum.php | 1 +\n database/migrations/2026_05_13_124153_create_mcp_feature_flag.php | 25 +++++++++++++\n front-end/src/components/Settings/Kiosk/modals/EditTeamModal/EditTeamModal.vue | 52 ++++++++++++++++++--------\n front-end/src/components/Settings/Kiosk/modals/EditTeamModal/__tests__/EditTeamModal.spec.js | 14 +++++++\n tests/Feature/Mcp/GetMeToolFeatureTest.php | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n tests/Feature/Mcp/ListCallsToolFeatureTest.php | 2 +-\n tests/Feature/Mcp/McpTestHelpersTrait.php | 19 +++++++++-\n tests/Unit/Component/ES/ChunkSizeTest.php | 50 +++++++++++++++++++++++++\n tests/Unit/Component/ES/Processor/DTOs/SelectionListTest.php | 27 ++++++++++----\n tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 39 +++++++++++---------\n 16 files changed, 557 insertions(+), 75 deletions(-)\n create mode 100644 app/Component/ES/ChunkSize.php\n create mode 100644 app/Mcp/Tools/GetMeTool.php\n create mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.php\n create mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.php\n create mode 100644 tests/Unit/Component/ES/ChunkSizeTest.php\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git push\nEnumerating objects: 40, done.\nCounting objects: 100% (34/34), done.\nDelta compression using up to 8 threads\nCompressing objects: 100% (18/18), done.\nWriting objects: 100% (18/18), 1.58 KiB | 1.58 MiB/s, done.\nTotal 18 (delta 15), reused 0 (delta 0), pack-reused 0\nremote: Resolving deltas: 100% (15/15), completed with 13 local objects.\nTo github.com:jiminny/app.git\n 190239dfd4..ec1b261264 JY-20613-allow-owner-role-on-team-setup -> JY-20613-allow-owner-role-on-team-setup\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ gbr\n* JY-20613-allow-owner-role-on-team-setup\n pipedrive-sdk-poc\n master\n JY-20903-update_activity-stage-on-opportunity-change\n JY-20904-fix-update-es-on-activity-command\n JY-20891-improve-sms-text-relays\n JY-20725-handle-HS-search-rate-limit\n JY-20818-move-AJ-reports-to-separated-datadog-metric\n JY-20773-fix-automated-reports-user-pilot-tracking\n JY-20157-AJ-report-not-send-notification\n JY-20508-notify-before-AJ-report-expiration\n JY-20372-ai-reports-promotion-pages\n JY-20352-sync-opportunities-without-a-local-owner-user-id-is-null\n JY-20738-debug-AJ-tracking-UP\n a\n JY-18909-automated-reports-ask-jiminny\n JY-20692-fix-integration-app-token-auth-response-change\n JY-20553-debug-crm-sync-delays\n JY-20698-fix-SF-activity-types-on-new-playbook\n JY-20543-AJ-report-tracking\n JY-20384-handle-auto-sync-with-no-access-to-event-type\n JY-20458-ask-jiminny-user-definitions\n JY-19666-fix-import-contacts-account-association\n JY-19666-HS-import-contacts-and-accounts-batch-job\n JY-20458-Ask-Jiminny-Reports\n JY-20200-batch-update-CRM-objects-Salesforce\n JY-19666-HS-webhooks-add-contact-and-company\n JY-20348-trigger-setup-DI-layout-on-team-creation\n JY-20326-refactor-info-message-in-command\n JY-20317-fix-auto-log-delay-issue-on-all-channels-disabled\n JY-20312-remove-on-update-change-last-synced-at-crm-configurations\n JY-20306-SF-skip-auto-sync-for-task-based-playbook\n JY-20192-remove-deleted-team-from-saved-search-filters\n JY-20197-import-opportunity-batch-job\n JY-20293-enable-status-field-for-pipedrive-deals\n JY-20191-remove-commands-interactive-prompts\n JY-20118-change-default-sync-strategy\n JY-20183-add-cache-on-auto-log-delay\n JY-20197-add-import-opportunity-batch-job\n 20118-hs-opportunity-make-webhook-strategy-default\n JY-20118-make-default-hs-opportunity-sync-strategy-webhook-based\n JY-20196-handle-opportunity-without-note\n JY-20118-improve-opportunity-import\n JY-20189-handle-activity-search-on-deleted-groups\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ co JY-20725-handle-HS-search-rate-limit\nM\u0000\u0000\u0000\u0000\u0000\u0000\t.env.local\nM\u0000\u0000\u0000\u0000\u0000\u0000\tconfig/logging.php\nSwitched to branch 'JY-20725-handle-HS-search-rate-limit'\nYour branch is behind 'origin/JY-20725-handle-HS-search-rate-limit' by 439 commits, and can be fast-forwarded.\n (use \"git pull\" to update your local branch)\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ git pull\nUpdating 0f3e438941..bc6a3fce6b\nFast-forward\n .gitignore | 3 +-\n .windsurfrules | 168 ++---\n CLAUDE.md | 1 +\n app/Component/ActivityAnalytics/Service/CalculateTalkTimeOffsetsFromTranscription.php | 24 +-\n app/Component/AiActivityType/Services/AiActivityTypeEligibilityChecker.php | 28 +-\n app/Component/AiAutomation/Actions/PrepareUpdateDtoAction.php | 32 +-\n app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.php | 47 ++\n app/Component/AiAutomation/TestCrmAiPromptService.php | 14 +\n app/Component/AiCallScoring/Services/AiCallScoringEligibilityChecker.php | 9 +\n app/Component/ES/ElasticSearchDocumentPartialUpdater.php | 13 +-\n app/Component/ES/ElasticSearchWorkerManager.php | 86 ---\n app/Component/ES/Processor/Actions/LoadDocumentsAction.php | 80 +--\n app/Component/ES/Processor/EntityQueryBuilder.php | 12 +-\n app/Component/ES/Processor/TargetEntitiesSelector.php | 2 +-\n app/Component/ES/Processor/Traits/SkipActivityTrait.php | 25 -\n app/Component/ES/Repositories/EsResetActivityRepository.php | 11 +-\n app/Component/ES/Worker/ActivityWorker.php | 73 --\n app/Component/ES/Worker/EntityWorker.php | 44 --\n app/Component/ES/Worker/WorkerAmount.php | 60 --\n app/Component/ES/Worker/WorkerInterface.php | 15 -\n app/Component/ElasticSearch/Contract/Searchable.php | 4 +\n app/Component/Encoding/Job/AnalyzeTrackChannelsJob.php | 20 +-\n app/Component/Encoding/Service/GenerateSpeechFromSilenceService.php | 85 ++-\n app/Component/FFMpeg/Services/GetSpeechIntervalsService.php | 18 +-\n app/Component/LanguageDetection/Services/FindSpeechTimeService.php | 22 +-\n app/Component/Nudge/Job/ProcessOrganisationImmediateNudgesJob.php | 218 +++++-\n app/Component/ParagraphBreaker/Services/TranscriptionParagraphsService.php | 4 +\n app/Component/ParticipantSpeech/Services/ParticipantSpeechesCreator.php | 33 +\n app/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleter.php | 15 +\n app/Component/ParticipantSpeech/Services/ParticipantSpeechesProvider.php | 51 +-\n app/Component/ParticipantSpeech/Services/ParticipantSpeechesUploader.php | 36 +\n app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.php | 11 +\n app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/NoAssemblyIdException.php | 11 +\n app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/SuccessfulResponse.php | 6 +\n app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNotCorrectFormatException.php | 11 +\n app/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeechesService.php | 23 +-\n app/Component/Transcription/Diarization/Source/MeetingBotSource.php | 16 +-\n app/Component/Transcription/TranscriptionProcessor/TranscriptionProcessor.php | 3 +\n app/Console/Commands/Activities/ActivityHardDeleteCommand.php | 4 +-\n app/Console/Commands/Activities/Copy.php | 2 +\n app/Console/Commands/Activities/SetupIntegration/TwilioSetS3RecordingCredentialsCommand.php | 119 ++++\n app/Console/Commands/Activities/UpdateActivityElasticSearchDocumentCommand.php | 10 +-\n app/Console/Commands/Crm/BackfillOpportunityUserFromAccountCommand.php | 126 ++++\n app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.php | 19 -\n app/Console/Commands/Elasticsearch/AsyncUpdateEsEntities.php | 50 +-\n app/Console/Commands/Elasticsearch/ResetAsyncElasticSearchCommand.php | 30 +-\n app/Console/Commands/GeckoExport/GeckoExportParticipantSpeechesCommand.php | 14 +-\n app/Console/Commands/IssueMcpTokenCommand.php | 84 +++\n app/Console/Commands/JiminnyDebugCommand.php | 7 +-\n app/Console/Commands/Tracks/CleanupActivityTracksCommand.php | 2 +-\n app/Console/Kernel.php | 6 +-\n app/Contracts/Services/Calendar/CalendarTrait.php | 80 ++-\n app/Events/AutomatedReports/AutomatedReportGenerated.php | 3 +\n app/Http/Controllers/API/AiCallScoring/AiScorecardController.php | 7 +-\n app/Http/Controllers/API/TeamAiAutomationController.php | 8 +\n app/Http/Controllers/CustomerApi/CustomerApiController.php | 4 +-\n app/Http/Controllers/Kiosk/ActivityController.php | 58 +-\n app/Http/Controllers/Settings/PlaybookController.php | 15 +-\n app/Http/Kernel.php | 23 +\n app/Http/Middleware/McpAuditMiddleware.php | 156 ++++\n app/Http/Middleware/McpTierMiddleware.php | 54 ++\n app/Http/Requests/API/V2/ZapierUploadActivityRequest.php | 28 +-\n app/Jobs/Activity/Import/ImportTwilioVideoSpeechesJob.php | 25 +-\n app/Jobs/Activity/Import/IsActivityReadyForProcessingJob.php | 10 +-\n app/Jobs/Calendar/SetupCalendarSync.php | 21 +-\n app/Jobs/ImportRemoteTrackJob.php | 96 ++-\n app/Jobs/Mailbox/EmailTextRelay.php | 15 +-\n app/Mcp/Contracts/McpCallRepositoryInterface.php | 30 +\n app/Mcp/DTO/ListCallsFilters.php | 29 +\n app/Mcp/Errors/McpError.php | 123 ++++\n app/Mcp/Repositories/McpActivityHydrator.php | 145 ++++\n app/Mcp/Repositories/McpCallRepository.php | 84 +++\n app/Mcp/Repositories/McpElasticCallRepository.php | 171 +++++\n app/Mcp/Servers/JiminnyServer.php | 38 +\n app/Mcp/Tools/ListCallsTool.php | 205 ++++++\n app/Models/Activity.php | 10 +-\n app/Models/Activity/Transcription.php | 17 +-\n app/Models/ElasticSearch/OpportunityElasticSearchTrait.php | 5 +\n app/Models/Participant.php | 1 +\n app/Providers/AppServiceProvider.php | 22 +\n app/Repositories/Crm/ContactRepository.php | 69 +-\n app/Repositories/ParticipantSpeechRepository.php | 13 +-\n app/Services/Activity/ParticipantsService.php | 19 +-\n app/Services/Activity/Twilio/S3RecordingCredentialsService.php | 82 +++\n app/Services/ActivityService.php | 21 +-\n app/Services/Calendar/CalendarActivityService.php | 46 ++\n app/Services/Calendar/Command/ImportParticipants.php | 1 +\n app/Services/Calendar/Command/MapActivityData.php | 106 +--\n app/Services/Calendar/GoogleCalendarService.php | 12 +-\n app/Services/Crm/Close/Processor/OpportunityProcessor.php | 2 +-\n app/Services/Crm/Close/Service.php | 22 +-\n app/Services/Crm/Copper/Service.php | 12 +-\n app/Services/Crm/Hubspot/Service.php | 154 +++-\n app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php | 88 ++-\n app/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTrait.php | 22 +-\n app/Services/Crm/Pipedrive/Service.php | 17 +-\n app/Services/Crm/Salesforce/Service.php | 42 +-\n app/Services/Mail/Office/EmailApiClient.php | 129 +---\n app/Services/RecallAI/Commands/ScheduleBotCommand.php | 39 +-\n app/Services/RecallAI/RecallAIService.php | 22 +-\n composer.json | 3 +-\n composer.lock | 87 ++-\n config/mcp.php | 23 +\n database/migrations/2026_04_30_120000_create_mcp_audit_log_table.php | 36 +\n docs/mcp/explorer/explorer.html | 697 ++++++++++++++++++\n docs/mcp/explorer/explorer.template.html | 697 ++++++++++++++++++\n docs/mcp/explorer/generate.js | 215 ++++++\n docs/mcp/explorer/tool-explorer-meta.json | 11 +\n docs/mcp/tools-list.json | 2536 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n docs/mcp/tools.md | 621 ++++++++++++++++\n front-end/package.json | 4 +-\n front-end/src/components/Settings/OrgSettings/AiAutomation/CrmFilling/TemplateFieldForm.vue | 28 +-\n front-end/src/components/Settings/OrgSettings/Playbooks/AddEditPlaybook.vue | 10 +\n front-end/src/components/playback/comments/ActivityComment.less | 10 +-\n front-end/src/components/shared/PromptTester/PromptTester.vue | 12 +-\n front-end/src/components/shared/__tests__/PromptTester.spec.js | 35 +\n front-end/src/components/shared/modals/EntityPickerModal/__tests__/useEntitiesCache.spec.ts | 37 +\n front-end/src/components/shared/modals/EntityPickerModal/useEntitiesCache.ts | 9 +\n front-end/yarn.lock | 16 +-\n phpstan-baseline.neon | 50 --\n routes/api.php | 11 +\n sonar-project.properties | 91 ++-\n tests/Feature/Component/Nudge/ProcessOrganisationImmediateNudgesJobTest.php | 534 ++++++++++++++\n tests/Feature/Jobs/ImportRemoteTrackJobTest.php | 283 +++++++-\n tests/Feature/Mcp/IssueMcpTokenCommandTest.php | 53 ++\n tests/Feature/Mcp/ListCallsToolElasticFeatureTest.php | 155 ++++\n tests/Feature/Mcp/ListCallsToolFeatureTest.php | 352 ++++++++++\n tests/Feature/Mcp/McpTestHelpersTrait.php | 77 ++\n tests/Feature/Services/Team/TeamDeleteHandlers/Retention/RetentionRepositoryHandlerTest.php | 1 +\n tests/Stubs/SentryStub.php | 18 +\n tests/Unit/Component/ActivityAnalytics/Service/CalculateTalkTimeOffsetFromTranscriptionTest.php | 28 +-\n tests/Unit/Component/AiActivityType/Services/AiActivityTypeEligibilityCheckerTest.php | 103 ++-\n tests/Unit/Component/AiAutomation/Actions/PrepareUpdateDtoActionTest.php | 91 +++\n tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheckerTest.php | 124 ++++\n tests/Unit/Component/AiAutomation/TestCrmAiPromptServiceTest.php | 67 +-\n tests/Unit/Component/AiCallScoring/Services/AiCallScoringEligibilityCheckerTest.php | 55 ++\n tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.php | 135 ----\n tests/Unit/Component/ES/Processor/Actions/LoadDocumentsActionTest.php | 220 ++++++\n tests/Unit/Component/ES/Processor/EntityQueryBuilderTest.php | 21 +-\n tests/Unit/Component/ES/Processor/Traits/SkipActivityTraitTest.php | 51 --\n tests/Unit/Component/ES/Worker/ActivityWorkerTest.php | 174 -----\n tests/Unit/Component/ES/Worker/EntityWorkerTest.php | 97 ---\n tests/Unit/Component/ES/Worker/WorkerAmountTest.php | 116 ---\n tests/Unit/Component/Encoding/Job/AnalyzeTrackChannelsJobTest.php | 52 +-\n tests/Unit/Component/Encoding/Service/GenerateSpeechFromSilenceServiceTest.php | 171 ++---\n tests/Unit/Component/FFMpeg/Services/GetSpeechIntervalsTest.php | 36 +-\n tests/Unit/Component/LanguageDetection/Services/FindSpeechTimeServiceTest.php | 20 +-\n tests/Unit/Component/MobileSettings/MobileSettingsControllerTest.php | 5 +-\n tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCreatorTest.php | 75 ++\n tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleterTest.php | 63 ++\n tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesProviderTest.php | 134 ++++\n tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesUploaderTest.php | 57 ++\n tests/Unit/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeechesServiceTest.php | 51 +-\n tests/Unit/Component/Transcription/Diarization/Source/MeetingBotSourceTest.php | 29 +-\n tests/Unit/Contracts/Services/Calendar/CalendarTraitTest.php | 58 +-\n tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.php | 159 +++++\n tests/Unit/Jobs/Activity/Import/ImportTwilioVideoSpeechesJobTest.php | 22 +-\n tests/Unit/Jobs/Activity/Import/IsActivityReadyForProcessingJobTest.php | 26 +-\n tests/Unit/Jobs/Calendar/SetupCalendarSyncTest.php | 25 -\n tests/Unit/Services/Activity/ParticipantsServiceTest.php | 12 +-\n tests/Unit/Services/Activity/Twilio/S3RecordingCredentialsServiceTest.php | 180 +++++\n tests/Unit/Services/ActivityServiceTest.php | 132 ++++\n tests/Unit/Services/Calendar/CalendarActivityServiceTest.php | 150 +++-\n tests/Unit/Services/Calendar/Command/ImportParticipantsTest.php | 6 +-\n tests/Unit/Services/Calendar/Command/MapActivityDataTest.php | 78 +-\n tests/Unit/Services/Calendar/GoogleCalendarServiceTest.php | 116 +++\n tests/Unit/Services/Crm/Close/ServiceTest.php | 165 +++++\n tests/Unit/Services/Crm/Hubspot/ServiceTest.php | 272 ++++++-\n tests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTest.php | 25 +-\n tests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTraitMatchActivitiesTest.php | 3 +-\n tests/Unit/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTraitOpportunitiesTest.php | 40 ++\n tests/Unit/Services/Crm/Pipedrive/ImportOpportunityMatchActivitiesTest.php | 2 +\n tests/Unit/Services/Crm/Salesforce/ServiceTest.php | 139 ++++\n tests/Unit/Services/Mail/Office/EmailApiClientTest.php | 195 ++---\n tests/Unit/Services/RecallAI/RecallAIServiceTest.php | 24 +-\n 175 files changed, 12562 insertions(+), 2162 deletions(-)\n create mode 120000 CLAUDE.md\n create mode 100644 app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.php\n delete mode 100644 app/Component/ES/ElasticSearchWorkerManager.php\n delete mode 100644 app/Component/ES/Processor/Traits/SkipActivityTrait.php\n delete mode 100644 app/Component/ES/Worker/ActivityWorker.php\n delete mode 100644 app/Component/ES/Worker/EntityWorker.php\n delete mode 100644 app/Component/ES/Worker/WorkerAmount.php\n delete mode 100644 app/Component/ES/Worker/WorkerInterface.php\n create mode 100644 app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.php\n create mode 100644 app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/NoAssemblyIdException.php\n create mode 100644 app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNotCorrectFormatException.php\n create mode 100644 app/Console/Commands/Activities/SetupIntegration/TwilioSetS3RecordingCredentialsCommand.php\n create mode 100644 app/Console/Commands/Crm/BackfillOpportunityUserFromAccountCommand.php\n delete mode 100644 app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.php\n create mode 100644 app/Console/Commands/IssueMcpTokenCommand.php\n create mode 100644 app/Http/Middleware/McpAuditMiddleware.php\n create mode 100644 app/Http/Middleware/McpTierMiddleware.php\n create mode 100644 app/Mcp/Contracts/McpCallRepositoryInterface.php\n create mode 100644 app/Mcp/DTO/ListCallsFilters.php\n create mode 100644 app/Mcp/Errors/McpError.php\n create mode 100644 app/Mcp/Repositories/McpActivityHydrator.php\n create mode 100644 app/Mcp/Repositories/McpCallRepository.php\n create mode 100644 app/Mcp/Repositories/McpElasticCallRepository.php\n create mode 100644 app/Mcp/Servers/JiminnyServer.php\n create mode 100644 app/Mcp/Tools/ListCallsTool.php\n create mode 100644 app/Services/Activity/Twilio/S3RecordingCredentialsService.php\n create mode 100644 config/mcp.php\n create mode 100644 database/migrations/2026_04_30_120000_create_mcp_audit_log_table.php\n create mode 100644 docs/mcp/explorer/explorer.html\n create mode 100644 docs/mcp/explorer/explorer.template.html\n create mode 100644 docs/mcp/explorer/generate.js\n create mode 100644 docs/mcp/explorer/tool-explorer-meta.json\n create mode 100644 docs/mcp/tools-list.json\n create mode 100644 docs/mcp/tools.md\n create mode 100644 front-end/src/components/shared/modals/EntityPickerModal/__tests__/useEntitiesCache.spec.ts\n create mode 100644 tests/Feature/Component/Nudge/ProcessOrganisationImmediateNudgesJobTest.php\n create mode 100644 tests/Feature/Mcp/IssueMcpTokenCommandTest.php\n create mode 100644 tests/Feature/Mcp/ListCallsToolElasticFeatureTest.php\n create mode 100644 tests/Feature/Mcp/ListCallsToolFeatureTest.php\n create mode 100644 tests/Feature/Mcp/McpTestHelpersTrait.php\n create mode 100644 tests/Stubs/SentryStub.php\n create mode 100644 tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheckerTest.php\n delete mode 100644 tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.php\n create mode 100644 tests/Unit/Component/ES/Processor/Actions/LoadDocumentsActionTest.php\n delete mode 100644 tests/Unit/Component/ES/Processor/Traits/SkipActivityTraitTest.php\n delete mode 100644 tests/Unit/Component/ES/Worker/ActivityWorkerTest.php\n delete mode 100644 tests/Unit/Component/ES/Worker/EntityWorkerTest.php\n delete mode 100644 tests/Unit/Component/ES/Worker/WorkerAmountTest.php\n create mode 100644 tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCreatorTest.php\n create mode 100644 tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.php\n create mode 100644 tests/Unit/Services/Activity/Twilio/S3RecordingCredentialsServiceTest.php\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ git status\nOn branch master\nYour branch is behind 'origin/master' by 114 commits, and can be fast-forwarded.\n (use \"git pull\" to update your local branch)\n\nChanges not staged for commit:\n (use \"git add <file>...\" to update what will be committed)\n (use \"git restore <file>...\" to discard changes in working directory)\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: .env.local\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Component/SCIM/Constants.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Component/SCIM/ScimProvisioning.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Component/Twilio/Conference/ConferenceManager/SoftPhoneManager.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Console/Commands/JiminnyDebugCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/DTO/SCIM/AAD/Request/CoreUserRequest.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/DTO/SCIM/AAD/Response/CoreUser.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Services/Telephony/TextMessagingService.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: config/logging.php\n\nUntracked files:\n (use \"git add <file>...\" to include in what will be committed)\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\t.env.nikilocal\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\t.env.other\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tWEBHOOK_FILTERING_IMPLEMENTATION.md\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Component/SCIM/Mutators/Attributes/User/RoleAttr.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Console/Commands/Crm/Hubspot/SimulateWebhooksCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Console/Commands/Reports/CreateMockAskJiminnyReportResultCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Rules/ListenerRoleCannotHaveAdminOrManagerPermissionRule.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tids.txt\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tpublic/favicon.ico\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\traw_sql_query.sql\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ttests/Unit/Component/SCIM/Mutators/Attributes/User/RoleAttrTest.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ttests/Unit/Policies/CanAccessAiReportsTest.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ttests/Unit/Rules/ListenerRoleCannotHaveAdminOrManagerPermissionRuleTest.php\n\nno changes added to commit (use \"git add\" and/or \"git commit -a\")\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull\nremote: Enumerating objects: 306, done.\nremote: Counting objects: 100% (299/299), done.\nremote: Compressing objects: 100% (183/183), done.\nremote: Total 306 (delta 213), reused 171 (delta 116), pack-reused 7 (from 1)\nReceiving objects: 100% (306/306), 80.12 KiB | 1000.00 KiB/s, done.\nResolving deltas: 100% (213/213), completed with 53 local objects.\nFrom github.com:jiminny/app\n 90bca4e4b2..5604af40cf master -> origin/master\n 4e7078fd8b..0b8343d179 JY-18091-upgrade-to-php-8-5 -> origin/JY-18091-upgrade-to-php-8-5\n 098eeaa087..d5a447e492 JY-20613-allow-owner-role-on-team-setup -> origin/JY-20613-allow-owner-role-on-team-setup\n c3a76ace91..af65249d0f JY-20749-user-can-view-recorded-meetings -> origin/JY-20749-user-can-view-recorded-meetings\n d94a285ae7..7ce96cb5fe JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue\n * [new branch] JY-20842-remove-partial-updater -> origin/JY-20842-remove-partial-updater\n * [new branch] JY-20920-fix-participant-flip -> origin/JY-20920-fix-participant-flip\n * [new branch] secfix/npm-20260519 -> origin/secfix/npm-20260519\nUpdating cb4ebf0c36..5604af40cf\nFast-forward\n app/Component/ES/ChunkSize.php | 54 +++++++++++++++++++\n app/Component/ES/Processor/DTOs/SelectionList.php | 4 +-\n app/Component/ES/Processor/TargetEntitiesSelector.php | 19 ++++---\n app/Component/MeetingBot/Service/ParticipantMatcher.php | 46 ++++++++++++----\n app/Exceptions/RateLimitException.php | 19 ++++++-\n app/Http/Middleware/McpTierMiddleware.php | 27 ++--------\n app/Jobs/Crm/MatchActivityCrmData.php | 47 ++++++++++++----\n app/Jobs/Middleware/HandleHubspotRateLimit.php | 42 +++++++++++++++\n app/Mcp/Servers/JiminnyServer.php | 2 +\n app/Mcp/Tools/GetMeTool.php | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++\n app/Models/Feature/FeatureEnum.php | 1 +\n app/Services/Activity/HubSpot/ProviderResolver.php | 4 +-\n app/Services/Activity/HubSpot/ProviderResolverInterface.php | 2 +-\n app/Services/Activity/HubSpot/Providers/Provider.php | 2 +-\n app/Services/Activity/HubSpot/Providers/ProviderKixie.php | 2 +-\n app/Services/Activity/HubSpot/Providers/ProviderOrum.php | 2 +-\n app/Services/Activity/HubSpot/Providers/ProviderTwilio.php | 2 +-\n app/Services/Activity/HubSpot/Providers/ProviderTwilioFlex.php | 5 +-\n app/Services/Activity/HubSpot/Service.php | 97 +++++++++++++++++++++++++++------\n app/Services/Crm/Hubspot/Client.php | 132 +++++++++++++++++++++++++++++++++++++++++++++\n app/Services/Crm/Hubspot/HubspotClientInterface.php | 15 ++++++\n app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php | 21 ++++----\n app/Services/Crm/Hubspot/Pagination/PaginationState.php | 2 +-\n database/migrations/2026_05_13_124153_create_mcp_feature_flag.php | 25 +++++++++\n tests/Feature/Mcp/GetMeToolFeatureTest.php | 140 +++++++++++++++++++++++++++++++++++++++++++++++\n tests/Feature/Mcp/ListCallsToolFeatureTest.php | 2 +-\n tests/Feature/Mcp/McpTestHelpersTrait.php | 19 ++++++-\n tests/Unit/Component/ES/ChunkSizeTest.php | 50 +++++++++++++++++\n tests/Unit/Component/ES/Processor/DTOs/SelectionListTest.php | 27 +++++++---\n tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 39 ++++++++------\n tests/Unit/Component/MeetingBot/Service/ParticipantMatcherTest.php | 68 ++++++++++++++++++++++-\n tests/Unit/Exceptions/RateLimitExceptionTest.php | 56 +++++++++++++++++++\n tests/Unit/Jobs/Crm/MatchActivityCrmDataTest.php | 8 +--\n tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++\n tests/Unit/Services/Activity/HubSpot/ServiceTest.php | 109 +++++++++++++++++++++++++++++++++++++\n tests/Unit/Services/Crm/Hubspot/ClientTest.php | 250 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n tests/Unit/Services/Crm/Hubspot/Pagination/HubspotPaginationServiceTest.php | 283 +++++++++++++++++++++---------------------------------------------------------------------------\n 37 files changed, 1587 insertions(+), 344 deletions(-)\n create mode 100644 app/Component/ES/ChunkSize.php\n create mode 100644 app/Jobs/Middleware/HandleHubspotRateLimit.php\n create mode 100644 app/Mcp/Tools/GetMeTool.php\n create mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.php\n create mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.php\n create mode 100644 tests/Unit/Component/ES/ChunkSizeTest.php\n create mode 100644 tests/Unit/Exceptions/RateLimitExceptionTest.php\n create mode 100644 tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull\nAlready up to date.\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20676-delete-report-related-objects\nSwitched to a new branch 'JY-20676-delete-report-related-objects'\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20676-delete-report-related-objects) $ csfix\ndocker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff \nPHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.\nPHP runtime: 8.3.30\nRunning analysis on 7 cores with 10 files per process.\nParallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!\nLoaded config default from \".php-cs-fixer.dist.php\".\n 5690/5690 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%\n\n 1) app/Console/Commands/JiminnyDebugCommand.php (statement_indentation, blank_line_before_statement)\n ---------- begin diff ----------\n--- /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php\n+++ /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php\n@@ -23,6 +23,7 @@\n \n if ($action === 'redis-set') {\n $this->testRedisSet();\n+\n return;\n }\n \n@@ -45,7 +46,7 @@\n $ttl = 60;\n \n try {\n-// $result = Redis::set($testKey, $testValue, 'EX', $ttl, 'NX');\n+ // $result = Redis::set($testKey, $testValue, 'EX', $ttl, 'NX');\n $result = Redis::set($testKey, $testValue, ['nx', 'ex' => $ttl]);\n \n if ($result) {\n\n ----------- end diff -----------\n\n\nFixed 1 of 5690 files in 50.673 seconds, 67.00 MB memory used\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20676-delete-report-related-objects) $ ;xd\ndocker exec -it docker_lamp_1 bash -c \"mv /usr/local/etc/php/conf.d/xdebug.ini ~/xdebug.ini\"\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\ndocker exec -it docker_lamp_1 supervisorctl restart all\njiminny-worker-processing-2:jiminny-worker-processing-2_00: stopped\njiminny-worker-processing-3:jiminny-worker-processing-3_00: stopped\njiminny-worker-processing-4:jiminny-worker-processing-4_00: stopped\njiminny-worker-processing-5:jiminny-worker-processing-5_00: stopped\njiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00: stopped\nworker-analytics:worker-analytics_00: stopped\nworker-crm-update:worker-crm-update_00: stopped\nworker-download:worker-download_00: stopped\nworker-nudges:worker-nudges_00: stopped\nworker-calendar:worker-calendar_00: stopped\nworker-audio:worker-audio_00: stopped\njiminny-worker-processing-1:jiminny-worker-processing-1_00: stopped\nworker:worker_00: stopped\nworker-conferences:worker-conferences_00: stopped\nworker-crm-sync:worker-crm-sync_00: stopped\nworker-emails:worker-emails_00: stopped\nworker-es-update:worker-es-update_00: stopped\nartisan-schedule:artisan-schedule_00: stopped\nartisan-schedule:artisan-schedule_00: started\njiminny-worker-processing-1:jiminny-worker-processing-1_00: started\njiminny-worker-processing-2:jiminny-worker-processing-2_00: started\njiminny-worker-processing-3:jiminny-worker-processing-3_00: started\njiminny-worker-processing-4:jiminny-worker-processing-4_00: started\njiminny-worker-processing-5:jiminny-worker-processing-5_00: started\njiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00: started\nworker:worker_00: started\nworker-analytics:worker-analytics_00: started\nworker-audio:worker-audio_00: started\nworker-calendar:worker-calendar_00: started\nworker-conferences:worker-conferences_00: started\nworker-crm-sync:worker-crm-sync_00: started\nworker-crm-update:worker-crm-update_00: started\nworker-download:worker-download_00: started\nworker-emails:worker-emails_00: started\nworker-es-update:worker-es-update_00: started\nworker-nudges:worker-nudges_00: started\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\ndocker exec -it docker_lamp_1 php -v\nPHP 8.3.30 (cli) (built: Mar 16 2026 22:32:32) (NTS)\nCopyright (c) The PHP Group\nZend Engine v4.3.30, Copyright (c) Zend Technologies\n with Zend OPcache v8.3.30, Copyright (c), by Zend Technologies\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20676-delete-report-related-objects) $ git sta","depth":4,"on_screen":true,"value":"Last login: Mon May 18 09:17:28 on ttys007\n\nPoetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parents\n\nPoetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parents\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ co master\nerror: Your local changes to the following files would be overwritten by checkout:\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tPIPEDRIVE_V2_MIGRATION_TICKETS.md\nPlease commit your changes or stash them before you switch branches.\nAborting\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ git pull\nremote: Enumerating objects: 1047, done.\nremote: Counting objects: 100% (832/832), done.\nremote: Compressing objects: 100% (298/298), done.\nremote: Total 1047 (delta 634), reused 596 (delta 534), pack-reused 215 (from 3)\nReceiving objects: 100% (1047/1047), 353.16 KiB | 1.56 MiB/s, done.\nResolving deltas: 100% (687/687), completed with 107 local objects.\nFrom github.com:jiminny/app\n 907c54896c..34656c53ed pipedrive-sdk-poc -> origin/pipedrive-sdk-poc\n 03325ec50f..4e7078fd8b JY-18091-upgrade-to-php-8-5 -> origin/JY-18091-upgrade-to-php-8-5\n e7d231e163..bc6a3fce6b JY-20725-handle-HS-search-rate-limit -> origin/JY-20725-handle-HS-search-rate-limit\n * [new branch] JY-20749-user-can-view-recorded-meetings -> origin/JY-20749-user-can-view-recorded-meetings\n 98ca281a04..e0351be069 JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue\n 569abb5149..3906a9238a JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details -> origin/JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details\n ad6c2a86e8..50eb6afba9 JY-20846-mcp-enable-the-ai-to-know-details-about-the-user -> origin/JY-20846-mcp-enable-the-ai-to-know-details-about-the-user\n * [new branch] JY-20893-chunk-control-per-update-target -> origin/JY-20893-chunk-control-per-update-target\n 31c62924a5..cb4ebf0c36 master -> origin/master\nUpdating 907c54896c..34656c53ed\nFast-forward\n PIPEDRIVE_V2_MIGRATION_TICKETS.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 52 insertions(+)\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ co master\nM\u0000\u0000\u0000\u0000\u0000\u0000\t.env.local\nM\u0000\u0000\u0000\u0000\u0000\u0000\tconfig/logging.php\nSwitched to branch 'master'\nYour branch is behind 'origin/master' by 31 commits, and can be fast-forwarded.\n (use \"git pull\" to update your local branch)\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull\nUpdating 31c62924a5..cb4ebf0c36\nFast-forward\n app/Component/ES/Processor/Traits/SelectEntityListTrait.php | 20 ------\n app/Services/Calendar/CalendarActivityService.php | 46 +++++++++++++\n app/Services/Calendar/Command/MapActivityData.php | 106 +++-------------------------\n docs/mcp/explorer/explorer.html | 104 +++++++++++++++++++++++++---\n docs/mcp/explorer/explorer.template.html | 102 ++++++++++++++++++++++++---\n docs/mcp/tools-list.json | 373 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------\n docs/mcp/tools.md | 117 +++++++++++++++++++++++--------\n tests/Unit/Component/ES/AsyncUpdateElasticSearchTest.php | 16 +----\n tests/Unit/Component/ES/Listeners/UpdateMultipleTargetsListenerTest.php | 10 ---\n tests/Unit/Component/ES/Listeners/UpdateSingleTargetListenerTest.php | 6 --\n tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 9 ---\n tests/Unit/Component/ES/Processor/Traits/SelectEntityListTraitTest.php | 15 ++--\n tests/Unit/Component/ES/UpdateProcessManagerTest.php | 2 -\n tests/Unit/Services/Calendar/CalendarActivityServiceTest.php | 150 ++++++++++++++++++++++++++++++++++++++--\n tests/Unit/Services/Calendar/Command/MapActivityDataTest.php | 78 ++-------------------\n 15 files changed, 832 insertions(+), 322 deletions(-)\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20613-allow-owner-role-on-team-setup\nSwitched to a new branch 'JY-20613-allow-owner-role-on-team-setup'\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ csfix\ndocker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff \nPHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.\nPHP runtime: 8.3.30\nRunning analysis on 7 cores with 10 files per process.\nParallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!\nLoaded config default from \".php-cs-fixer.dist.php\".\n 5682/5682 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%\n\n\nFixed 0 of 5682 files in 56.978 seconds, 67.00 MB memory used\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ ;xd\ndocker exec -it docker_lamp_1 bash -c \"mv /usr/local/etc/php/conf.d/xdebug.ini ~/xdebug.ini\"\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\ndocker exec -it docker_lamp_1 supervisorctl restart all\njiminny-worker-processing-2:jiminny-worker-processing-2_00: stopped\njiminny-worker-processing-3:jiminny-worker-processing-3_00: stopped\njiminny-worker-processing-4:jiminny-worker-processing-4_00: stopped\njiminny-worker-processing-5:jiminny-worker-processing-5_00: stopped\njiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00: stopped\nworker-analytics:worker-analytics_00: stopped\nworker-crm-update:worker-crm-update_00: stopped\nworker-download:worker-download_00: stopped\nworker-nudges:worker-nudges_00: stopped\nartisan-schedule:artisan-schedule_00: stopped\nworker-emails:worker-emails_00: stopped\nworker-calendar:worker-calendar_00: stopped\nworker:worker_00: stopped\nworker-conferences:worker-conferences_00: stopped\nworker-crm-sync:worker-crm-sync_00: stopped\njiminny-worker-processing-1:jiminny-worker-processing-1_00: stopped\nworker-audio:worker-audio_00: stopped\nworker-es-update:worker-es-update_00: stopped\nartisan-schedule:artisan-schedule_00: started\njiminny-worker-processing-1:jiminny-worker-processing-1_00: started\njiminny-worker-processing-2:jiminny-worker-processing-2_00: started\njiminny-worker-processing-3:jiminny-worker-processing-3_00: started\njiminny-worker-processing-4:jiminny-worker-processing-4_00: started\njiminny-worker-processing-5:jiminny-worker-processing-5_00: started\njiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00: started\nworker:worker_00: started\nworker-analytics:worker-analytics_00: started\nworker-audio:worker-audio_00: started\nworker-calendar:worker-calendar_00: started\nworker-conferences:worker-conferences_00: started\nworker-crm-sync:worker-crm-sync_00: started\nworker-crm-update:worker-crm-update_00: started\nworker-download:worker-download_00: started\nworker-emails:worker-emails_00: started\nworker-es-update:worker-es-update_00: started\nworker-nudges:worker-nudges_00: started\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\ndocker exec -it docker_lamp_1 php -v\nPHP 8.3.30 (cli) (built: Mar 16 2026 22:32:32) (NTS)\nCopyright (c) The PHP Group\nZend Engine v4.3.30, Copyright (c) Zend Technologies\n with Zend OPcache v8.3.30, Copyright (c), by Zend Technologies\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ csfix\ndocker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff \nPHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.\nPHP runtime: 8.3.30\nRunning analysis on 7 cores with 10 files per process.\nParallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!\nLoaded config default from \".php-cs-fixer.dist.php\".\n 5682/5682 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%\n\n\nFixed 0 of 5682 files in 49.910 seconds, 60.00 MB memory used\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git status\nOn branch JY-20613-allow-owner-role-on-team-setup\nYour branch is ahead of 'origin/JY-20613-allow-owner-role-on-team-setup' by 1 commit.\n (use \"git push\" to publish your local commits)\n\nChanges not staged for commit:\n (use \"git add <file>...\" to update what will be committed)\n (use \"git restore <file>...\" to discard changes in working directory)\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: .env.local\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: config/logging.php\n\nUntracked files:\n (use \"git add <file>...\" to include in what will be committed)\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\t.env.nikilocal\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\t.env.other\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tWEBHOOK_FILTERING_IMPLEMENTATION.md\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Console/Commands/Crm/Hubspot/SimulateWebhooksCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Console/Commands/Reports/CreateMockAskJiminnyReportResultCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tids.txt\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tpublic/favicon.ico\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\traw_sql_query.sql\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ttests/Unit/Policies/CanAccessAiReportsTest.php\n\nno changes added to commit (use \"git add\" and/or \"git commit -a\")\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git pull\nremote: Enumerating objects: 248, done.\nremote: Counting objects: 100% (128/128), done.\nremote: Compressing objects: 100% (23/23), done.\nremote: Total 59 (delta 43), reused 44 (delta 33), pack-reused 0 (from 0)\nUnpacking objects: 100% (59/59), 10.48 KiB | 228.00 KiB/s, done.\nFrom github.com:jiminny/app\n b7df560451..190239dfd4 JY-20613-allow-owner-role-on-team-setup -> origin/JY-20613-allow-owner-role-on-team-setup\n e0351be069..d94a285ae7 JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue\n * [new branch] JY-20920-fix-participant-matcher -> origin/JY-20920-fix-participant-matcher\n cb4ebf0c36..90bca4e4b2 master -> origin/master\nMerge made by the 'ort' strategy.\n app/Component/ES/ChunkSize.php | 54 +++++++++++++++++++++++++++\n app/Component/ES/Processor/DTOs/SelectionList.php | 4 +-\n app/Component/ES/Processor/TargetEntitiesSelector.php | 19 ++++++----\n app/Http/Middleware/McpTierMiddleware.php | 27 +++-----------\n app/Mcp/Servers/JiminnyServer.php | 2 +\n app/Mcp/Tools/GetMeTool.php | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n app/Models/Feature/FeatureEnum.php | 1 +\n database/migrations/2026_05_13_124153_create_mcp_feature_flag.php | 25 +++++++++++++\n front-end/src/components/Settings/Kiosk/modals/EditTeamModal/EditTeamModal.vue | 52 ++++++++++++++++++--------\n front-end/src/components/Settings/Kiosk/modals/EditTeamModal/__tests__/EditTeamModal.spec.js | 14 +++++++\n tests/Feature/Mcp/GetMeToolFeatureTest.php | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n tests/Feature/Mcp/ListCallsToolFeatureTest.php | 2 +-\n tests/Feature/Mcp/McpTestHelpersTrait.php | 19 +++++++++-\n tests/Unit/Component/ES/ChunkSizeTest.php | 50 +++++++++++++++++++++++++\n tests/Unit/Component/ES/Processor/DTOs/SelectionListTest.php | 27 ++++++++++----\n tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 39 +++++++++++---------\n 16 files changed, 557 insertions(+), 75 deletions(-)\n create mode 100644 app/Component/ES/ChunkSize.php\n create mode 100644 app/Mcp/Tools/GetMeTool.php\n create mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.php\n create mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.php\n create mode 100644 tests/Unit/Component/ES/ChunkSizeTest.php\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git push\nEnumerating objects: 40, done.\nCounting objects: 100% (34/34), done.\nDelta compression using up to 8 threads\nCompressing objects: 100% (18/18), done.\nWriting objects: 100% (18/18), 1.58 KiB | 1.58 MiB/s, done.\nTotal 18 (delta 15), reused 0 (delta 0), pack-reused 0\nremote: Resolving deltas: 100% (15/15), completed with 13 local objects.\nTo github.com:jiminny/app.git\n 190239dfd4..ec1b261264 JY-20613-allow-owner-role-on-team-setup -> JY-20613-allow-owner-role-on-team-setup\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ gbr\n* JY-20613-allow-owner-role-on-team-setup\n pipedrive-sdk-poc\n master\n JY-20903-update_activity-stage-on-opportunity-change\n JY-20904-fix-update-es-on-activity-command\n JY-20891-improve-sms-text-relays\n JY-20725-handle-HS-search-rate-limit\n JY-20818-move-AJ-reports-to-separated-datadog-metric\n JY-20773-fix-automated-reports-user-pilot-tracking\n JY-20157-AJ-report-not-send-notification\n JY-20508-notify-before-AJ-report-expiration\n JY-20372-ai-reports-promotion-pages\n JY-20352-sync-opportunities-without-a-local-owner-user-id-is-null\n JY-20738-debug-AJ-tracking-UP\n a\n JY-18909-automated-reports-ask-jiminny\n JY-20692-fix-integration-app-token-auth-response-change\n JY-20553-debug-crm-sync-delays\n JY-20698-fix-SF-activity-types-on-new-playbook\n JY-20543-AJ-report-tracking\n JY-20384-handle-auto-sync-with-no-access-to-event-type\n JY-20458-ask-jiminny-user-definitions\n JY-19666-fix-import-contacts-account-association\n JY-19666-HS-import-contacts-and-accounts-batch-job\n JY-20458-Ask-Jiminny-Reports\n JY-20200-batch-update-CRM-objects-Salesforce\n JY-19666-HS-webhooks-add-contact-and-company\n JY-20348-trigger-setup-DI-layout-on-team-creation\n JY-20326-refactor-info-message-in-command\n JY-20317-fix-auto-log-delay-issue-on-all-channels-disabled\n JY-20312-remove-on-update-change-last-synced-at-crm-configurations\n JY-20306-SF-skip-auto-sync-for-task-based-playbook\n JY-20192-remove-deleted-team-from-saved-search-filters\n JY-20197-import-opportunity-batch-job\n JY-20293-enable-status-field-for-pipedrive-deals\n JY-20191-remove-commands-interactive-prompts\n JY-20118-change-default-sync-strategy\n JY-20183-add-cache-on-auto-log-delay\n JY-20197-add-import-opportunity-batch-job\n 20118-hs-opportunity-make-webhook-strategy-default\n JY-20118-make-default-hs-opportunity-sync-strategy-webhook-based\n JY-20196-handle-opportunity-without-note\n JY-20118-improve-opportunity-import\n JY-20189-handle-activity-search-on-deleted-groups\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ co JY-20725-handle-HS-search-rate-limit\nM\u0000\u0000\u0000\u0000\u0000\u0000\t.env.local\nM\u0000\u0000\u0000\u0000\u0000\u0000\tconfig/logging.php\nSwitched to branch 'JY-20725-handle-HS-search-rate-limit'\nYour branch is behind 'origin/JY-20725-handle-HS-search-rate-limit' by 439 commits, and can be fast-forwarded.\n (use \"git pull\" to update your local branch)\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ git pull\nUpdating 0f3e438941..bc6a3fce6b\nFast-forward\n .gitignore | 3 +-\n .windsurfrules | 168 ++---\n CLAUDE.md | 1 +\n app/Component/ActivityAnalytics/Service/CalculateTalkTimeOffsetsFromTranscription.php | 24 +-\n app/Component/AiActivityType/Services/AiActivityTypeEligibilityChecker.php | 28 +-\n app/Component/AiAutomation/Actions/PrepareUpdateDtoAction.php | 32 +-\n app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.php | 47 ++\n app/Component/AiAutomation/TestCrmAiPromptService.php | 14 +\n app/Component/AiCallScoring/Services/AiCallScoringEligibilityChecker.php | 9 +\n app/Component/ES/ElasticSearchDocumentPartialUpdater.php | 13 +-\n app/Component/ES/ElasticSearchWorkerManager.php | 86 ---\n app/Component/ES/Processor/Actions/LoadDocumentsAction.php | 80 +--\n app/Component/ES/Processor/EntityQueryBuilder.php | 12 +-\n app/Component/ES/Processor/TargetEntitiesSelector.php | 2 +-\n app/Component/ES/Processor/Traits/SkipActivityTrait.php | 25 -\n app/Component/ES/Repositories/EsResetActivityRepository.php | 11 +-\n app/Component/ES/Worker/ActivityWorker.php | 73 --\n app/Component/ES/Worker/EntityWorker.php | 44 --\n app/Component/ES/Worker/WorkerAmount.php | 60 --\n app/Component/ES/Worker/WorkerInterface.php | 15 -\n app/Component/ElasticSearch/Contract/Searchable.php | 4 +\n app/Component/Encoding/Job/AnalyzeTrackChannelsJob.php | 20 +-\n app/Component/Encoding/Service/GenerateSpeechFromSilenceService.php | 85 ++-\n app/Component/FFMpeg/Services/GetSpeechIntervalsService.php | 18 +-\n app/Component/LanguageDetection/Services/FindSpeechTimeService.php | 22 +-\n app/Component/Nudge/Job/ProcessOrganisationImmediateNudgesJob.php | 218 +++++-\n app/Component/ParagraphBreaker/Services/TranscriptionParagraphsService.php | 4 +\n app/Component/ParticipantSpeech/Services/ParticipantSpeechesCreator.php | 33 +\n app/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleter.php | 15 +\n app/Component/ParticipantSpeech/Services/ParticipantSpeechesProvider.php | 51 +-\n app/Component/ParticipantSpeech/Services/ParticipantSpeechesUploader.php | 36 +\n app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.php | 11 +\n app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/NoAssemblyIdException.php | 11 +\n app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/SuccessfulResponse.php | 6 +\n app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNotCorrectFormatException.php | 11 +\n app/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeechesService.php | 23 +-\n app/Component/Transcription/Diarization/Source/MeetingBotSource.php | 16 +-\n app/Component/Transcription/TranscriptionProcessor/TranscriptionProcessor.php | 3 +\n app/Console/Commands/Activities/ActivityHardDeleteCommand.php | 4 +-\n app/Console/Commands/Activities/Copy.php | 2 +\n app/Console/Commands/Activities/SetupIntegration/TwilioSetS3RecordingCredentialsCommand.php | 119 ++++\n app/Console/Commands/Activities/UpdateActivityElasticSearchDocumentCommand.php | 10 +-\n app/Console/Commands/Crm/BackfillOpportunityUserFromAccountCommand.php | 126 ++++\n app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.php | 19 -\n app/Console/Commands/Elasticsearch/AsyncUpdateEsEntities.php | 50 +-\n app/Console/Commands/Elasticsearch/ResetAsyncElasticSearchCommand.php | 30 +-\n app/Console/Commands/GeckoExport/GeckoExportParticipantSpeechesCommand.php | 14 +-\n app/Console/Commands/IssueMcpTokenCommand.php | 84 +++\n app/Console/Commands/JiminnyDebugCommand.php | 7 +-\n app/Console/Commands/Tracks/CleanupActivityTracksCommand.php | 2 +-\n app/Console/Kernel.php | 6 +-\n app/Contracts/Services/Calendar/CalendarTrait.php | 80 ++-\n app/Events/AutomatedReports/AutomatedReportGenerated.php | 3 +\n app/Http/Controllers/API/AiCallScoring/AiScorecardController.php | 7 +-\n app/Http/Controllers/API/TeamAiAutomationController.php | 8 +\n app/Http/Controllers/CustomerApi/CustomerApiController.php | 4 +-\n app/Http/Controllers/Kiosk/ActivityController.php | 58 +-\n app/Http/Controllers/Settings/PlaybookController.php | 15 +-\n app/Http/Kernel.php | 23 +\n app/Http/Middleware/McpAuditMiddleware.php | 156 ++++\n app/Http/Middleware/McpTierMiddleware.php | 54 ++\n app/Http/Requests/API/V2/ZapierUploadActivityRequest.php | 28 +-\n app/Jobs/Activity/Import/ImportTwilioVideoSpeechesJob.php | 25 +-\n app/Jobs/Activity/Import/IsActivityReadyForProcessingJob.php | 10 +-\n app/Jobs/Calendar/SetupCalendarSync.php | 21 +-\n app/Jobs/ImportRemoteTrackJob.php | 96 ++-\n app/Jobs/Mailbox/EmailTextRelay.php | 15 +-\n app/Mcp/Contracts/McpCallRepositoryInterface.php | 30 +\n app/Mcp/DTO/ListCallsFilters.php | 29 +\n app/Mcp/Errors/McpError.php | 123 ++++\n app/Mcp/Repositories/McpActivityHydrator.php | 145 ++++\n app/Mcp/Repositories/McpCallRepository.php | 84 +++\n app/Mcp/Repositories/McpElasticCallRepository.php | 171 +++++\n app/Mcp/Servers/JiminnyServer.php | 38 +\n app/Mcp/Tools/ListCallsTool.php | 205 ++++++\n app/Models/Activity.php | 10 +-\n app/Models/Activity/Transcription.php | 17 +-\n app/Models/ElasticSearch/OpportunityElasticSearchTrait.php | 5 +\n app/Models/Participant.php | 1 +\n app/Providers/AppServiceProvider.php | 22 +\n app/Repositories/Crm/ContactRepository.php | 69 +-\n app/Repositories/ParticipantSpeechRepository.php | 13 +-\n app/Services/Activity/ParticipantsService.php | 19 +-\n app/Services/Activity/Twilio/S3RecordingCredentialsService.php | 82 +++\n app/Services/ActivityService.php | 21 +-\n app/Services/Calendar/CalendarActivityService.php | 46 ++\n app/Services/Calendar/Command/ImportParticipants.php | 1 +\n app/Services/Calendar/Command/MapActivityData.php | 106 +--\n app/Services/Calendar/GoogleCalendarService.php | 12 +-\n app/Services/Crm/Close/Processor/OpportunityProcessor.php | 2 +-\n app/Services/Crm/Close/Service.php | 22 +-\n app/Services/Crm/Copper/Service.php | 12 +-\n app/Services/Crm/Hubspot/Service.php | 154 +++-\n app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php | 88 ++-\n app/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTrait.php | 22 +-\n app/Services/Crm/Pipedrive/Service.php | 17 +-\n app/Services/Crm/Salesforce/Service.php | 42 +-\n app/Services/Mail/Office/EmailApiClient.php | 129 +---\n app/Services/RecallAI/Commands/ScheduleBotCommand.php | 39 +-\n app/Services/RecallAI/RecallAIService.php | 22 +-\n composer.json | 3 +-\n composer.lock | 87 ++-\n config/mcp.php | 23 +\n database/migrations/2026_04_30_120000_create_mcp_audit_log_table.php | 36 +\n docs/mcp/explorer/explorer.html | 697 ++++++++++++++++++\n docs/mcp/explorer/explorer.template.html | 697 ++++++++++++++++++\n docs/mcp/explorer/generate.js | 215 ++++++\n docs/mcp/explorer/tool-explorer-meta.json | 11 +\n docs/mcp/tools-list.json | 2536 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n docs/mcp/tools.md | 621 ++++++++++++++++\n front-end/package.json | 4 +-\n front-end/src/components/Settings/OrgSettings/AiAutomation/CrmFilling/TemplateFieldForm.vue | 28 +-\n front-end/src/components/Settings/OrgSettings/Playbooks/AddEditPlaybook.vue | 10 +\n front-end/src/components/playback/comments/ActivityComment.less | 10 +-\n front-end/src/components/shared/PromptTester/PromptTester.vue | 12 +-\n front-end/src/components/shared/__tests__/PromptTester.spec.js | 35 +\n front-end/src/components/shared/modals/EntityPickerModal/__tests__/useEntitiesCache.spec.ts | 37 +\n front-end/src/components/shared/modals/EntityPickerModal/useEntitiesCache.ts | 9 +\n front-end/yarn.lock | 16 +-\n phpstan-baseline.neon | 50 --\n routes/api.php | 11 +\n sonar-project.properties | 91 ++-\n tests/Feature/Component/Nudge/ProcessOrganisationImmediateNudgesJobTest.php | 534 ++++++++++++++\n tests/Feature/Jobs/ImportRemoteTrackJobTest.php | 283 +++++++-\n tests/Feature/Mcp/IssueMcpTokenCommandTest.php | 53 ++\n tests/Feature/Mcp/ListCallsToolElasticFeatureTest.php | 155 ++++\n tests/Feature/Mcp/ListCallsToolFeatureTest.php | 352 ++++++++++\n tests/Feature/Mcp/McpTestHelpersTrait.php | 77 ++\n tests/Feature/Services/Team/TeamDeleteHandlers/Retention/RetentionRepositoryHandlerTest.php | 1 +\n tests/Stubs/SentryStub.php | 18 +\n tests/Unit/Component/ActivityAnalytics/Service/CalculateTalkTimeOffsetFromTranscriptionTest.php | 28 +-\n tests/Unit/Component/AiActivityType/Services/AiActivityTypeEligibilityCheckerTest.php | 103 ++-\n tests/Unit/Component/AiAutomation/Actions/PrepareUpdateDtoActionTest.php | 91 +++\n tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheckerTest.php | 124 ++++\n tests/Unit/Component/AiAutomation/TestCrmAiPromptServiceTest.php | 67 +-\n tests/Unit/Component/AiCallScoring/Services/AiCallScoringEligibilityCheckerTest.php | 55 ++\n tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.php | 135 ----\n tests/Unit/Component/ES/Processor/Actions/LoadDocumentsActionTest.php | 220 ++++++\n tests/Unit/Component/ES/Processor/EntityQueryBuilderTest.php | 21 +-\n tests/Unit/Component/ES/Processor/Traits/SkipActivityTraitTest.php | 51 --\n tests/Unit/Component/ES/Worker/ActivityWorkerTest.php | 174 -----\n tests/Unit/Component/ES/Worker/EntityWorkerTest.php | 97 ---\n tests/Unit/Component/ES/Worker/WorkerAmountTest.php | 116 ---\n tests/Unit/Component/Encoding/Job/AnalyzeTrackChannelsJobTest.php | 52 +-\n tests/Unit/Component/Encoding/Service/GenerateSpeechFromSilenceServiceTest.php | 171 ++---\n tests/Unit/Component/FFMpeg/Services/GetSpeechIntervalsTest.php | 36 +-\n tests/Unit/Component/LanguageDetection/Services/FindSpeechTimeServiceTest.php | 20 +-\n tests/Unit/Component/MobileSettings/MobileSettingsControllerTest.php | 5 +-\n tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCreatorTest.php | 75 ++\n tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleterTest.php | 63 ++\n tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesProviderTest.php | 134 ++++\n tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesUploaderTest.php | 57 ++\n tests/Unit/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeechesServiceTest.php | 51 +-\n tests/Unit/Component/Transcription/Diarization/Source/MeetingBotSourceTest.php | 29 +-\n tests/Unit/Contracts/Services/Calendar/CalendarTraitTest.php | 58 +-\n tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.php | 159 +++++\n tests/Unit/Jobs/Activity/Import/ImportTwilioVideoSpeechesJobTest.php | 22 +-\n tests/Unit/Jobs/Activity/Import/IsActivityReadyForProcessingJobTest.php | 26 +-\n tests/Unit/Jobs/Calendar/SetupCalendarSyncTest.php | 25 -\n tests/Unit/Services/Activity/ParticipantsServiceTest.php | 12 +-\n tests/Unit/Services/Activity/Twilio/S3RecordingCredentialsServiceTest.php | 180 +++++\n tests/Unit/Services/ActivityServiceTest.php | 132 ++++\n tests/Unit/Services/Calendar/CalendarActivityServiceTest.php | 150 +++-\n tests/Unit/Services/Calendar/Command/ImportParticipantsTest.php | 6 +-\n tests/Unit/Services/Calendar/Command/MapActivityDataTest.php | 78 +-\n tests/Unit/Services/Calendar/GoogleCalendarServiceTest.php | 116 +++\n tests/Unit/Services/Crm/Close/ServiceTest.php | 165 +++++\n tests/Unit/Services/Crm/Hubspot/ServiceTest.php | 272 ++++++-\n tests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTest.php | 25 +-\n tests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTraitMatchActivitiesTest.php | 3 +-\n tests/Unit/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTraitOpportunitiesTest.php | 40 ++\n tests/Unit/Services/Crm/Pipedrive/ImportOpportunityMatchActivitiesTest.php | 2 +\n tests/Unit/Services/Crm/Salesforce/ServiceTest.php | 139 ++++\n tests/Unit/Services/Mail/Office/EmailApiClientTest.php | 195 ++---\n tests/Unit/Services/RecallAI/RecallAIServiceTest.php | 24 +-\n 175 files changed, 12562 insertions(+), 2162 deletions(-)\n create mode 120000 CLAUDE.md\n create mode 100644 app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.php\n delete mode 100644 app/Component/ES/ElasticSearchWorkerManager.php\n delete mode 100644 app/Component/ES/Processor/Traits/SkipActivityTrait.php\n delete mode 100644 app/Component/ES/Worker/ActivityWorker.php\n delete mode 100644 app/Component/ES/Worker/EntityWorker.php\n delete mode 100644 app/Component/ES/Worker/WorkerAmount.php\n delete mode 100644 app/Component/ES/Worker/WorkerInterface.php\n create mode 100644 app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.php\n create mode 100644 app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/NoAssemblyIdException.php\n create mode 100644 app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNotCorrectFormatException.php\n create mode 100644 app/Console/Commands/Activities/SetupIntegration/TwilioSetS3RecordingCredentialsCommand.php\n create mode 100644 app/Console/Commands/Crm/BackfillOpportunityUserFromAccountCommand.php\n delete mode 100644 app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.php\n create mode 100644 app/Console/Commands/IssueMcpTokenCommand.php\n create mode 100644 app/Http/Middleware/McpAuditMiddleware.php\n create mode 100644 app/Http/Middleware/McpTierMiddleware.php\n create mode 100644 app/Mcp/Contracts/McpCallRepositoryInterface.php\n create mode 100644 app/Mcp/DTO/ListCallsFilters.php\n create mode 100644 app/Mcp/Errors/McpError.php\n create mode 100644 app/Mcp/Repositories/McpActivityHydrator.php\n create mode 100644 app/Mcp/Repositories/McpCallRepository.php\n create mode 100644 app/Mcp/Repositories/McpElasticCallRepository.php\n create mode 100644 app/Mcp/Servers/JiminnyServer.php\n create mode 100644 app/Mcp/Tools/ListCallsTool.php\n create mode 100644 app/Services/Activity/Twilio/S3RecordingCredentialsService.php\n create mode 100644 config/mcp.php\n create mode 100644 database/migrations/2026_04_30_120000_create_mcp_audit_log_table.php\n create mode 100644 docs/mcp/explorer/explorer.html\n create mode 100644 docs/mcp/explorer/explorer.template.html\n create mode 100644 docs/mcp/explorer/generate.js\n create mode 100644 docs/mcp/explorer/tool-explorer-meta.json\n create mode 100644 docs/mcp/tools-list.json\n create mode 100644 docs/mcp/tools.md\n create mode 100644 front-end/src/components/shared/modals/EntityPickerModal/__tests__/useEntitiesCache.spec.ts\n create mode 100644 tests/Feature/Component/Nudge/ProcessOrganisationImmediateNudgesJobTest.php\n create mode 100644 tests/Feature/Mcp/IssueMcpTokenCommandTest.php\n create mode 100644 tests/Feature/Mcp/ListCallsToolElasticFeatureTest.php\n create mode 100644 tests/Feature/Mcp/ListCallsToolFeatureTest.php\n create mode 100644 tests/Feature/Mcp/McpTestHelpersTrait.php\n create mode 100644 tests/Stubs/SentryStub.php\n create mode 100644 tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheckerTest.php\n delete mode 100644 tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.php\n create mode 100644 tests/Unit/Component/ES/Processor/Actions/LoadDocumentsActionTest.php\n delete mode 100644 tests/Unit/Component/ES/Processor/Traits/SkipActivityTraitTest.php\n delete mode 100644 tests/Unit/Component/ES/Worker/ActivityWorkerTest.php\n delete mode 100644 tests/Unit/Component/ES/Worker/EntityWorkerTest.php\n delete mode 100644 tests/Unit/Component/ES/Worker/WorkerAmountTest.php\n create mode 100644 tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCreatorTest.php\n create mode 100644 tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.php\n create mode 100644 tests/Unit/Services/Activity/Twilio/S3RecordingCredentialsServiceTest.php\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ git status\nOn branch master\nYour branch is behind 'origin/master' by 114 commits, and can be fast-forwarded.\n (use \"git pull\" to update your local branch)\n\nChanges not staged for commit:\n (use \"git add <file>...\" to update what will be committed)\n (use \"git restore <file>...\" to discard changes in working directory)\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: .env.local\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Component/SCIM/Constants.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Component/SCIM/ScimProvisioning.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Component/Twilio/Conference/ConferenceManager/SoftPhoneManager.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Console/Commands/JiminnyDebugCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/DTO/SCIM/AAD/Request/CoreUserRequest.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/DTO/SCIM/AAD/Response/CoreUser.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Services/Telephony/TextMessagingService.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: config/logging.php\n\nUntracked files:\n (use \"git add <file>...\" to include in what will be committed)\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\t.env.nikilocal\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\t.env.other\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tWEBHOOK_FILTERING_IMPLEMENTATION.md\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Component/SCIM/Mutators/Attributes/User/RoleAttr.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Console/Commands/Crm/Hubspot/SimulateWebhooksCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Console/Commands/Reports/CreateMockAskJiminnyReportResultCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Rules/ListenerRoleCannotHaveAdminOrManagerPermissionRule.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tids.txt\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tpublic/favicon.ico\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\traw_sql_query.sql\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ttests/Unit/Component/SCIM/Mutators/Attributes/User/RoleAttrTest.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ttests/Unit/Policies/CanAccessAiReportsTest.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ttests/Unit/Rules/ListenerRoleCannotHaveAdminOrManagerPermissionRuleTest.php\n\nno changes added to commit (use \"git add\" and/or \"git commit -a\")\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull\nremote: Enumerating objects: 306, done.\nremote: Counting objects: 100% (299/299), done.\nremote: Compressing objects: 100% (183/183), done.\nremote: Total 306 (delta 213), reused 171 (delta 116), pack-reused 7 (from 1)\nReceiving objects: 100% (306/306), 80.12 KiB | 1000.00 KiB/s, done.\nResolving deltas: 100% (213/213), completed with 53 local objects.\nFrom github.com:jiminny/app\n 90bca4e4b2..5604af40cf master -> origin/master\n 4e7078fd8b..0b8343d179 JY-18091-upgrade-to-php-8-5 -> origin/JY-18091-upgrade-to-php-8-5\n 098eeaa087..d5a447e492 JY-20613-allow-owner-role-on-team-setup -> origin/JY-20613-allow-owner-role-on-team-setup\n c3a76ace91..af65249d0f JY-20749-user-can-view-recorded-meetings -> origin/JY-20749-user-can-view-recorded-meetings\n d94a285ae7..7ce96cb5fe JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue\n * [new branch] JY-20842-remove-partial-updater -> origin/JY-20842-remove-partial-updater\n * [new branch] JY-20920-fix-participant-flip -> origin/JY-20920-fix-participant-flip\n * [new branch] secfix/npm-20260519 -> origin/secfix/npm-20260519\nUpdating cb4ebf0c36..5604af40cf\nFast-forward\n app/Component/ES/ChunkSize.php | 54 +++++++++++++++++++\n app/Component/ES/Processor/DTOs/SelectionList.php | 4 +-\n app/Component/ES/Processor/TargetEntitiesSelector.php | 19 ++++---\n app/Component/MeetingBot/Service/ParticipantMatcher.php | 46 ++++++++++++----\n app/Exceptions/RateLimitException.php | 19 ++++++-\n app/Http/Middleware/McpTierMiddleware.php | 27 ++--------\n app/Jobs/Crm/MatchActivityCrmData.php | 47 ++++++++++++----\n app/Jobs/Middleware/HandleHubspotRateLimit.php | 42 +++++++++++++++\n app/Mcp/Servers/JiminnyServer.php | 2 +\n app/Mcp/Tools/GetMeTool.php | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++\n app/Models/Feature/FeatureEnum.php | 1 +\n app/Services/Activity/HubSpot/ProviderResolver.php | 4 +-\n app/Services/Activity/HubSpot/ProviderResolverInterface.php | 2 +-\n app/Services/Activity/HubSpot/Providers/Provider.php | 2 +-\n app/Services/Activity/HubSpot/Providers/ProviderKixie.php | 2 +-\n app/Services/Activity/HubSpot/Providers/ProviderOrum.php | 2 +-\n app/Services/Activity/HubSpot/Providers/ProviderTwilio.php | 2 +-\n app/Services/Activity/HubSpot/Providers/ProviderTwilioFlex.php | 5 +-\n app/Services/Activity/HubSpot/Service.php | 97 +++++++++++++++++++++++++++------\n app/Services/Crm/Hubspot/Client.php | 132 +++++++++++++++++++++++++++++++++++++++++++++\n app/Services/Crm/Hubspot/HubspotClientInterface.php | 15 ++++++\n app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php | 21 ++++----\n app/Services/Crm/Hubspot/Pagination/PaginationState.php | 2 +-\n database/migrations/2026_05_13_124153_create_mcp_feature_flag.php | 25 +++++++++\n tests/Feature/Mcp/GetMeToolFeatureTest.php | 140 +++++++++++++++++++++++++++++++++++++++++++++++\n tests/Feature/Mcp/ListCallsToolFeatureTest.php | 2 +-\n tests/Feature/Mcp/McpTestHelpersTrait.php | 19 ++++++-\n tests/Unit/Component/ES/ChunkSizeTest.php | 50 +++++++++++++++++\n tests/Unit/Component/ES/Processor/DTOs/SelectionListTest.php | 27 +++++++---\n tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 39 ++++++++------\n tests/Unit/Component/MeetingBot/Service/ParticipantMatcherTest.php | 68 ++++++++++++++++++++++-\n tests/Unit/Exceptions/RateLimitExceptionTest.php | 56 +++++++++++++++++++\n tests/Unit/Jobs/Crm/MatchActivityCrmDataTest.php | 8 +--\n tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++\n tests/Unit/Services/Activity/HubSpot/ServiceTest.php | 109 +++++++++++++++++++++++++++++++++++++\n tests/Unit/Services/Crm/Hubspot/ClientTest.php | 250 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n tests/Unit/Services/Crm/Hubspot/Pagination/HubspotPaginationServiceTest.php | 283 +++++++++++++++++++++---------------------------------------------------------------------------\n 37 files changed, 1587 insertions(+), 344 deletions(-)\n create mode 100644 app/Component/ES/ChunkSize.php\n create mode 100644 app/Jobs/Middleware/HandleHubspotRateLimit.php\n create mode 100644 app/Mcp/Tools/GetMeTool.php\n create mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.php\n create mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.php\n create mode 100644 tests/Unit/Component/ES/ChunkSizeTest.php\n create mode 100644 tests/Unit/Exceptions/RateLimitExceptionTest.php\n create mode 100644 tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull\nAlready up to date.\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20676-delete-report-related-objects\nSwitched to a new branch 'JY-20676-delete-report-related-objects'\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20676-delete-report-related-objects) $ csfix\ndocker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff \nPHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.\nPHP runtime: 8.3.30\nRunning analysis on 7 cores with 10 files per process.\nParallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!\nLoaded config default from \".php-cs-fixer.dist.php\".\n 5690/5690 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%\n\n 1) app/Console/Commands/JiminnyDebugCommand.php (statement_indentation, blank_line_before_statement)\n ---------- begin diff ----------\n--- /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php\n+++ /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php\n@@ -23,6 +23,7 @@\n \n if ($action === 'redis-set') {\n $this->testRedisSet();\n+\n return;\n }\n \n@@ -45,7 +46,7 @@\n $ttl = 60;\n \n try {\n-// $result = Redis::set($testKey, $testValue, 'EX', $ttl, 'NX');\n+ // $result = Redis::set($testKey, $testValue, 'EX', $ttl, 'NX');\n $result = Redis::set($testKey, $testValue, ['nx', 'ex' => $ttl]);\n \n if ($result) {\n\n ----------- end diff -----------\n\n\nFixed 1 of 5690 files in 50.673 seconds, 67.00 MB memory used\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20676-delete-report-related-objects) $ ;xd\ndocker exec -it docker_lamp_1 bash -c \"mv /usr/local/etc/php/conf.d/xdebug.ini ~/xdebug.ini\"\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\ndocker exec -it docker_lamp_1 supervisorctl restart all\njiminny-worker-processing-2:jiminny-worker-processing-2_00: stopped\njiminny-worker-processing-3:jiminny-worker-processing-3_00: stopped\njiminny-worker-processing-4:jiminny-worker-processing-4_00: stopped\njiminny-worker-processing-5:jiminny-worker-processing-5_00: stopped\njiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00: stopped\nworker-analytics:worker-analytics_00: stopped\nworker-crm-update:worker-crm-update_00: stopped\nworker-download:worker-download_00: stopped\nworker-nudges:worker-nudges_00: stopped\nworker-calendar:worker-calendar_00: stopped\nworker-audio:worker-audio_00: stopped\njiminny-worker-processing-1:jiminny-worker-processing-1_00: stopped\nworker:worker_00: stopped\nworker-conferences:worker-conferences_00: stopped\nworker-crm-sync:worker-crm-sync_00: stopped\nworker-emails:worker-emails_00: stopped\nworker-es-update:worker-es-update_00: stopped\nartisan-schedule:artisan-schedule_00: stopped\nartisan-schedule:artisan-schedule_00: started\njiminny-worker-processing-1:jiminny-worker-processing-1_00: started\njiminny-worker-processing-2:jiminny-worker-processing-2_00: started\njiminny-worker-processing-3:jiminny-worker-processing-3_00: started\njiminny-worker-processing-4:jiminny-worker-processing-4_00: started\njiminny-worker-processing-5:jiminny-worker-processing-5_00: started\njiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00: started\nworker:worker_00: started\nworker-analytics:worker-analytics_00: started\nworker-audio:worker-audio_00: started\nworker-calendar:worker-calendar_00: started\nworker-conferences:worker-conferences_00: started\nworker-crm-sync:worker-crm-sync_00: started\nworker-crm-update:worker-crm-update_00: started\nworker-download:worker-download_00: started\nworker-emails:worker-emails_00: started\nworker-es-update:worker-es-update_00: started\nworker-nudges:worker-nudges_00: started\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\ndocker exec -it docker_lamp_1 php -v\nPHP 8.3.30 (cli) (built: Mar 16 2026 22:32:32) (NTS)\nCopyright (c) The PHP Group\nZend Engine v4.3.30, Copyright (c) Zend Technologies\n with Zend OPcache v8.3.30, Copyright (c), by Zend Technologies\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20676-delete-report-related-objects) $ git sta","is_focused":true},{"role":"AXRadioButton","text":"DOCKER","depth":2,"bounds":{"left":0.0,"top":0.05888889,"width":0.19826388,"height":0.026666667},"on_screen":true,"role_description":"radio button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close Tab","depth":3,"bounds":{"left":0.004166667,"top":0.06333333,"width":0.011111111,"height":0.017777778},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"DEV (docker)","depth":2,"bounds":{"left":0.19826388,"top":0.05888889,"width":0.19826388,"height":0.026666667},"on_screen":true,"role_description":"radio button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close Tab","depth":3,"bounds":{"left":0.20243056,"top":0.06333333,"width":0.011111111,"height":0.017777778},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"APP (-zsh)","depth":2,"bounds":{"left":0.39652777,"top":0.05888889,"width":0.19791667,"height":0.026666667},"on_screen":true,"role_description":"radio button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close Tab","depth":3,"bounds":{"left":0.40069443,"top":0.06333333,"width":0.011111111,"height":0.017777778},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"ffmpeg","depth":2,"bounds":{"left":0.59444445,"top":0.05888889,"width":0.19791667,"height":0.026666667},"on_screen":true,"role_description":"radio button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close Tab","depth":3,"bounds":{"left":0.5986111,"top":0.06333333,"width":0.011111111,"height":0.017777778},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"-zsh","depth":2,"bounds":{"left":0.79236114,"top":0.05888889,"width":0.19791667,"height":0.026666667},"on_screen":true,"role_description":"radio button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close Tab","depth":3,"bounds":{"left":0.7965278,"top":0.06333333,"width":0.011111111,"height":0.017777778},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"⌥⌘1","depth":1,"bounds":{"left":0.9618056,"top":0.032222223,"width":0.038194418,"height":0.018888889},"on_screen":true,"automation_id":"_NS:8","role_description":"text"},{"role":"AXStaticText","text":"APP (-zsh)","depth":1,"bounds":{"left":0.47777778,"top":0.033333335,"width":0.05138889,"height":0.017777778},"on_screen":true,"role_description":"text"}]...
|
2802650493718167367
|
-1358120912881272742
|
click
|
accessibility
|
NULL
|
Last login: Mon May 18 09:17:28 on ttys007
Poetry Last login: Mon May 18 09:17:28 on ttys007
Poetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parents
Poetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parents
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ co master
error: Your local changes to the following files would be overwritten by checkout:
PIPEDRIVE_V2_MIGRATION_TICKETS.md
Please commit your changes or stash them before you switch branches.
Aborting
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ git pull
remote: Enumerating objects: 1047, done.
remote: Counting objects: 100% (832/832), done.
remote: Compressing objects: 100% (298/298), done.
remote: Total 1047 (delta 634), reused 596 (delta 534), pack-reused 215 (from 3)
Receiving objects: 100% (1047/1047), 353.16 KiB | 1.56 MiB/s, done.
Resolving deltas: 100% (687/687), completed with 107 local objects.
From github.com:jiminny/app
907c54896c..34656c53ed pipedrive-sdk-poc -> origin/pipedrive-sdk-poc
03325ec50f..4e7078fd8b JY-18091-upgrade-to-php-8-5 -> origin/JY-18091-upgrade-to-php-8-5
e7d231e163..bc6a3fce6b JY-20725-handle-HS-search-rate-limit -> origin/JY-20725-handle-HS-search-rate-limit
* [new branch] JY-20749-user-can-view-recorded-meetings -> origin/JY-20749-user-can-view-recorded-meetings
98ca281a04..e0351be069 JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue
569abb5149..3906a9238a JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details -> origin/JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details
ad6c2a86e8..50eb6afba9 JY-20846-mcp-enable-the-ai-to-know-details-about-the-user -> origin/JY-20846-mcp-enable-the-ai-to-know-details-about-the-user
* [new branch] JY-20893-chunk-control-per-update-target -> origin/JY-20893-chunk-control-per-update-target
31c62924a5..cb4ebf0c36 master -> origin/master
Updating 907c54896c..34656c53ed
Fast-forward
PIPEDRIVE_V2_MIGRATION_TICKETS.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 52 insertions(+)
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ co master
M .env.local
M config/logging.php
Switched to branch 'master'
Your branch is behind 'origin/master' by 31 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull
Updating 31c62924a5..cb4ebf0c36
Fast-forward
app/Component/ES/Processor/Traits/SelectEntityListTrait.php | 20 ------
app/Services/Calendar/CalendarActivityService.php | 46 +++++++++++++
app/Services/Calendar/Command/MapActivityData.php | 106 +++-------------------------
docs/mcp/explorer/explorer.html | 104 +++++++++++++++++++++++++---
docs/mcp/explorer/explorer.template.html | 102 ++++++++++++++++++++++++---
docs/mcp/tools-list.json | 373 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
docs/mcp/tools.md | 117 +++++++++++++++++++++++--------
tests/Unit/Component/ES/AsyncUpdateElasticSearchTest.php | 16 +----
tests/Unit/Component/ES/Listeners/UpdateMultipleTargetsListenerTest.php | 10 ---
tests/Unit/Component/ES/Listeners/UpdateSingleTargetListenerTest.php | 6 --
tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 9 ---
tests/Unit/Component/ES/Processor/Traits/SelectEntityListTraitTest.php | 15 ++--
tests/Unit/Component/ES/UpdateProcessManagerTest.php | 2 -
tests/Unit/Services/Calendar/CalendarActivityServiceTest.php | 150 ++++++++++++++++++++++++++++++++++++++--
tests/Unit/Services/Calendar/Command/MapActivityDataTest.php | 78 ++-------------------
15 files changed, 832 insertions(+), 322 deletions(-)
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20613-allow-owner-role-on-team-setup
Switched to a new branch 'JY-20613-allow-owner-role-on-team-setup'
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ csfix
docker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff
PHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.
PHP runtime: 8.3.30
Running analysis on 7 cores with 10 files per process.
Parallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!
Loaded config default from ".php-cs-fixer.dist.php".
5682/5682 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
Fixed 0 of 5682 files in 56.978 seconds, 67.00 MB memory used
What's next:
Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1
Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ csfix
docker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff
PHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.
PHP runtime: 8.3.30
Running analysis on 7 cores with 10 files per process.
Parallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!
Loaded config default from ".php-cs-fixer.dist.php".
5682/5682 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
Fixed 0 of 5682 files in 49.910 seconds, 60.00 MB memory used
What's next:
Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1
Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git pull
remote: Enumerating objects: 248, done.
remote: Counting objects: 100% (128/128), done.
remote: Compressing objects: 100% (23/23), done.
remote: Total 59 (delta 43), reused 44 (delta 33), pack-reused 0 (from 0)
Unpacking objects: 100% (59/59), 10.48 KiB | 228.00 KiB/s, done.
From github.com:jiminny/app
b7df560451..190239dfd4 JY-20613-allow-owner-role-on-team-setup -> origin/JY-20613-allow-owner-role-on-team-setup
e0351be069..d94a285ae7 JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue
* [new branch] JY-20920-fix-participant-matcher -> origin/JY-20920-fix-participant-matcher
cb4ebf0c36..90bca4e4b2 master -> origin/master
Merge made by the 'ort' strategy.
app/Component/ES/ChunkSize.php | 54 +++++++++++++++++++++++++++
app/Component/ES/Processor/DTOs/SelectionList.php | 4 +-
app/Component/ES/Processor/TargetEntitiesSelector.php | 19 ++++++----
app/Http/Middleware/McpTierMiddleware.php | 27 +++-----------
app/Mcp/Servers/JiminnyServer.php | 2 +
app/Mcp/Tools/GetMeTool.php | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
app/Models/Feature/FeatureEnum.php | 1 +
database/migrations/2026_05_13_124153_create_mcp_feature_flag.php | 25 +++++++++++++
front-end/src/components/Settings/Kiosk/modals/EditTeamModal/EditTeamModal.vue | 52 ++++++++++++++++++--------
front-end/src/components/Settings/Kiosk/modals/EditTeamModal/__tests__/EditTeamModal.spec.js | 14 +++++++
tests/Feature/Mcp/GetMeToolFeatureTest.php | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/Feature/Mcp/ListCallsToolFeatureTest.php | 2 +-
tests/Feature/Mcp/McpTestHelpersTrait.php | 19 +++++++++-
tests/Unit/Component/ES/ChunkSizeTest.php | 50 +++++++++++++++++++++++++
tests/Unit/Component/ES/Processor/DTOs/SelectionListTest.php | 27 ++++++++++----
tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 39 +++++++++++---------
16 files changed, 557 insertions(+), 75 deletions(-)
create mode 100644 app/Component/ES/ChunkSize.php
create mode 100644 app/Mcp/Tools/GetMeTool.php
create mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.php
create mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.php
create mode 100644 tests/Unit/Component/ES/ChunkSizeTest.php
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git push
Enumerating objects: 40, done.
Counting objects: 100% (34/34), done.
Delta compression using up to 8 threads
Compressing objects: 100% (18/18), done.
Writing objects: 100% (18/18), 1.58 KiB | 1.58 MiB/s, done.
Total 18 (delta 15), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (15/15), completed with 13 local objects.
To github.com:jiminny/app.git
190239dfd4..ec1b261264 JY-20613-allow-owner-role-on-team-setup -> JY-20613-allow-owner-role-on-team-setup
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ gbr
* JY-20613-allow-owner-role-on-team-setup
pipedrive-sdk-poc
master
JY-20903-update_activity-stage-on-opportunity-change
JY-20904-fix-update-es-on-activity-command
JY-20891-improve-sms-text-relays
JY-20725-handle-HS-search-rate-limit
JY-20818-move-AJ-reports-to-separated-datadog-metric
JY-20773-fix-automated-reports-user-pilot-tracking
JY-20157-AJ-report-not-send-notification
JY-20508-notify-before-AJ-report-expiration
JY-20372-ai-reports-promotion-pages
JY-20352-sync-opportunities-without-a-local-owner-user-id-is-null
JY-20738-debug-AJ-tracking-UP
a
JY-18909-automated-reports-ask-jiminny
JY-20692-fix-integration-app-[API_KEY]
JY-20553-debug-crm-sync-delays
JY-20698-fix-SF-activity-types-on-new-playbook
JY-20543-AJ-report-tracking
JY-20384-handle-auto-sync-with-no-access-to-event-type
JY-20458-ask-jiminny-user-definitions
JY-19666-fix-import-contacts-account-association
JY-19666-HS-import-contacts-and-accounts-batch-job
JY-20458-Ask-Jiminny-Reports
JY-20200-batch-update-CRM-objects-Salesforce
JY-19666-HS-webhooks-add-contact-and-company
JY-20348-trigger-setup-DI-layout-on-team-creation
JY-20326-refactor-info-message-in-command
JY-20317-fix-auto-log-delay-issue-on-all-channels-disabled
JY-20312-remove-on-update-change-last-synced-at-crm-configurations
JY-20306-SF-skip-auto-sync-for-task-based-playbook
JY-20192-remove-deleted-team-from-saved-search-filters
JY-20197-import-opportunity-batch-job
JY-20293-enable-status-field-for-pipedrive-deals
JY-20191-remove-commands-interactive-prompts
JY-20118-change-default-sync-strategy
JY-20183-add-cache-on-auto-log-delay
JY-20197-add-import-opportunity-batch-job
20118-hs-opportunity-make-webhook-strategy-default
JY-20118-make-default-hs-opportunity-sync-strategy-webhook-based
JY-20196-handle-opportunity-without-note
JY-20118-improve-opportunity-import
JY-20189-handle-activity-search-on-deleted-groups
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ co JY-20725-handle-HS-search-rate-limit
M .env.local
M config/logging.php
Switched to branch 'JY-20725-handle-HS-search-rate-limit'
Your branch is behind 'origin/JY-20725-handle-HS-search-rate-limit' by 439 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ git pull
Updating 0f3e438941..bc6a3fce6b
Fast-forward
.gitignore | 3 +-
.windsurfrules | 168 ++---
CLAUDE.md | 1 +
app/Component/ActivityAnalytics/Service/CalculateTalkTimeOffsetsFromTranscription.php | 24 +-
app/Component/AiActivityType/Services/AiActivityTypeEligibilityChecker.php | 28 +-
app/Component/AiAutomation/Actions/PrepareUpdateDtoAction.php | 32 +-
app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.php | 47 ++
app/Component/AiAutomation/TestCrmAiPromptService.php | 14 +
app/Component/AiCallScoring/Services/AiCallScoringEligibilityChecker.php | 9 +
app/Component/ES/ElasticSearchDocumentPartialUpdater.php | 13 +-
app/Component/ES/ElasticSearchWorkerManager.php | 86 ---
app/Component/ES/Processor/Actions/LoadDocumentsAction.php | 80 +--
app/Component/ES/Processor/EntityQueryBuilder.php | 12 +-
app/Component/ES/Processor/TargetEntitiesSelector.php | 2 +-
app/Component/ES/Processor/Traits/SkipActivityTrait.php | 25 -
app/Component/ES/Repositories/EsResetActivityRepository.php | 11 +-
app/Component/ES/Worker/ActivityWorker.php | 73 --
app/Component/ES/Worker/EntityWorker.php | 44 --
app/Component/ES/Worker/WorkerAmount.php | 60 --
app/Component/ES/Worker/WorkerInterface.php | 15 -
app/Component/ElasticSearch/Contract/Searchable.php | 4 +
app/Component/Encoding/Job/AnalyzeTrackChannelsJob.php | 20 +-
app/Component/Encoding/Service/GenerateSpeechFromSilenceService.php | 85 ++-
app/Component/FFMpeg/Services/GetSpeechIntervalsService.php | 18 +-
app/Component/LanguageDetection/Services/FindSpeechTimeService.php | 22 +-
app/Component/Nudge/Job/ProcessOrganisationImmediateNudgesJob.php | 218 +++++-
app/Component/ParagraphBreaker/Services/TranscriptionParagraphsService.php | 4 +
app/Component/ParticipantSpeech/Services/ParticipantSpeechesCreator.php | 33 +
app/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleter.php | 15 +
app/Component/ParticipantSpeech/Services/ParticipantSpeechesProvider.php | 51 +-
app/Component/ParticipantSpeech/Services/ParticipantSpeechesUploader.php | 36 +
app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.php | 11 +
app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/NoAssemblyIdException.php | 11 +
app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/SuccessfulResponse.php | 6 +
app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNotCorrectFormatException.php | 11 +
app/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeechesService.php | 23 +-
app/Component/Transcription/Diarization/Source/MeetingBotSource.php | 16 +-
app/Component/Transcription/TranscriptionProcessor/TranscriptionProcessor.php | 3 +
app/Console/Commands/Activities/ActivityHardDeleteCommand.php | 4 +-
app/Console/Commands/Activities/Copy.php | 2 +
app/Console/Commands/Activities/SetupIntegration/TwilioSetS3RecordingCredentialsCommand.php | 119 ++++
app/Console/Commands/Activities/UpdateActivityElasticSearchDocumentCommand.php | 10 +-
app/Console/Commands/Crm/BackfillOpportunityUserFromAccountCommand.php | 126 ++++
app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.php | 19 -
app/Console/Commands/Elasticsearch/AsyncUpdateEsEntities.php | 50 +-
app/Console/Commands/Elasticsearch/ResetAsyncElasticSearchCommand.php | 30 +-
app/Console/Commands/GeckoExport/GeckoExportParticipantSpeechesCommand.php | 14 +-
app/Console/Commands/IssueMcpTokenCommand.php | 84 +++
app/Console/Commands/JiminnyDebugCommand.php | 7 +-
app/Console/Commands/Tracks/CleanupActivityTracksCommand.php | 2 +-
app/Console/Kernel.php | 6 +-
app/Contracts/Services/Calendar/CalendarTrait.php | 80 ++-
app/Events/AutomatedReports/AutomatedReportGenerated.php | 3 +
app/Http/Controllers/API/AiCallScoring/AiScorecardController.php | 7 +-
app/Http/Controllers/API/TeamAiAutomationController.php | 8 +
app/Http/Controllers/CustomerApi/CustomerApiController.php | 4 +-
app/Http/Controllers/Kiosk/ActivityController.php | 58 +-
app/Http/Controllers/Settings/PlaybookController.php | 15 +-
app/Http/Kernel.php | 23 +
app/Http/Middleware/McpAuditMiddleware.php | 156 ++++
app/Http/Middleware/McpTierMiddleware.php | 54 ++
app/Http/Requests/API/V2/ZapierUploadActivityRequest.php | 28 +-
app/Jobs/Activity/Import/ImportTwilioVideoSpeechesJob.php | 25 +-
app/Jobs/Activity/Import/IsActivityReadyForProcessingJob.php | 10 +-
app/Jobs/Calendar/SetupCalendarSync.php | 21 +-
app/Jobs/ImportRemoteTrackJob.php | 96 ++-
app/Jobs/Mailbox/EmailTextRelay.php | 15 +-
app/Mcp/Contracts/McpCallRepositoryInterface.php | 30 +
app/Mcp/DTO/ListCallsFilters.php | 29 +
app/Mcp/Errors/McpError.php | 123 ++++
app/Mcp/Repositories/McpActivityHydrator.php | 145 ++++
app/Mcp/Repositories/McpCallRepository.php | 84 +++
app/Mcp/Repositories/McpElasticCallRepository.php | 171 +++++
app/Mcp/Servers/JiminnyServer.php | 38 +
app/Mcp/Tools/ListCallsTool.php | 205 ++++++
app/Models/Activity.php | 10 +-
app/Models/Activity/Transcription.php | 17 +-
app/Models/ElasticSearch/OpportunityElasticSearchTrait.php | 5 +
app/Models/Participant.php | 1 +
app/Providers/AppServiceProvider.php | 22 +
app/Repositories/Crm/ContactRepository.php | 69 +-
app/Repositories/ParticipantSpeechRepository.php | 13 +-
app/Services/Activity/ParticipantsService.php | 19 +-
app/Services/Activity/Twilio/S3RecordingCredentialsService.php | 82 +++
app/Services/ActivityService.php | 21 +-
app/Services/Calendar/CalendarActivityService.php | 46 ++
app/Services/Calendar/Command/ImportParticipants.php | 1 +
app/Services/Calendar/Command/MapActivityData.php | 106 +--
app/Services/Calendar/GoogleCalendarService.php | 12 +-
app/Services/Crm/Close/Processor/OpportunityProcessor.php | 2 +-
app/Services/Crm/Close/Service.php | 22 +-
app/Services/Crm/Copper/Service.php | 12 +-
app/Services/Crm/Hubspot/Service.php | 154 +++-
app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php | 88 ++-
app/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTrait.php | 22 +-
app/Services/Crm/Pipedrive/Service.php | 17 +-
app/Services/Crm/Salesforce/Service.php | 42 +-
app/Services/Mail/Office/EmailApiClient.php | 129 +---
app/Services/RecallAI/Commands/ScheduleBotCommand.php | 39 +-
app/Services/RecallAI/RecallAIService.php | 22 +-
composer.json | 3 +-
composer.lock | 87 ++-
config/mcp.php | 23 +
database/migrations/2026_04_30_120000_create_mcp_audit_log_table.php | 36 +
docs/mcp/explorer/explorer.html | 697 ++++++++++++++++++
docs/mcp/explorer/explorer.template.html | 697 ++++++++++++++++++
docs/mcp/explorer/generate.js | 215 ++++++
docs/mcp/explorer/tool-explorer-meta.json | 11 +
docs/mcp/tools-list.json | 2536 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
docs/mcp/tools.md | 621 ++++++++++++++++
front-end/package.json | 4 +-
front-end/src/components/Settings/OrgSettings/AiAutomation/CrmFilling/TemplateFieldForm.vue | 28 +-
front-end/src/components/Settings/OrgSettings/Playbooks/AddEditPlaybook.vue | 10 +
front-end/src/components/playback/comments/ActivityComment.less | 10 +-
front-end/src/components/shared/PromptTester/PromptTester.vue | 12 +-
front-end/src/components/shared/__tests__/PromptTester.spec.js | 35 +
front-end/src/components/shared/modals/EntityPickerModal/__tests__/useEntitiesCache.spec.ts | 37 +
front-end/src/components/shared/modals/EntityPickerModal/useEntitiesCache.ts | 9 +
front-end/yarn.lock | 16 +-
phpstan-baseline.neon | 50 --
routes/api.php | 11 +
sonar-project.properties | 91 ++-
tests/Feature/Component/Nudge/ProcessOrganisationImmediateNudgesJobTest.php | 534 ++++++++++++++
tests/Feature/Jobs/ImportRemoteTrackJobTest.php | 283 +++++++-
tests/Feature/Mcp/IssueMcpTokenCommandTest.php | 53 ++
tests/Feature/Mcp/ListCallsToolElasticFeatureTest.php | 155 ++++
tests/Feature/Mcp/ListCallsToolFeatureTest.php | 352 ++++++++++
tests/Feature/Mcp/McpTestHelpersTrait.php | 77 ++
tests/Feature/Services/Team/TeamDeleteHandlers/Retention/RetentionRepositoryHandlerTest.php | 1 +
tests/Stubs/SentryStub.php | 18 +
tests/Unit/Component/ActivityAnalytics/Service/CalculateTalkTimeOffsetFromTranscriptionTest.php | 28 +-
tests/Unit/Component/AiActivityType/Services/AiActivityTypeEligibilityCheckerTest.php | 103 ++-
tests/Unit/Component/AiAutomation/Actions/PrepareUpdateDtoActionTest.php | 91 +++
tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheckerTest.php | 124 ++++
tests/Unit/Component/AiAutomation/TestCrmAiPromptServiceTest.php | 67 +-
tests/Unit/Component/AiCallScoring/Services/AiCallScoringEligibilityCheckerTest.php | 55 ++
tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.php | 135 ----
tests/Unit/Component/ES/Processor/Actions/LoadDocumentsActionTest.php | 220 ++++++
tests/Unit/Component/ES/Processor/EntityQueryBuilderTest.php | 21 +-
tests/Unit/Component/ES/Processor/Traits/SkipActivityTraitTest.php | 51 --
tests/Unit/Component/ES/Worker/ActivityWorkerTest.php | 174 -----
tests/Unit/Component/ES/Worker/EntityWorkerTest.php | 97 ---
tests/Unit/Component/ES/Worker/WorkerAmountTest.php | 116 ---
tests/Unit/Component/Encoding/Job/AnalyzeTrackChannelsJobTest.php | 52 +-
tests/Unit/Component/Encoding/Service/GenerateSpeechFromSilenceServiceTest.php | 171 ++---
tests/Unit/Component/FFMpeg/Services/GetSpeechIntervalsTest.php | 36 +-
tests/Unit/Component/LanguageDetection/Services/FindSpeechTimeServiceTest.php | 20 +-
tests/Unit/Component/MobileSettings/MobileSettingsControllerTest.php | 5 +-
tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCreatorTest.php | 75 ++
tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleterTest.php | 63 ++
tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesProviderTest.php | 134 ++++
tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesUploaderTest.php | 57 ++
tests/Unit/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeechesServiceTest.php | 51 +-
tests/Unit/Component/Transcription/Diarization/Source/MeetingBotSourceTest.php | 29 +-
tests/Unit/Contracts/Services/Calendar/CalendarTraitTest.php | 58 +-
tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.php | 159 +++++
tests/Unit/Jobs/Activity/Import/ImportTwilioVideoSpeechesJobTest.php | 22 +-
tests/Unit/Jobs/Activity/Import/IsActivityReadyForProcessingJobTest.php | 26 +-
tests/Unit/Jobs/Calendar/SetupCalendarSyncTest.php | 25 -
tests/Unit/Services/Activity/ParticipantsServiceTest.php | 12 +-
tests/Unit/Services/Activity/Twilio/S3RecordingCredentialsServiceTest.php | 180 +++++
tests/Unit/Services/ActivityServiceTest.php | 132 ++++
tests/Unit/Services/Calendar/CalendarActivityServiceTest.php | 150 +++-
tests/Unit/Services/Calendar/Command/ImportParticipantsTest.php | 6 +-
tests/Unit/Services/Calendar/Command/MapActivityDataTest.php | 78 +-
tests/Unit/Services/Calendar/GoogleCalendarServiceTest.php | 116 +++
tests/Unit/Services/Crm/Close/ServiceTest.php | 165 +++++
tests/Unit/Services/Crm/Hubspot/ServiceTest.php | 272 ++++++-
tests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTest.php | 25 +-
tests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTraitMatchActivitiesTest.php | 3 +-
tests/Unit/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTraitOpportunitiesTest.php | 40 ++
tests/Unit/Services/Crm/Pipedrive/ImportOpportunityMatchActivitiesTest.php | 2 +
tests/Unit/Services/Crm/Salesforce/ServiceTest.php | 139 ++++
tests/Unit/Services/Mail/Office/EmailApiClientTest.php | 195 ++---
tests/Unit/Services/RecallAI/RecallAIServiceTest.php | 24 +-
175 files changed, 12562 insertions(+), 2162 deletions(-)
create mode 120000 CLAUDE.md
create mode 100644 app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.php
delete mode 100644 app/Component/ES/ElasticSearchWorkerManager.php
delete mode 100644 app/Component/ES/Processor/Traits/SkipActivityTrait.php
delete mode 100644 app/Component/ES/Worker/ActivityWorker.php
delete mode 100644 app/Component/ES/Worker/EntityWorker.php
delete mode 100644 app/Component/ES/Worker/WorkerAmount.php
delete mode 100644 app/Component/ES/Worker/WorkerInterface.php
create mode 100644 app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.php
create mode 100644 app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/NoAssemblyIdException.php
create mode 100644 app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNotCorrectFormatException.php
create mode 100644 app/Console/Commands/Activities/SetupIntegration/TwilioSetS3RecordingCredentialsCommand.php
create mode 100644 app/Console/Commands/Crm/BackfillOpportunityUserFromAccountCommand.php
delete mode 100644 app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.php
create mode 100644 app/Console/Commands/IssueMcpTokenCommand.php
create mode 100644 app/Http/Middleware/McpAuditMiddleware.php
create mode 100644 app/Http/Middleware/McpTierMiddleware.php
create mode 100644 app/Mcp/Contracts/McpCallRepositoryInterface.php
create mode 100644 app/Mcp/DTO/ListCallsFilters.php
create mode 100644 app/Mcp/Errors/McpError.php
create mode 100644 app/Mcp/Repositories/McpActivityHydrator.php
create mode 100644 app/Mcp/Repositories/McpCallRepository.php
create mode 100644 app/Mcp/Repositories/McpElasticCallRepository.php
create mode 100644 app/Mcp/Servers/JiminnyServer.php
create mode 100644 app/Mcp/Tools/ListCallsTool.php
create mode 100644 app/Services/Activity/Twilio/S3RecordingCredentialsService.php
create mode 100644 config/mcp.php
create mode 100644 database/migrations/2026_04_30_120000_create_mcp_audit_log_table.php
create mode 100644 docs/mcp/explorer/explorer.html
create mode 100644 docs/mcp/explorer/explorer.template.html
create mode 100644 docs/mcp/explorer/generate.js
create mode 100644 docs/mcp/explorer/tool-explorer-meta.json
create mode 100644 docs/mcp/tools-list.json
create mode 100644 docs/mcp/tools.md
create mode 100644 front-end/src/components/shared/modals/EntityPickerModal/__tests__/useEntitiesCache.spec.ts
create mode 100644 tests/Feature/Component/Nudge/ProcessOrganisationImmediateNudgesJobTest.php
create mode 100644 tests/Feature/Mcp/IssueMcpTokenCommandTest.php
create mode 100644 tests/Feature/Mcp/ListCallsToolElasticFeatureTest.php
create mode 100644 tests/Feature/Mcp/ListCallsToolFeatureTest.php
create mode 100644 tests/Feature/Mcp/McpTestHelpersTrait.php
create mode 100644 tests/Stubs/SentryStub.php
create mode 100644 tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheckerTest.php
delete mode 100644 tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.php
create mode 100644 tests/Unit/Component/ES/Processor/Actions/LoadDocumentsActionTest.php
delete mode 100644 tests/Unit/Component/ES/Processor/Traits/SkipActivityTraitTest.php
delete mode 100644 tests/Unit/Component/ES/Worker/ActivityWorkerTest.php
delete mode 100644 tests/Unit/Component/ES/Worker/EntityWorkerTest.php
delete mode 100644 tests/Unit/Component/ES/Worker/WorkerAmountTest.php
create mode 100644 tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCreatorTest.php
create mode 100644 tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.php
create mode 100644 tests/Unit/Services/Activity/Twilio/S3RecordingCredentialsServiceTest.php
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ git status
On branch master
Your branch is behind 'origin/master' by 114 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: .env.local
modified: app/Component/SCIM/Constants.php
modified: app/Component/SCIM/ScimProvisioning.php
modified: app/Component/Twilio/Conference/ConferenceManager/SoftPhoneManager.php
modified: app/Console/Commands/JiminnyDebugCommand.php
modified: app/DTO/SCIM/AAD/Request/CoreUserRequest.php
modified: app/DTO/SCIM/AAD/Response/CoreUser.php
modified: app/Services/Telephony/TextMessagingService.php
modified: config/logging.php
Untracked files:
(use "git add <file>..." to include in what will be committed)
.env.nikilocal
.env.other
WEBHOOK_FILTERING_IMPLEMENTATION.md
app/Component/SCIM/Mutators/Attributes/User/RoleAttr.php
app/Console/Commands/Crm/Hubspot/SimulateWebhooksCommand.php
app/Console/Commands/Reports/CreateMockAskJiminnyReportResultCommand.php
app/Rules/ListenerRoleCannotHaveAdminOrManagerPermissionRule.php
ids.txt
public/favicon.ico
raw_sql_query.sql
tests/Unit/Component/SCIM/Mutators/Attributes/User/RoleAttrTest.php
tests/Unit/Policies/CanAccessAiReportsTest.php
tests/Unit/Rules/ListenerRoleCannotHaveAdminOrManagerPermissionRuleTest.php
no changes added to commit (use "git add" and/or "git commit -a")
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull
remote: Enumerating objects: 306, done.
remote: Counting objects: 100% (299/299), done.
remote: Compressing objects: 100% (183/183), done.
remote: Total 306 (delta 213), reused 171 (delta 116), pack-reused 7 (from 1)
Receiving objects: 100% (306/306), 80.12 KiB | 1000.00 KiB/s, done.
Resolving deltas: 100% (213/213), completed with 53 local objects.
From github.com:jiminny/app
90bca4e4b2..5604af40cf master -> origin/master
4e7078fd8b..0b8343d179 JY-18091-upgrade-to-php-8-5 -> origin/JY-18091-upgrade-to-php-8-5
098eeaa087..d5a447e492 JY-20613-allow-owner-role-on-team-setup -> origin/JY-20613-allow-owner-role-on-team-setup
c3a76ace91..af65249d0f JY-20749-user-can-view-recorded-meetings -> origin/JY-20749-user-can-view-recorded-meetings
d94a285ae7..7ce96cb5fe JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue
* [new branch] JY-20842-remove-partial-updater -> origin/JY-20842-remove-partial-updater
* [new branch] JY-20920-fix-participant-flip -> origin/JY-20920-fix-participant-flip
* [new branch] secfix/npm-20260519 -> origin/secfix/npm-20260519
Updating cb4ebf0c36..5604af40cf
Fast-forward
app/Component/ES/ChunkSize.php | 54 +++++++++++++++++++
app/Component/ES/Processor/DTOs/SelectionList.php | 4 +-
app/Component/ES/Processor/TargetEntitiesSelector.php | 19 ++++---
app/Component/MeetingBot/Service/ParticipantMatcher.php | 46 ++++++++++++----
app/Exceptions/RateLimitException.php | 19 ++++++-
app/Http/Middleware/McpTierMiddleware.php | 27 ++--------
app/Jobs/Crm/MatchActivityCrmData.php | 47 ++++++++++++----
app/Jobs/Middleware/HandleHubspotRateLimit.php | 42 +++++++++++++++
app/Mcp/Servers/JiminnyServer.php | 2 +
app/Mcp/Tools/GetMeTool.php | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++
app/Models/Feature/FeatureEnum.php | 1 +
app/Services/Activity/HubSpot/ProviderResolver.php | 4 +-
app/Services/Activity/HubSpot/ProviderResolverInterface.php | 2 +-
app/Services/Activity/HubSpot/Providers/Provider.php | 2 +-
app/Services/Activity/HubSpot/Providers/ProviderKixie.php | 2 +-
app/Services/Activity/HubSpot/Providers/ProviderOrum.php | 2 +-
app/Services/Activity/HubSpot/Providers/ProviderTwilio.php | 2 +-
app/Services/Activity/HubSpot/Providers/ProviderTwilioFlex.php | 5 +-
app/Services/Activity/HubSpot/Service.php | 97 +++++++++++++++++++++++++++------
app/Services/Crm/Hubspot/Client.php | 132 +++++++++++++++++++++++++++++++++++++++++++++
app/Services/Crm/Hubspot/HubspotClientInterface.php | 15 ++++++
app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php | 21 ++++----
app/Services/Crm/Hubspot/Pagination/PaginationState.php | 2 +-
database/migrations/2026_05_13_124153_create_mcp_feature_flag.php | 25 +++++++++
tests/Feature/Mcp/GetMeToolFeatureTest.php | 140 +++++++++++++++++++++++++++++++++++++++++++++++
tests/Feature/Mcp/ListCallsToolFeatureTest.php | 2 +-
tests/Feature/Mcp/McpTestHelpersTrait.php | 19 ++++++-
tests/Unit/Component/ES/ChunkSizeTest.php | 50 +++++++++++++++++
tests/Unit/Component/ES/Processor/DTOs/SelectionListTest.php | 27 +++++++---
tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 39 ++++++++------
tests/Unit/Component/MeetingBot/Service/ParticipantMatcherTest.php | 68 ++++++++++++++++++++++-
tests/Unit/Exceptions/RateLimitExceptionTest.php | 56 +++++++++++++++++++
tests/Unit/Jobs/Crm/MatchActivityCrmDataTest.php | 8 +--
tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++
tests/Unit/Services/Activity/HubSpot/ServiceTest.php | 109 +++++++++++++++++++++++++++++++++++++
tests/Unit/Services/Crm/Hubspot/ClientTest.php | 250 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/Unit/Services/Crm/Hubspot/Pagination/HubspotPaginationServiceTest.php | 283 +++++++++++++++++++++---------------------------------------------------------------------------
37 files changed, 1587 insertions(+), 344 deletions(-)
create mode 100644 app/Component/ES/ChunkSize.php
create mode 100644 app/Jobs/Middleware/HandleHubspotRateLimit.php
create mode 100644 app/Mcp/Tools/GetMeTool.php
create mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.php
create mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.php
create mode 100644 tests/Unit/Component/ES/ChunkSizeTest.php
create mode 100644 tests/Unit/Exceptions/RateLimitExceptionTest.php
create mode 100644 tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull
Already up to date.
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20676-delete-report-related-objects
Switched to a new branch 'JY-20676-delete-report-related-objects'
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20676-delete-report-related-objects) $ csfix
docker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff
PHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.
PHP runtime: 8.3.30
Running analysis on 7 cores with 10 files per process.
Parallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!
Loaded config default from ".php-cs-fixer.dist.php".
5690/5690 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
1) app/Console/Commands/JiminnyDebugCommand.php (statement_indentation, blank_line_before_statement)
---------- begin diff ----------
--- /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php
+++ /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php
@@ -23,6 +23,7 @@
if ($action === 'redis-set') {
$this->testRedisSet();
+
return;
}
@@ -45,7 +46,7 @@
$ttl = 60;
try {
-// $result = Redis::set($testKey, $testValue, 'EX', $ttl, 'NX');
+ // $result = Redis::set($testKey, $testValue, 'EX', $ttl, 'NX');
$result = Redis::set($testKey, $testValue, ['nx', 'ex' => $ttl]);
if ($result) {
----------- end diff -----------
Fixed 1 of 5690 files i...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
57003
|
NULL
|
0
|
2026-05-19T08:48:35.533523+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779180515533_m1.jpg...
|
iTerm2
|
APP (-zsh)
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Last login: Mon May 18 09:17:28 on ttys007
Poetry Last login: Mon May 18 09:17:28 on ttys007
Poetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parents
Poetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parents
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ co master
error: Your local changes to the following files would be overwritten by checkout:
PIPEDRIVE_V2_MIGRATION_TICKETS.md
Please commit your changes or stash them before you switch branches.
Aborting
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ git pull
remote: Enumerating objects: 1047, done.
remote: Counting objects: 100% (832/832), done.
remote: Compressing objects: 100% (298/298), done.
remote: Total 1047 (delta 634), reused 596 (delta 534), pack-reused 215 (from 3)
Receiving objects: 100% (1047/1047), 353.16 KiB | 1.56 MiB/s, done.
Resolving deltas: 100% (687/687), completed with 107 local objects.
From github.com:jiminny/app
907c54896c..34656c53ed pipedrive-sdk-poc -> origin/pipedrive-sdk-poc
03325ec50f..4e7078fd8b JY-18091-upgrade-to-php-8-5 -> origin/JY-18091-upgrade-to-php-8-5
e7d231e163..bc6a3fce6b JY-20725-handle-HS-search-rate-limit -> origin/JY-20725-handle-HS-search-rate-limit
* [new branch] JY-20749-user-can-view-recorded-meetings -> origin/JY-20749-user-can-view-recorded-meetings
98ca281a04..e0351be069 JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue
569abb5149..3906a9238a JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details -> origin/JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details
ad6c2a86e8..50eb6afba9 JY-20846-mcp-enable-the-ai-to-know-details-about-the-user -> origin/JY-20846-mcp-enable-the-ai-to-know-details-about-the-user
* [new branch] JY-20893-chunk-control-per-update-target -> origin/JY-20893-chunk-control-per-update-target
31c62924a5..cb4ebf0c36 master -> origin/master
Updating 907c54896c..34656c53ed
Fast-forward
PIPEDRIVE_V2_MIGRATION_TICKETS.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 52 insertions(+)
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ co master
M .env.local
M config/logging.php
Switched to branch 'master'
Your branch is behind 'origin/master' by 31 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull
Updating 31c62924a5..cb4ebf0c36
Fast-forward
app/Component/ES/Processor/Traits/SelectEntityListTrait.php | 20 ------
app/Services/Calendar/CalendarActivityService.php | 46 +++++++++++++
app/Services/Calendar/Command/MapActivityData.php | 106 +++-------------------------
docs/mcp/explorer/explorer.html | 104 +++++++++++++++++++++++++---
docs/mcp/explorer/explorer.template.html | 102 ++++++++++++++++++++++++---
docs/mcp/tools-list.json | 373 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
docs/mcp/tools.md | 117 +++++++++++++++++++++++--------
tests/Unit/Component/ES/AsyncUpdateElasticSearchTest.php | 16 +----
tests/Unit/Component/ES/Listeners/UpdateMultipleTargetsListenerTest.php | 10 ---
tests/Unit/Component/ES/Listeners/UpdateSingleTargetListenerTest.php | 6 --
tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 9 ---
tests/Unit/Component/ES/Processor/Traits/SelectEntityListTraitTest.php | 15 ++--
tests/Unit/Component/ES/UpdateProcessManagerTest.php | 2 -
tests/Unit/Services/Calendar/CalendarActivityServiceTest.php | 150 ++++++++++++++++++++++++++++++++++++++--
tests/Unit/Services/Calendar/Command/MapActivityDataTest.php | 78 ++-------------------
15 files changed, 832 insertions(+), 322 deletions(-)
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20613-allow-owner-role-on-team-setup
Switched to a new branch 'JY-20613-allow-owner-role-on-team-setup'
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ csfix
docker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff
PHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.
PHP runtime: 8.3.30
Running analysis on 7 cores with 10 files per process.
Parallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!
Loaded config default from ".php-cs-fixer.dist.php".
5682/5682 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
Fixed 0 of 5682 files in 56.978 seconds, 67.00 MB memory used
What's next:
Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1
Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ csfix
docker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff
PHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.
PHP runtime: 8.3.30
Running analysis on 7 cores with 10 files per process.
Parallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!
Loaded config default from ".php-cs-fixer.dist.php".
5682/5682 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
Fixed 0 of 5682 files in 49.910 seconds, 60.00 MB memory used
What's next:
Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1
Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git pull
remote: Enumerating objects: 248, done.
remote: Counting objects: 100% (128/128), done.
remote: Compressing objects: 100% (23/23), done.
remote: Total 59 (delta 43), reused 44 (delta 33), pack-reused 0 (from 0)
Unpacking objects: 100% (59/59), 10.48 KiB | 228.00 KiB/s, done.
From github.com:jiminny/app
b7df560451..190239dfd4 JY-20613-allow-owner-role-on-team-setup -> origin/JY-20613-allow-owner-role-on-team-setup
e0351be069..d94a285ae7 JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue
* [new branch] JY-20920-fix-participant-matcher -> origin/JY-20920-fix-participant-matcher
cb4ebf0c36..90bca4e4b2 master -> origin/master
Merge made by the 'ort' strategy.
app/Component/ES/ChunkSize.php | 54 +++++++++++++++++++++++++++
app/Component/ES/Processor/DTOs/SelectionList.php | 4 +-
app/Component/ES/Processor/TargetEntitiesSelector.php | 19 ++++++----
app/Http/Middleware/McpTierMiddleware.php | 27 +++-----------
app/Mcp/Servers/JiminnyServer.php | 2 +
app/Mcp/Tools/GetMeTool.php | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
app/Models/Feature/FeatureEnum.php | 1 +
database/migrations/2026_05_13_124153_create_mcp_feature_flag.php | 25 +++++++++++++
front-end/src/components/Settings/Kiosk/modals/EditTeamModal/EditTeamModal.vue | 52 ++++++++++++++++++--------
front-end/src/components/Settings/Kiosk/modals/EditTeamModal/__tests__/EditTeamModal.spec.js | 14 +++++++
tests/Feature/Mcp/GetMeToolFeatureTest.php | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/Feature/Mcp/ListCallsToolFeatureTest.php | 2 +-
tests/Feature/Mcp/McpTestHelpersTrait.php | 19 +++++++++-
tests/Unit/Component/ES/ChunkSizeTest.php | 50 +++++++++++++++++++++++++
tests/Unit/Component/ES/Processor/DTOs/SelectionListTest.php | 27 ++++++++++----
tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 39 +++++++++++---------
16 files changed, 557 insertions(+), 75 deletions(-)
create mode 100644 app/Component/ES/ChunkSize.php
create mode 100644 app/Mcp/Tools/GetMeTool.php
create mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.php
create mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.php
create mode 100644 tests/Unit/Component/ES/ChunkSizeTest.php
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git push
Enumerating objects: 40, done.
Counting objects: 100% (34/34), done.
Delta compression using up to 8 threads
Compressing objects: 100% (18/18), done.
Writing objects: 100% (18/18), 1.58 KiB | 1.58 MiB/s, done.
Total 18 (delta 15), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (15/15), completed with 13 local objects.
To github.com:jiminny/app.git
190239dfd4..ec1b261264 JY-20613-allow-owner-role-on-team-setup -> JY-20613-allow-owner-role-on-team-setup
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ gbr
* JY-20613-allow-owner-role-on-team-setup
pipedrive-sdk-poc
master
JY-20903-update_activity-stage-on-opportunity-change
JY-20904-fix-update-es-on-activity-command
JY-20891-improve-sms-text-relays
JY-20725-handle-HS-search-rate-limit
JY-20818-move-AJ-reports-to-separated-datadog-metric
JY-20773-fix-automated-reports-user-pilot-tracking
JY-20157-AJ-report-not-send-notification
JY-20508-notify-before-AJ-report-expiration
JY-20372-ai-reports-promotion-pages
JY-20352-sync-opportunities-without-a-local-owner-user-id-is-null
JY-20738-debug-AJ-tracking-UP
a
JY-18909-automated-reports-ask-jiminny
JY-20692-fix-integration-app-[API_KEY]
JY-20553-debug-crm-sync-delays
JY-20698-fix-SF-activity-types-on-new-playbook
JY-20543-AJ-report-tracking
JY-20384-handle-auto-sync-with-no-access-to-event-type
JY-20458-ask-jiminny-user-definitions
JY-19666-fix-import-contacts-account-association
JY-19666-HS-import-contacts-and-accounts-batch-job
JY-20458-Ask-Jiminny-Reports
JY-20200-batch-update-CRM-objects-Salesforce
JY-19666-HS-webhooks-add-contact-and-company
JY-20348-trigger-setup-DI-layout-on-team-creation
JY-20326-refactor-info-message-in-command
JY-20317-fix-auto-log-delay-issue-on-all-channels-disabled
JY-20312-remove-on-update-change-last-synced-at-crm-configurations
JY-20306-SF-skip-auto-sync-for-task-based-playbook
JY-20192-remove-deleted-team-from-saved-search-filters
JY-20197-import-opportunity-batch-job
JY-20293-enable-status-field-for-pipedrive-deals
JY-20191-remove-commands-interactive-prompts
JY-20118-change-default-sync-strategy
JY-20183-add-cache-on-auto-log-delay
JY-20197-add-import-opportunity-batch-job
20118-hs-opportunity-make-webhook-strategy-default
JY-20118-make-default-hs-opportunity-sync-strategy-webhook-based
JY-20196-handle-opportunity-without-note
JY-20118-improve-opportunity-import
JY-20189-handle-activity-search-on-deleted-groups
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ co JY-20725-handle-HS-search-rate-limit
M .env.local
M config/logging.php
Switched to branch 'JY-20725-handle-HS-search-rate-limit'
Your branch is behind 'origin/JY-20725-handle-HS-search-rate-limit' by 439 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ git pull
Updating 0f3e438941..bc6a3fce6b
Fast-forward
.gitignore | 3 +-
.windsurfrules | 168 ++---
CLAUDE.md | 1 +
app/Component/ActivityAnalytics/Service/CalculateTalkTimeOffsetsFromTranscription.php | 24 +-
app/Component/AiActivityType/Services/AiActivityTypeEligibilityChecker.php | 28 +-
app/Component/AiAutomation/Actions/PrepareUpdateDtoAction.php | 32 +-
app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.php | 47 ++
app/Component/AiAutomation/TestCrmAiPromptService.php | 14 +
app/Component/AiCallScoring/Services/AiCallScoringEligibilityChecker.php | 9 +
app/Component/ES/ElasticSearchDocumentPartialUpdater.php | 13 +-
app/Component/ES/ElasticSearchWorkerManager.php | 86 ---
app/Component/ES/Processor/Actions/LoadDocumentsAction.php | 80 +--
app/Component/ES/Processor/EntityQueryBuilder.php | 12 +-
app/Component/ES/Processor/TargetEntitiesSelector.php | 2 +-
app/Component/ES/Processor/Traits/SkipActivityTrait.php | 25 -
app/Component/ES/Repositories/EsResetActivityRepository.php | 11 +-
app/Component/ES/Worker/ActivityWorker.php | 73 --
app/Component/ES/Worker/EntityWorker.php | 44 --
app/Component/ES/Worker/WorkerAmount.php | 60 --
app/Component/ES/Worker/WorkerInterface.php | 15 -
app/Component/ElasticSearch/Contract/Searchable.php | 4 +
app/Component/Encoding/Job/AnalyzeTrackChannelsJob.php | 20 +-
app/Component/Encoding/Service/GenerateSpeechFromSilenceService.php | 85 ++-
app/Component/FFMpeg/Services/GetSpeechIntervalsService.php | 18 +-
app/Component/LanguageDetection/Services/FindSpeechTimeService.php | 22 +-
app/Component/Nudge/Job/ProcessOrganisationImmediateNudgesJob.php | 218 +++++-
app/Component/ParagraphBreaker/Services/TranscriptionParagraphsService.php | 4 +
app/Component/ParticipantSpeech/Services/ParticipantSpeechesCreator.php | 33 +
app/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleter.php | 15 +
app/Component/ParticipantSpeech/Services/ParticipantSpeechesProvider.php | 51 +-
app/Component/ParticipantSpeech/Services/ParticipantSpeechesUploader.php | 36 +
app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.php | 11 +
app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/NoAssemblyIdException.php | 11 +
app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/SuccessfulResponse.php | 6 +
app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNotCorrectFormatException.php | 11 +
app/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeechesService.php | 23 +-
app/Component/Transcription/Diarization/Source/MeetingBotSource.php | 16 +-
app/Component/Transcription/TranscriptionProcessor/TranscriptionProcessor.php | 3 +
app/Console/Commands/Activities/ActivityHardDeleteCommand.php | 4 +-
app/Console/Commands/Activities/Copy.php | 2 +
app/Console/Commands/Activities/SetupIntegration/TwilioSetS3RecordingCredentialsCommand.php | 119 ++++
app/Console/Commands/Activities/UpdateActivityElasticSearchDocumentCommand.php | 10 +-
app/Console/Commands/Crm/BackfillOpportunityUserFromAccountCommand.php | 126 ++++
app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.php | 19 -
app/Console/Commands/Elasticsearch/AsyncUpdateEsEntities.php | 50 +-
app/Console/Commands/Elasticsearch/ResetAsyncElasticSearchCommand.php | 30 +-
app/Console/Commands/GeckoExport/GeckoExportParticipantSpeechesCommand.php | 14 +-
app/Console/Commands/IssueMcpTokenCommand.php | 84 +++
app/Console/Commands/JiminnyDebugCommand.php | 7 +-
app/Console/Commands/Tracks/CleanupActivityTracksCommand.php | 2 +-
app/Console/Kernel.php | 6 +-
app/Contracts/Services/Calendar/CalendarTrait.php | 80 ++-
app/Events/AutomatedReports/AutomatedReportGenerated.php | 3 +
app/Http/Controllers/API/AiCallScoring/AiScorecardController.php | 7 +-
app/Http/Controllers/API/TeamAiAutomationController.php | 8 +
app/Http/Controllers/CustomerApi/CustomerApiController.php | 4 +-
app/Http/Controllers/Kiosk/ActivityController.php | 58 +-
app/Http/Controllers/Settings/PlaybookController.php | 15 +-
app/Http/Kernel.php | 23 +
app/Http/Middleware/McpAuditMiddleware.php | 156 ++++
app/Http/Middleware/McpTierMiddleware.php | 54 ++
app/Http/Requests/API/V2/ZapierUploadActivityRequest.php | 28 +-
app/Jobs/Activity/Import/ImportTwilioVideoSpeechesJob.php | 25 +-
app/Jobs/Activity/Import/IsActivityReadyForProcessingJob.php | 10 +-
app/Jobs/Calendar/SetupCalendarSync.php | 21 +-
app/Jobs/ImportRemoteTrackJob.php | 96 ++-
app/Jobs/Mailbox/EmailTextRelay.php | 15 +-
app/Mcp/Contracts/McpCallRepositoryInterface.php | 30 +
app/Mcp/DTO/ListCallsFilters.php | 29 +
app/Mcp/Errors/McpError.php | 123 ++++
app/Mcp/Repositories/McpActivityHydrator.php | 145 ++++
app/Mcp/Repositories/McpCallRepository.php | 84 +++
app/Mcp/Repositories/McpElasticCallRepository.php | 171 +++++
app/Mcp/Servers/JiminnyServer.php | 38 +
app/Mcp/Tools/ListCallsTool.php | 205 ++++++
app/Models/Activity.php | 10 +-
app/Models/Activity/Transcription.php | 17 +-
app/Models/ElasticSearch/OpportunityElasticSearchTrait.php | 5 +
app/Models/Participant.php | 1 +
app/Providers/AppServiceProvider.php | 22 +
app/Repositories/Crm/ContactRepository.php | 69 +-
app/Repositories/ParticipantSpeechRepository.php | 13 +-
app/Services/Activity/ParticipantsService.php | 19 +-
app/Services/Activity/Twilio/S3RecordingCredentialsService.php | 82 +++
app/Services/ActivityService.php | 21 +-
app/Services/Calendar/CalendarActivityService.php | 46 ++
app/Services/Calendar/Command/ImportParticipants.php | 1 +
app/Services/Calendar/Command/MapActivityData.php | 106 +--
app/Services/Calendar/GoogleCalendarService.php | 12 +-
app/Services/Crm/Close/Processor/OpportunityProcessor.php | 2 +-
app/Services/Crm/Close/Service.php | 22 +-
app/Services/Crm/Copper/Service.php | 12 +-
app/Services/Crm/Hubspot/Service.php | 154 +++-
app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php | 88 ++-
app/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTrait.php | 22 +-
app/Services/Crm/Pipedrive/Service.php | 17 +-
app/Services/Crm/Salesforce/Service.php | 42 +-
app/Services/Mail/Office/EmailApiClient.php | 129 +---
app/Services/RecallAI/Commands/ScheduleBotCommand.php | 39 +-
app/Services/RecallAI/RecallAIService.php | 22 +-
composer.json | 3 +-
composer.lock | 87 ++-
config/mcp.php | 23 +
database/migrations/2026_04_30_120000_create_mcp_audit_log_table.php | 36 +
docs/mcp/explorer/explorer.html | 697 ++++++++++++++++++
docs/mcp/explorer/explorer.template.html | 697 ++++++++++++++++++
docs/mcp/explorer/generate.js | 215 ++++++
docs/mcp/explorer/tool-explorer-meta.json | 11 +
docs/mcp/tools-list.json | 2536 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
docs/mcp/tools.md | 621 ++++++++++++++++
front-end/package.json | 4 +-
front-end/src/components/Settings/OrgSettings/AiAutomation/CrmFilling/TemplateFieldForm.vue | 28 +-
front-end/src/components/Settings/OrgSettings/Playbooks/AddEditPlaybook.vue | 10 +
front-end/src/components/playback/comments/ActivityComment.less | 10 +-
front-end/src/components/shared/PromptTester/PromptTester.vue | 12 +-
front-end/src/components/shared/__tests__/PromptTester.spec.js | 35 +
front-end/src/components/shared/modals/EntityPickerModal/__tests__/useEntitiesCache.spec.ts | 37 +
front-end/src/components/shared/modals/EntityPickerModal/useEntitiesCache.ts | 9 +
front-end/yarn.lock | 16 +-
phpstan-baseline.neon | 50 --
routes/api.php | 11 +
sonar-project.properties | 91 ++-
tests/Feature/Component/Nudge/ProcessOrganisationImmediateNudgesJobTest.php | 534 ++++++++++++++
tests/Feature/Jobs/ImportRemoteTrackJobTest.php | 283 +++++++-
tests/Feature/Mcp/IssueMcpTokenCommandTest.php | 53 ++
tests/Feature/Mcp/ListCallsToolElasticFeatureTest.php | 155 ++++
tests/Feature/Mcp/ListCallsToolFeatureTest.php | 352 ++++++++++
tests/Feature/Mcp/McpTestHelpersTrait.php | 77 ++
tests/Feature/Services/Team/TeamDeleteHandlers/Retention/RetentionRepositoryHandlerTest.php | 1 +
tests/Stubs/SentryStub.php | 18 +
tests/Unit/Component/ActivityAnalytics/Service/CalculateTalkTimeOffsetFromTranscriptionTest.php | 28 +-
tests/Unit/Component/AiActivityType/Services/AiActivityTypeEligibilityCheckerTest.php | 103 ++-
tests/Unit/Component/AiAutomation/Actions/PrepareUpdateDtoActionTest.php | 91 +++
tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheckerTest.php | 124 ++++
tests/Unit/Component/AiAutomation/TestCrmAiPromptServiceTest.php | 67 +-
tests/Unit/Component/AiCallScoring/Services/AiCallScoringEligibilityCheckerTest.php | 55 ++
tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.php | 135 ----
tests/Unit/Component/ES/Processor/Actions/LoadDocumentsActionTest.php | 220 ++++++
tests/Unit/Component/ES/Processor/EntityQueryBuilderTest.php | 21 +-
tests/Unit/Component/ES/Processor/Traits/SkipActivityTraitTest.php | 51 --
tests/Unit/Component/ES/Worker/ActivityWorkerTest.php | 174 -----
tests/Unit/Component/ES/Worker/EntityWorkerTest.php | 97 ---
tests/Unit/Component/ES/Worker/WorkerAmountTest.php | 116 ---
tests/Unit/Component/Encoding/Job/AnalyzeTrackChannelsJobTest.php | 52 +-
tests/Unit/Component/Encoding/Service/GenerateSpeechFromSilenceServiceTest.php | 171 ++---
tests/Unit/Component/FFMpeg/Services/GetSpeechIntervalsTest.php | 36 +-
tests/Unit/Component/LanguageDetection/Services/FindSpeechTimeServiceTest.php | 20 +-
tests/Unit/Component/MobileSettings/MobileSettingsControllerTest.php | 5 +-
tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCreatorTest.php | 75 ++
tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleterTest.php | 63 ++
tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesProviderTest.php | 134 ++++
tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesUploaderTest.php | 57 ++
tests/Unit/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeechesServiceTest.php | 51 +-
tests/Unit/Component/Transcription/Diarization/Source/MeetingBotSourceTest.php | 29 +-
tests/Unit/Contracts/Services/Calendar/CalendarTraitTest.php | 58 +-
tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.php | 159 +++++
tests/Unit/Jobs/Activity/Import/ImportTwilioVideoSpeechesJobTest.php | 22 +-
tests/Unit/Jobs/Activity/Import/IsActivityReadyForProcessingJobTest.php | 26 +-
tests/Unit/Jobs/Calendar/SetupCalendarSyncTest.php | 25 -
tests/Unit/Services/Activity/ParticipantsServiceTest.php | 12 +-
tests/Unit/Services/Activity/Twilio/S3RecordingCredentialsServiceTest.php | 180 +++++
tests/Unit/Services/ActivityServiceTest.php | 132 ++++
tests/Unit/Services/Calendar/CalendarActivityServiceTest.php | 150 +++-
tests/Unit/Services/Calendar/Command/ImportParticipantsTest.php | 6 +-
tests/Unit/Services/Calendar/Command/MapActivityDataTest.php | 78 +-
tests/Unit/Services/Calendar/GoogleCalendarServiceTest.php | 116 +++
tests/Unit/Services/Crm/Close/ServiceTest.php | 165 +++++
tests/Unit/Services/Crm/Hubspot/ServiceTest.php | 272 ++++++-
tests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTest.php | 25 +-
tests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTraitMatchActivitiesTest.php | 3 +-
tests/Unit/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTraitOpportunitiesTest.php | 40 ++
tests/Unit/Services/Crm/Pipedrive/ImportOpportunityMatchActivitiesTest.php | 2 +
tests/Unit/Services/Crm/Salesforce/ServiceTest.php | 139 ++++
tests/Unit/Services/Mail/Office/EmailApiClientTest.php | 195 ++---
tests/Unit/Services/RecallAI/RecallAIServiceTest.php | 24 +-
175 files changed, 12562 insertions(+), 2162 deletions(-)
create mode 120000 CLAUDE.md
create mode 100644 app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.php
delete mode 100644 app/Component/ES/ElasticSearchWorkerManager.php
delete mode 100644 app/Component/ES/Processor/Traits/SkipActivityTrait.php
delete mode 100644 app/Component/ES/Worker/ActivityWorker.php
delete mode 100644 app/Component/ES/Worker/EntityWorker.php
delete mode 100644 app/Component/ES/Worker/WorkerAmount.php
delete mode 100644 app/Component/ES/Worker/WorkerInterface.php
create mode 100644 app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.php
create mode 100644 app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/NoAssemblyIdException.php
create mode 100644 app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNotCorrectFormatException.php
create mode 100644 app/Console/Commands/Activities/SetupIntegration/TwilioSetS3RecordingCredentialsCommand.php
create mode 100644 app/Console/Commands/Crm/BackfillOpportunityUserFromAccountCommand.php
delete mode 100644 app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.php
create mode 100644 app/Console/Commands/IssueMcpTokenCommand.php
create mode 100644 app/Http/Middleware/McpAuditMiddleware.php
create mode 100644 app/Http/Middleware/McpTierMiddleware.php
create mode 100644 app/Mcp/Contracts/McpCallRepositoryInterface.php
create mode 100644 app/Mcp/DTO/ListCallsFilters.php
create mode 100644 app/Mcp/Errors/McpError.php
create mode 100644 app/Mcp/Repositories/McpActivityHydrator.php
create mode 100644 app/Mcp/Repositories/McpCallRepository.php
create mode 100644 app/Mcp/Repositories/McpElasticCallRepository.php
create mode 100644 app/Mcp/Servers/JiminnyServer.php
create mode 100644 app/Mcp/Tools/ListCallsTool.php
create mode 100644 app/Services/Activity/Twilio/S3RecordingCredentialsService.php
create mode 100644 config/mcp.php
create mode 100644 database/migrations/2026_04_30_120000_create_mcp_audit_log_table.php
create mode 100644 docs/mcp/explorer/explorer.html
create mode 100644 docs/mcp/explorer/explorer.template.html
create mode 100644 docs/mcp/explorer/generate.js
create mode 100644 docs/mcp/explorer/tool-explorer-meta.json
create mode 100644 docs/mcp/tools-list.json
create mode 100644 docs/mcp/tools.md
create mode 100644 front-end/src/components/shared/modals/EntityPickerModal/__tests__/useEntitiesCache.spec.ts
create mode 100644 tests/Feature/Component/Nudge/ProcessOrganisationImmediateNudgesJobTest.php
create mode 100644 tests/Feature/Mcp/IssueMcpTokenCommandTest.php
create mode 100644 tests/Feature/Mcp/ListCallsToolElasticFeatureTest.php
create mode 100644 tests/Feature/Mcp/ListCallsToolFeatureTest.php
create mode 100644 tests/Feature/Mcp/McpTestHelpersTrait.php
create mode 100644 tests/Stubs/SentryStub.php
create mode 100644 tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheckerTest.php
delete mode 100644 tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.php
create mode 100644 tests/Unit/Component/ES/Processor/Actions/LoadDocumentsActionTest.php
delete mode 100644 tests/Unit/Component/ES/Processor/Traits/SkipActivityTraitTest.php
delete mode 100644 tests/Unit/Component/ES/Worker/ActivityWorkerTest.php
delete mode 100644 tests/Unit/Component/ES/Worker/EntityWorkerTest.php
delete mode 100644 tests/Unit/Component/ES/Worker/WorkerAmountTest.php
create mode 100644 tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCreatorTest.php
create mode 100644 tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.php
create mode 100644 tests/Unit/Services/Activity/Twilio/S3RecordingCredentialsServiceTest.php
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ git status
On branch master
Your branch is behind 'origin/master' by 114 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: .env.local
modified: app/Component/SCIM/Constants.php
modified: app/Component/SCIM/ScimProvisioning.php
modified: app/Component/Twilio/Conference/ConferenceManager/SoftPhoneManager.php
modified: app/Console/Commands/JiminnyDebugCommand.php
modified: app/DTO/SCIM/AAD/Request/CoreUserRequest.php
modified: app/DTO/SCIM/AAD/Response/CoreUser.php
modified: app/Services/Telephony/TextMessagingService.php
modified: config/logging.php
Untracked files:
(use "git add <file>..." to include in what will be committed)
.env.nikilocal
.env.other
WEBHOOK_FILTERING_IMPLEMENTATION.md
app/Component/SCIM/Mutators/Attributes/User/RoleAttr.php
app/Console/Commands/Crm/Hubspot/SimulateWebhooksCommand.php
app/Console/Commands/Reports/CreateMockAskJiminnyReportResultCommand.php
app/Rules/ListenerRoleCannotHaveAdminOrManagerPermissionRule.php
ids.txt
public/favicon.ico
raw_sql_query.sql
tests/Unit/Component/SCIM/Mutators/Attributes/User/RoleAttrTest.php
tests/Unit/Policies/CanAccessAiReportsTest.php
tests/Unit/Rules/ListenerRoleCannotHaveAdminOrManagerPermissionRuleTest.php
no changes added to commit (use "git add" and/or "git commit -a")
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull
remote: Enumerating objects: 306, done.
remote: Counting objects: 100% (299/299), done.
remote: Compressing objects: 100% (183/183), done.
remote: Total 306 (delta 213), reused 171 (delta 116), pack-reused 7 (from 1)
Receiving objects: 100% (306/306), 80.12 KiB | 1000.00 KiB/s, done.
Resolving deltas: 100% (213/213), completed with 53 local objects.
From github.com:jiminny/app
90bca4e4b2..5604af40cf master -> origin/master
4e7078fd8b..0b8343d179 JY-18091-upgrade-to-php-8-5 -> origin/JY-18091-upgrade-to-php-8-5
098eeaa087..d5a447e492 JY-20613-allow-owner-role-on-team-setup -> origin/JY-20613-allow-owner-role-on-team-setup
c3a76ace91..af65249d0f JY-20749-user-can-view-recorded-meetings -> origin/JY-20749-user-can-view-recorded-meetings
d94a285ae7..7ce96cb5fe JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue
* [new branch] JY-20842-remove-partial-updater -> origin/JY-20842-remove-partial-updater
* [new branch] JY-20920-fix-participant-flip -> origin/JY-20920-fix-participant-flip
* [new branch] secfix/npm-20260519 -> origin/secfix/npm-20260519
Updating cb4ebf0c36..5604af40cf
Fast-forward
app/Component/ES/ChunkSize.php | 54 +++++++++++++++++++
app/Component/ES/Processor/DTOs/SelectionList.php | 4 +-
app/Component/ES/Processor/TargetEntitiesSelector.php | 19 ++++---
app/Component/MeetingBot/Service/ParticipantMatcher.php | 46 ++++++++++++----
app/Exceptions/RateLimitException.php | 19 ++++++-
app/Http/Middleware/McpTierMiddleware.php | 27 ++--------
app/Jobs/Crm/MatchActivityCrmData.php | 47 ++++++++++++----
app/Jobs/Middleware/HandleHubspotRateLimit.php | 42 +++++++++++++++
app/Mcp/Servers/JiminnyServer.php | 2 +
app/Mcp/Tools/GetMeTool.php | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++
app/Models/Feature/FeatureEnum.php | 1 +
app/Services/Activity/HubSpot/ProviderResolver.php | 4 +-
app/Services/Activity/HubSpot/ProviderResolverInterface.php | 2 +-
app/Services/Activity/HubSpot/Providers/Provider.php | 2 +-
app/Services/Activity/HubSpot/Providers/ProviderKixie.php | 2 +-
app/Services/Activity/HubSpot/Providers/ProviderOrum.php | 2 +-
app/Services/Activity/HubSpot/Providers/ProviderTwilio.php | 2 +-
app/Services/Activity/HubSpot/Providers/ProviderTwilioFlex.php | 5 +-
app/Services/Activity/HubSpot/Service.php | 97 +++++++++++++++++++++++++++------
app/Services/Crm/Hubspot/Client.php | 132 +++++++++++++++++++++++++++++++++++++++++++++
app/Services/Crm/Hubspot/HubspotClientInterface.php | 15 ++++++
app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php | 21 ++++----
app/Services/Crm/Hubspot/Pagination/PaginationState.php | 2 +-
database/migrations/2026_05_13_124153_create_mcp_feature_flag.php | 25 +++++++++
tests/Feature/Mcp/GetMeToolFeatureTest.php | 140 +++++++++++++++++++++++++++++++++++++++++++++++
tests/Feature/Mcp/ListCallsToolFeatureTest.php | 2 +-
tests/Feature/Mcp/McpTestHelpersTrait.php | 19 ++++++-
tests/Unit/Component/ES/ChunkSizeTest.php | 50 +++++++++++++++++
tests/Unit/Component/ES/Processor/DTOs/SelectionListTest.php | 27 +++++++---
tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 39 ++++++++------
tests/Unit/Component/MeetingBot/Service/ParticipantMatcherTest.php | 68 ++++++++++++++++++++++-
tests/Unit/Exceptions/RateLimitExceptionTest.php | 56 +++++++++++++++++++
tests/Unit/Jobs/Crm/MatchActivityCrmDataTest.php | 8 +--
tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++
tests/Unit/Services/Activity/HubSpot/ServiceTest.php | 109 +++++++++++++++++++++++++++++++++++++
tests/Unit/Services/Crm/Hubspot/ClientTest.php | 250 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/Unit/Services/Crm/Hubspot/Pagination/HubspotPaginationServiceTest.php | 283 +++++++++++++++++++++---------------------------------------------------------------------------
37 files changed, 1587 insertions(+), 344 deletions(-)
create mode 100644 app/Component/ES/ChunkSize.php
create mode 100644 app/Jobs/Middleware/HandleHubspotRateLimit.php
create mode 100644 app/Mcp/Tools/GetMeTool.php
create mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.php
create mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.php
create mode 100644 tests/Unit/Component/ES/ChunkSizeTest.php
create mode 100644 tests/Unit/Exceptions/RateLimitExceptionTest.php
create mode 100644 tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull
Already up to date.
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20676-delete-report-related-objects
Switched to a new branch 'JY-20676-delete-report-related-objects'
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20676-delete-report-related-objects) $ csfix
docker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff
PHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.
PHP runtime: 8.3.30
Running analysis on 7 cores with 10 files per process.
Parallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!
Loaded config default from ".php-cs-fixer.dist.php".
5690/5690 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
1) app/Console/Commands/JiminnyDebugCommand.php (statement_indentation, blank_line_before_statement)
---------- begin diff ----------
--- /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php
+++ /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php
@@ -23,6 +23,7 @@
if ($action === 'redis-set') {
$this->testRedisSet();
+
return;
}
@@ -45,7 +46,7 @@
$ttl = 60;
try {
-// $result = Redis::set($testKey, $testValue, 'EX', $ttl, 'NX');
+ // $result = Redis::set($testKey, $testValue, 'EX', $ttl, 'NX');
$result = Redis::set($testKey, $testValue, ['nx', 'ex' => $ttl]);
if ($result) {
----------- end diff -----------
Fixed 1 of 5690 files i...
|
[{"role":"AXTextArea","text [{"role":"AXTextArea","text":"Last login: Mon May 18 09:17:28 on ttys007\n\nPoetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parents\n\nPoetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parents\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ co master\nerror: Your local changes to the following files would be overwritten by checkout:\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tPIPEDRIVE_V2_MIGRATION_TICKETS.md\nPlease commit your changes or stash them before you switch branches.\nAborting\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ git pull\nremote: Enumerating objects: 1047, done.\nremote: Counting objects: 100% (832/832), done.\nremote: Compressing objects: 100% (298/298), done.\nremote: Total 1047 (delta 634), reused 596 (delta 534), pack-reused 215 (from 3)\nReceiving objects: 100% (1047/1047), 353.16 KiB | 1.56 MiB/s, done.\nResolving deltas: 100% (687/687), completed with 107 local objects.\nFrom github.com:jiminny/app\n 907c54896c..34656c53ed pipedrive-sdk-poc -> origin/pipedrive-sdk-poc\n 03325ec50f..4e7078fd8b JY-18091-upgrade-to-php-8-5 -> origin/JY-18091-upgrade-to-php-8-5\n e7d231e163..bc6a3fce6b JY-20725-handle-HS-search-rate-limit -> origin/JY-20725-handle-HS-search-rate-limit\n * [new branch] JY-20749-user-can-view-recorded-meetings -> origin/JY-20749-user-can-view-recorded-meetings\n 98ca281a04..e0351be069 JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue\n 569abb5149..3906a9238a JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details -> origin/JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details\n ad6c2a86e8..50eb6afba9 JY-20846-mcp-enable-the-ai-to-know-details-about-the-user -> origin/JY-20846-mcp-enable-the-ai-to-know-details-about-the-user\n * [new branch] JY-20893-chunk-control-per-update-target -> origin/JY-20893-chunk-control-per-update-target\n 31c62924a5..cb4ebf0c36 master -> origin/master\nUpdating 907c54896c..34656c53ed\nFast-forward\n PIPEDRIVE_V2_MIGRATION_TICKETS.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 52 insertions(+)\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ co master\nM\u0000\u0000\u0000\u0000\u0000\u0000\t.env.local\nM\u0000\u0000\u0000\u0000\u0000\u0000\tconfig/logging.php\nSwitched to branch 'master'\nYour branch is behind 'origin/master' by 31 commits, and can be fast-forwarded.\n (use \"git pull\" to update your local branch)\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull\nUpdating 31c62924a5..cb4ebf0c36\nFast-forward\n app/Component/ES/Processor/Traits/SelectEntityListTrait.php | 20 ------\n app/Services/Calendar/CalendarActivityService.php | 46 +++++++++++++\n app/Services/Calendar/Command/MapActivityData.php | 106 +++-------------------------\n docs/mcp/explorer/explorer.html | 104 +++++++++++++++++++++++++---\n docs/mcp/explorer/explorer.template.html | 102 ++++++++++++++++++++++++---\n docs/mcp/tools-list.json | 373 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------\n docs/mcp/tools.md | 117 +++++++++++++++++++++++--------\n tests/Unit/Component/ES/AsyncUpdateElasticSearchTest.php | 16 +----\n tests/Unit/Component/ES/Listeners/UpdateMultipleTargetsListenerTest.php | 10 ---\n tests/Unit/Component/ES/Listeners/UpdateSingleTargetListenerTest.php | 6 --\n tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 9 ---\n tests/Unit/Component/ES/Processor/Traits/SelectEntityListTraitTest.php | 15 ++--\n tests/Unit/Component/ES/UpdateProcessManagerTest.php | 2 -\n tests/Unit/Services/Calendar/CalendarActivityServiceTest.php | 150 ++++++++++++++++++++++++++++++++++++++--\n tests/Unit/Services/Calendar/Command/MapActivityDataTest.php | 78 ++-------------------\n 15 files changed, 832 insertions(+), 322 deletions(-)\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20613-allow-owner-role-on-team-setup\nSwitched to a new branch 'JY-20613-allow-owner-role-on-team-setup'\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ csfix\ndocker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff \nPHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.\nPHP runtime: 8.3.30\nRunning analysis on 7 cores with 10 files per process.\nParallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!\nLoaded config default from \".php-cs-fixer.dist.php\".\n 5682/5682 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%\n\n\nFixed 0 of 5682 files in 56.978 seconds, 67.00 MB memory used\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ ;xd\ndocker exec -it docker_lamp_1 bash -c \"mv /usr/local/etc/php/conf.d/xdebug.ini ~/xdebug.ini\"\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\ndocker exec -it docker_lamp_1 supervisorctl restart all\njiminny-worker-processing-2:jiminny-worker-processing-2_00: stopped\njiminny-worker-processing-3:jiminny-worker-processing-3_00: stopped\njiminny-worker-processing-4:jiminny-worker-processing-4_00: stopped\njiminny-worker-processing-5:jiminny-worker-processing-5_00: stopped\njiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00: stopped\nworker-analytics:worker-analytics_00: stopped\nworker-crm-update:worker-crm-update_00: stopped\nworker-download:worker-download_00: stopped\nworker-nudges:worker-nudges_00: stopped\nartisan-schedule:artisan-schedule_00: stopped\nworker-emails:worker-emails_00: stopped\nworker-calendar:worker-calendar_00: stopped\nworker:worker_00: stopped\nworker-conferences:worker-conferences_00: stopped\nworker-crm-sync:worker-crm-sync_00: stopped\njiminny-worker-processing-1:jiminny-worker-processing-1_00: stopped\nworker-audio:worker-audio_00: stopped\nworker-es-update:worker-es-update_00: stopped\nartisan-schedule:artisan-schedule_00: started\njiminny-worker-processing-1:jiminny-worker-processing-1_00: started\njiminny-worker-processing-2:jiminny-worker-processing-2_00: started\njiminny-worker-processing-3:jiminny-worker-processing-3_00: started\njiminny-worker-processing-4:jiminny-worker-processing-4_00: started\njiminny-worker-processing-5:jiminny-worker-processing-5_00: started\njiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00: started\nworker:worker_00: started\nworker-analytics:worker-analytics_00: started\nworker-audio:worker-audio_00: started\nworker-calendar:worker-calendar_00: started\nworker-conferences:worker-conferences_00: started\nworker-crm-sync:worker-crm-sync_00: started\nworker-crm-update:worker-crm-update_00: started\nworker-download:worker-download_00: started\nworker-emails:worker-emails_00: started\nworker-es-update:worker-es-update_00: started\nworker-nudges:worker-nudges_00: started\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\ndocker exec -it docker_lamp_1 php -v\nPHP 8.3.30 (cli) (built: Mar 16 2026 22:32:32) (NTS)\nCopyright (c) The PHP Group\nZend Engine v4.3.30, Copyright (c) Zend Technologies\n with Zend OPcache v8.3.30, Copyright (c), by Zend Technologies\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ csfix\ndocker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff \nPHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.\nPHP runtime: 8.3.30\nRunning analysis on 7 cores with 10 files per process.\nParallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!\nLoaded config default from \".php-cs-fixer.dist.php\".\n 5682/5682 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%\n\n\nFixed 0 of 5682 files in 49.910 seconds, 60.00 MB memory used\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git status\nOn branch JY-20613-allow-owner-role-on-team-setup\nYour branch is ahead of 'origin/JY-20613-allow-owner-role-on-team-setup' by 1 commit.\n (use \"git push\" to publish your local commits)\n\nChanges not staged for commit:\n (use \"git add <file>...\" to update what will be committed)\n (use \"git restore <file>...\" to discard changes in working directory)\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: .env.local\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: config/logging.php\n\nUntracked files:\n (use \"git add <file>...\" to include in what will be committed)\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\t.env.nikilocal\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\t.env.other\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tWEBHOOK_FILTERING_IMPLEMENTATION.md\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Console/Commands/Crm/Hubspot/SimulateWebhooksCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Console/Commands/Reports/CreateMockAskJiminnyReportResultCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tids.txt\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tpublic/favicon.ico\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\traw_sql_query.sql\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ttests/Unit/Policies/CanAccessAiReportsTest.php\n\nno changes added to commit (use \"git add\" and/or \"git commit -a\")\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git pull\nremote: Enumerating objects: 248, done.\nremote: Counting objects: 100% (128/128), done.\nremote: Compressing objects: 100% (23/23), done.\nremote: Total 59 (delta 43), reused 44 (delta 33), pack-reused 0 (from 0)\nUnpacking objects: 100% (59/59), 10.48 KiB | 228.00 KiB/s, done.\nFrom github.com:jiminny/app\n b7df560451..190239dfd4 JY-20613-allow-owner-role-on-team-setup -> origin/JY-20613-allow-owner-role-on-team-setup\n e0351be069..d94a285ae7 JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue\n * [new branch] JY-20920-fix-participant-matcher -> origin/JY-20920-fix-participant-matcher\n cb4ebf0c36..90bca4e4b2 master -> origin/master\nMerge made by the 'ort' strategy.\n app/Component/ES/ChunkSize.php | 54 +++++++++++++++++++++++++++\n app/Component/ES/Processor/DTOs/SelectionList.php | 4 +-\n app/Component/ES/Processor/TargetEntitiesSelector.php | 19 ++++++----\n app/Http/Middleware/McpTierMiddleware.php | 27 +++-----------\n app/Mcp/Servers/JiminnyServer.php | 2 +\n app/Mcp/Tools/GetMeTool.php | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n app/Models/Feature/FeatureEnum.php | 1 +\n database/migrations/2026_05_13_124153_create_mcp_feature_flag.php | 25 +++++++++++++\n front-end/src/components/Settings/Kiosk/modals/EditTeamModal/EditTeamModal.vue | 52 ++++++++++++++++++--------\n front-end/src/components/Settings/Kiosk/modals/EditTeamModal/__tests__/EditTeamModal.spec.js | 14 +++++++\n tests/Feature/Mcp/GetMeToolFeatureTest.php | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n tests/Feature/Mcp/ListCallsToolFeatureTest.php | 2 +-\n tests/Feature/Mcp/McpTestHelpersTrait.php | 19 +++++++++-\n tests/Unit/Component/ES/ChunkSizeTest.php | 50 +++++++++++++++++++++++++\n tests/Unit/Component/ES/Processor/DTOs/SelectionListTest.php | 27 ++++++++++----\n tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 39 +++++++++++---------\n 16 files changed, 557 insertions(+), 75 deletions(-)\n create mode 100644 app/Component/ES/ChunkSize.php\n create mode 100644 app/Mcp/Tools/GetMeTool.php\n create mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.php\n create mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.php\n create mode 100644 tests/Unit/Component/ES/ChunkSizeTest.php\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git push\nEnumerating objects: 40, done.\nCounting objects: 100% (34/34), done.\nDelta compression using up to 8 threads\nCompressing objects: 100% (18/18), done.\nWriting objects: 100% (18/18), 1.58 KiB | 1.58 MiB/s, done.\nTotal 18 (delta 15), reused 0 (delta 0), pack-reused 0\nremote: Resolving deltas: 100% (15/15), completed with 13 local objects.\nTo github.com:jiminny/app.git\n 190239dfd4..ec1b261264 JY-20613-allow-owner-role-on-team-setup -> JY-20613-allow-owner-role-on-team-setup\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ gbr\n* JY-20613-allow-owner-role-on-team-setup\n pipedrive-sdk-poc\n master\n JY-20903-update_activity-stage-on-opportunity-change\n JY-20904-fix-update-es-on-activity-command\n JY-20891-improve-sms-text-relays\n JY-20725-handle-HS-search-rate-limit\n JY-20818-move-AJ-reports-to-separated-datadog-metric\n JY-20773-fix-automated-reports-user-pilot-tracking\n JY-20157-AJ-report-not-send-notification\n JY-20508-notify-before-AJ-report-expiration\n JY-20372-ai-reports-promotion-pages\n JY-20352-sync-opportunities-without-a-local-owner-user-id-is-null\n JY-20738-debug-AJ-tracking-UP\n a\n JY-18909-automated-reports-ask-jiminny\n JY-20692-fix-integration-app-token-auth-response-change\n JY-20553-debug-crm-sync-delays\n JY-20698-fix-SF-activity-types-on-new-playbook\n JY-20543-AJ-report-tracking\n JY-20384-handle-auto-sync-with-no-access-to-event-type\n JY-20458-ask-jiminny-user-definitions\n JY-19666-fix-import-contacts-account-association\n JY-19666-HS-import-contacts-and-accounts-batch-job\n JY-20458-Ask-Jiminny-Reports\n JY-20200-batch-update-CRM-objects-Salesforce\n JY-19666-HS-webhooks-add-contact-and-company\n JY-20348-trigger-setup-DI-layout-on-team-creation\n JY-20326-refactor-info-message-in-command\n JY-20317-fix-auto-log-delay-issue-on-all-channels-disabled\n JY-20312-remove-on-update-change-last-synced-at-crm-configurations\n JY-20306-SF-skip-auto-sync-for-task-based-playbook\n JY-20192-remove-deleted-team-from-saved-search-filters\n JY-20197-import-opportunity-batch-job\n JY-20293-enable-status-field-for-pipedrive-deals\n JY-20191-remove-commands-interactive-prompts\n JY-20118-change-default-sync-strategy\n JY-20183-add-cache-on-auto-log-delay\n JY-20197-add-import-opportunity-batch-job\n 20118-hs-opportunity-make-webhook-strategy-default\n JY-20118-make-default-hs-opportunity-sync-strategy-webhook-based\n JY-20196-handle-opportunity-without-note\n JY-20118-improve-opportunity-import\n JY-20189-handle-activity-search-on-deleted-groups\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ co JY-20725-handle-HS-search-rate-limit\nM\u0000\u0000\u0000\u0000\u0000\u0000\t.env.local\nM\u0000\u0000\u0000\u0000\u0000\u0000\tconfig/logging.php\nSwitched to branch 'JY-20725-handle-HS-search-rate-limit'\nYour branch is behind 'origin/JY-20725-handle-HS-search-rate-limit' by 439 commits, and can be fast-forwarded.\n (use \"git pull\" to update your local branch)\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ git pull\nUpdating 0f3e438941..bc6a3fce6b\nFast-forward\n .gitignore | 3 +-\n .windsurfrules | 168 ++---\n CLAUDE.md | 1 +\n app/Component/ActivityAnalytics/Service/CalculateTalkTimeOffsetsFromTranscription.php | 24 +-\n app/Component/AiActivityType/Services/AiActivityTypeEligibilityChecker.php | 28 +-\n app/Component/AiAutomation/Actions/PrepareUpdateDtoAction.php | 32 +-\n app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.php | 47 ++\n app/Component/AiAutomation/TestCrmAiPromptService.php | 14 +\n app/Component/AiCallScoring/Services/AiCallScoringEligibilityChecker.php | 9 +\n app/Component/ES/ElasticSearchDocumentPartialUpdater.php | 13 +-\n app/Component/ES/ElasticSearchWorkerManager.php | 86 ---\n app/Component/ES/Processor/Actions/LoadDocumentsAction.php | 80 +--\n app/Component/ES/Processor/EntityQueryBuilder.php | 12 +-\n app/Component/ES/Processor/TargetEntitiesSelector.php | 2 +-\n app/Component/ES/Processor/Traits/SkipActivityTrait.php | 25 -\n app/Component/ES/Repositories/EsResetActivityRepository.php | 11 +-\n app/Component/ES/Worker/ActivityWorker.php | 73 --\n app/Component/ES/Worker/EntityWorker.php | 44 --\n app/Component/ES/Worker/WorkerAmount.php | 60 --\n app/Component/ES/Worker/WorkerInterface.php | 15 -\n app/Component/ElasticSearch/Contract/Searchable.php | 4 +\n app/Component/Encoding/Job/AnalyzeTrackChannelsJob.php | 20 +-\n app/Component/Encoding/Service/GenerateSpeechFromSilenceService.php | 85 ++-\n app/Component/FFMpeg/Services/GetSpeechIntervalsService.php | 18 +-\n app/Component/LanguageDetection/Services/FindSpeechTimeService.php | 22 +-\n app/Component/Nudge/Job/ProcessOrganisationImmediateNudgesJob.php | 218 +++++-\n app/Component/ParagraphBreaker/Services/TranscriptionParagraphsService.php | 4 +\n app/Component/ParticipantSpeech/Services/ParticipantSpeechesCreator.php | 33 +\n app/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleter.php | 15 +\n app/Component/ParticipantSpeech/Services/ParticipantSpeechesProvider.php | 51 +-\n app/Component/ParticipantSpeech/Services/ParticipantSpeechesUploader.php | 36 +\n app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.php | 11 +\n app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/NoAssemblyIdException.php | 11 +\n app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/SuccessfulResponse.php | 6 +\n app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNotCorrectFormatException.php | 11 +\n app/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeechesService.php | 23 +-\n app/Component/Transcription/Diarization/Source/MeetingBotSource.php | 16 +-\n app/Component/Transcription/TranscriptionProcessor/TranscriptionProcessor.php | 3 +\n app/Console/Commands/Activities/ActivityHardDeleteCommand.php | 4 +-\n app/Console/Commands/Activities/Copy.php | 2 +\n app/Console/Commands/Activities/SetupIntegration/TwilioSetS3RecordingCredentialsCommand.php | 119 ++++\n app/Console/Commands/Activities/UpdateActivityElasticSearchDocumentCommand.php | 10 +-\n app/Console/Commands/Crm/BackfillOpportunityUserFromAccountCommand.php | 126 ++++\n app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.php | 19 -\n app/Console/Commands/Elasticsearch/AsyncUpdateEsEntities.php | 50 +-\n app/Console/Commands/Elasticsearch/ResetAsyncElasticSearchCommand.php | 30 +-\n app/Console/Commands/GeckoExport/GeckoExportParticipantSpeechesCommand.php | 14 +-\n app/Console/Commands/IssueMcpTokenCommand.php | 84 +++\n app/Console/Commands/JiminnyDebugCommand.php | 7 +-\n app/Console/Commands/Tracks/CleanupActivityTracksCommand.php | 2 +-\n app/Console/Kernel.php | 6 +-\n app/Contracts/Services/Calendar/CalendarTrait.php | 80 ++-\n app/Events/AutomatedReports/AutomatedReportGenerated.php | 3 +\n app/Http/Controllers/API/AiCallScoring/AiScorecardController.php | 7 +-\n app/Http/Controllers/API/TeamAiAutomationController.php | 8 +\n app/Http/Controllers/CustomerApi/CustomerApiController.php | 4 +-\n app/Http/Controllers/Kiosk/ActivityController.php | 58 +-\n app/Http/Controllers/Settings/PlaybookController.php | 15 +-\n app/Http/Kernel.php | 23 +\n app/Http/Middleware/McpAuditMiddleware.php | 156 ++++\n app/Http/Middleware/McpTierMiddleware.php | 54 ++\n app/Http/Requests/API/V2/ZapierUploadActivityRequest.php | 28 +-\n app/Jobs/Activity/Import/ImportTwilioVideoSpeechesJob.php | 25 +-\n app/Jobs/Activity/Import/IsActivityReadyForProcessingJob.php | 10 +-\n app/Jobs/Calendar/SetupCalendarSync.php | 21 +-\n app/Jobs/ImportRemoteTrackJob.php | 96 ++-\n app/Jobs/Mailbox/EmailTextRelay.php | 15 +-\n app/Mcp/Contracts/McpCallRepositoryInterface.php | 30 +\n app/Mcp/DTO/ListCallsFilters.php | 29 +\n app/Mcp/Errors/McpError.php | 123 ++++\n app/Mcp/Repositories/McpActivityHydrator.php | 145 ++++\n app/Mcp/Repositories/McpCallRepository.php | 84 +++\n app/Mcp/Repositories/McpElasticCallRepository.php | 171 +++++\n app/Mcp/Servers/JiminnyServer.php | 38 +\n app/Mcp/Tools/ListCallsTool.php | 205 ++++++\n app/Models/Activity.php | 10 +-\n app/Models/Activity/Transcription.php | 17 +-\n app/Models/ElasticSearch/OpportunityElasticSearchTrait.php | 5 +\n app/Models/Participant.php | 1 +\n app/Providers/AppServiceProvider.php | 22 +\n app/Repositories/Crm/ContactRepository.php | 69 +-\n app/Repositories/ParticipantSpeechRepository.php | 13 +-\n app/Services/Activity/ParticipantsService.php | 19 +-\n app/Services/Activity/Twilio/S3RecordingCredentialsService.php | 82 +++\n app/Services/ActivityService.php | 21 +-\n app/Services/Calendar/CalendarActivityService.php | 46 ++\n app/Services/Calendar/Command/ImportParticipants.php | 1 +\n app/Services/Calendar/Command/MapActivityData.php | 106 +--\n app/Services/Calendar/GoogleCalendarService.php | 12 +-\n app/Services/Crm/Close/Processor/OpportunityProcessor.php | 2 +-\n app/Services/Crm/Close/Service.php | 22 +-\n app/Services/Crm/Copper/Service.php | 12 +-\n app/Services/Crm/Hubspot/Service.php | 154 +++-\n app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php | 88 ++-\n app/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTrait.php | 22 +-\n app/Services/Crm/Pipedrive/Service.php | 17 +-\n app/Services/Crm/Salesforce/Service.php | 42 +-\n app/Services/Mail/Office/EmailApiClient.php | 129 +---\n app/Services/RecallAI/Commands/ScheduleBotCommand.php | 39 +-\n app/Services/RecallAI/RecallAIService.php | 22 +-\n composer.json | 3 +-\n composer.lock | 87 ++-\n config/mcp.php | 23 +\n database/migrations/2026_04_30_120000_create_mcp_audit_log_table.php | 36 +\n docs/mcp/explorer/explorer.html | 697 ++++++++++++++++++\n docs/mcp/explorer/explorer.template.html | 697 ++++++++++++++++++\n docs/mcp/explorer/generate.js | 215 ++++++\n docs/mcp/explorer/tool-explorer-meta.json | 11 +\n docs/mcp/tools-list.json | 2536 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n docs/mcp/tools.md | 621 ++++++++++++++++\n front-end/package.json | 4 +-\n front-end/src/components/Settings/OrgSettings/AiAutomation/CrmFilling/TemplateFieldForm.vue | 28 +-\n front-end/src/components/Settings/OrgSettings/Playbooks/AddEditPlaybook.vue | 10 +\n front-end/src/components/playback/comments/ActivityComment.less | 10 +-\n front-end/src/components/shared/PromptTester/PromptTester.vue | 12 +-\n front-end/src/components/shared/__tests__/PromptTester.spec.js | 35 +\n front-end/src/components/shared/modals/EntityPickerModal/__tests__/useEntitiesCache.spec.ts | 37 +\n front-end/src/components/shared/modals/EntityPickerModal/useEntitiesCache.ts | 9 +\n front-end/yarn.lock | 16 +-\n phpstan-baseline.neon | 50 --\n routes/api.php | 11 +\n sonar-project.properties | 91 ++-\n tests/Feature/Component/Nudge/ProcessOrganisationImmediateNudgesJobTest.php | 534 ++++++++++++++\n tests/Feature/Jobs/ImportRemoteTrackJobTest.php | 283 +++++++-\n tests/Feature/Mcp/IssueMcpTokenCommandTest.php | 53 ++\n tests/Feature/Mcp/ListCallsToolElasticFeatureTest.php | 155 ++++\n tests/Feature/Mcp/ListCallsToolFeatureTest.php | 352 ++++++++++\n tests/Feature/Mcp/McpTestHelpersTrait.php | 77 ++\n tests/Feature/Services/Team/TeamDeleteHandlers/Retention/RetentionRepositoryHandlerTest.php | 1 +\n tests/Stubs/SentryStub.php | 18 +\n tests/Unit/Component/ActivityAnalytics/Service/CalculateTalkTimeOffsetFromTranscriptionTest.php | 28 +-\n tests/Unit/Component/AiActivityType/Services/AiActivityTypeEligibilityCheckerTest.php | 103 ++-\n tests/Unit/Component/AiAutomation/Actions/PrepareUpdateDtoActionTest.php | 91 +++\n tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheckerTest.php | 124 ++++\n tests/Unit/Component/AiAutomation/TestCrmAiPromptServiceTest.php | 67 +-\n tests/Unit/Component/AiCallScoring/Services/AiCallScoringEligibilityCheckerTest.php | 55 ++\n tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.php | 135 ----\n tests/Unit/Component/ES/Processor/Actions/LoadDocumentsActionTest.php | 220 ++++++\n tests/Unit/Component/ES/Processor/EntityQueryBuilderTest.php | 21 +-\n tests/Unit/Component/ES/Processor/Traits/SkipActivityTraitTest.php | 51 --\n tests/Unit/Component/ES/Worker/ActivityWorkerTest.php | 174 -----\n tests/Unit/Component/ES/Worker/EntityWorkerTest.php | 97 ---\n tests/Unit/Component/ES/Worker/WorkerAmountTest.php | 116 ---\n tests/Unit/Component/Encoding/Job/AnalyzeTrackChannelsJobTest.php | 52 +-\n tests/Unit/Component/Encoding/Service/GenerateSpeechFromSilenceServiceTest.php | 171 ++---\n tests/Unit/Component/FFMpeg/Services/GetSpeechIntervalsTest.php | 36 +-\n tests/Unit/Component/LanguageDetection/Services/FindSpeechTimeServiceTest.php | 20 +-\n tests/Unit/Component/MobileSettings/MobileSettingsControllerTest.php | 5 +-\n tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCreatorTest.php | 75 ++\n tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleterTest.php | 63 ++\n tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesProviderTest.php | 134 ++++\n tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesUploaderTest.php | 57 ++\n tests/Unit/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeechesServiceTest.php | 51 +-\n tests/Unit/Component/Transcription/Diarization/Source/MeetingBotSourceTest.php | 29 +-\n tests/Unit/Contracts/Services/Calendar/CalendarTraitTest.php | 58 +-\n tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.php | 159 +++++\n tests/Unit/Jobs/Activity/Import/ImportTwilioVideoSpeechesJobTest.php | 22 +-\n tests/Unit/Jobs/Activity/Import/IsActivityReadyForProcessingJobTest.php | 26 +-\n tests/Unit/Jobs/Calendar/SetupCalendarSyncTest.php | 25 -\n tests/Unit/Services/Activity/ParticipantsServiceTest.php | 12 +-\n tests/Unit/Services/Activity/Twilio/S3RecordingCredentialsServiceTest.php | 180 +++++\n tests/Unit/Services/ActivityServiceTest.php | 132 ++++\n tests/Unit/Services/Calendar/CalendarActivityServiceTest.php | 150 +++-\n tests/Unit/Services/Calendar/Command/ImportParticipantsTest.php | 6 +-\n tests/Unit/Services/Calendar/Command/MapActivityDataTest.php | 78 +-\n tests/Unit/Services/Calendar/GoogleCalendarServiceTest.php | 116 +++\n tests/Unit/Services/Crm/Close/ServiceTest.php | 165 +++++\n tests/Unit/Services/Crm/Hubspot/ServiceTest.php | 272 ++++++-\n tests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTest.php | 25 +-\n tests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTraitMatchActivitiesTest.php | 3 +-\n tests/Unit/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTraitOpportunitiesTest.php | 40 ++\n tests/Unit/Services/Crm/Pipedrive/ImportOpportunityMatchActivitiesTest.php | 2 +\n tests/Unit/Services/Crm/Salesforce/ServiceTest.php | 139 ++++\n tests/Unit/Services/Mail/Office/EmailApiClientTest.php | 195 ++---\n tests/Unit/Services/RecallAI/RecallAIServiceTest.php | 24 +-\n 175 files changed, 12562 insertions(+), 2162 deletions(-)\n create mode 120000 CLAUDE.md\n create mode 100644 app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.php\n delete mode 100644 app/Component/ES/ElasticSearchWorkerManager.php\n delete mode 100644 app/Component/ES/Processor/Traits/SkipActivityTrait.php\n delete mode 100644 app/Component/ES/Worker/ActivityWorker.php\n delete mode 100644 app/Component/ES/Worker/EntityWorker.php\n delete mode 100644 app/Component/ES/Worker/WorkerAmount.php\n delete mode 100644 app/Component/ES/Worker/WorkerInterface.php\n create mode 100644 app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.php\n create mode 100644 app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/NoAssemblyIdException.php\n create mode 100644 app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNotCorrectFormatException.php\n create mode 100644 app/Console/Commands/Activities/SetupIntegration/TwilioSetS3RecordingCredentialsCommand.php\n create mode 100644 app/Console/Commands/Crm/BackfillOpportunityUserFromAccountCommand.php\n delete mode 100644 app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.php\n create mode 100644 app/Console/Commands/IssueMcpTokenCommand.php\n create mode 100644 app/Http/Middleware/McpAuditMiddleware.php\n create mode 100644 app/Http/Middleware/McpTierMiddleware.php\n create mode 100644 app/Mcp/Contracts/McpCallRepositoryInterface.php\n create mode 100644 app/Mcp/DTO/ListCallsFilters.php\n create mode 100644 app/Mcp/Errors/McpError.php\n create mode 100644 app/Mcp/Repositories/McpActivityHydrator.php\n create mode 100644 app/Mcp/Repositories/McpCallRepository.php\n create mode 100644 app/Mcp/Repositories/McpElasticCallRepository.php\n create mode 100644 app/Mcp/Servers/JiminnyServer.php\n create mode 100644 app/Mcp/Tools/ListCallsTool.php\n create mode 100644 app/Services/Activity/Twilio/S3RecordingCredentialsService.php\n create mode 100644 config/mcp.php\n create mode 100644 database/migrations/2026_04_30_120000_create_mcp_audit_log_table.php\n create mode 100644 docs/mcp/explorer/explorer.html\n create mode 100644 docs/mcp/explorer/explorer.template.html\n create mode 100644 docs/mcp/explorer/generate.js\n create mode 100644 docs/mcp/explorer/tool-explorer-meta.json\n create mode 100644 docs/mcp/tools-list.json\n create mode 100644 docs/mcp/tools.md\n create mode 100644 front-end/src/components/shared/modals/EntityPickerModal/__tests__/useEntitiesCache.spec.ts\n create mode 100644 tests/Feature/Component/Nudge/ProcessOrganisationImmediateNudgesJobTest.php\n create mode 100644 tests/Feature/Mcp/IssueMcpTokenCommandTest.php\n create mode 100644 tests/Feature/Mcp/ListCallsToolElasticFeatureTest.php\n create mode 100644 tests/Feature/Mcp/ListCallsToolFeatureTest.php\n create mode 100644 tests/Feature/Mcp/McpTestHelpersTrait.php\n create mode 100644 tests/Stubs/SentryStub.php\n create mode 100644 tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheckerTest.php\n delete mode 100644 tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.php\n create mode 100644 tests/Unit/Component/ES/Processor/Actions/LoadDocumentsActionTest.php\n delete mode 100644 tests/Unit/Component/ES/Processor/Traits/SkipActivityTraitTest.php\n delete mode 100644 tests/Unit/Component/ES/Worker/ActivityWorkerTest.php\n delete mode 100644 tests/Unit/Component/ES/Worker/EntityWorkerTest.php\n delete mode 100644 tests/Unit/Component/ES/Worker/WorkerAmountTest.php\n create mode 100644 tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCreatorTest.php\n create mode 100644 tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.php\n create mode 100644 tests/Unit/Services/Activity/Twilio/S3RecordingCredentialsServiceTest.php\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ git status\nOn branch master\nYour branch is behind 'origin/master' by 114 commits, and can be fast-forwarded.\n (use \"git pull\" to update your local branch)\n\nChanges not staged for commit:\n (use \"git add <file>...\" to update what will be committed)\n (use \"git restore <file>...\" to discard changes in working directory)\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: .env.local\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Component/SCIM/Constants.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Component/SCIM/ScimProvisioning.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Component/Twilio/Conference/ConferenceManager/SoftPhoneManager.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Console/Commands/JiminnyDebugCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/DTO/SCIM/AAD/Request/CoreUserRequest.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/DTO/SCIM/AAD/Response/CoreUser.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Services/Telephony/TextMessagingService.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: config/logging.php\n\nUntracked files:\n (use \"git add <file>...\" to include in what will be committed)\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\t.env.nikilocal\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\t.env.other\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tWEBHOOK_FILTERING_IMPLEMENTATION.md\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Component/SCIM/Mutators/Attributes/User/RoleAttr.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Console/Commands/Crm/Hubspot/SimulateWebhooksCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Console/Commands/Reports/CreateMockAskJiminnyReportResultCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Rules/ListenerRoleCannotHaveAdminOrManagerPermissionRule.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tids.txt\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tpublic/favicon.ico\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\traw_sql_query.sql\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ttests/Unit/Component/SCIM/Mutators/Attributes/User/RoleAttrTest.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ttests/Unit/Policies/CanAccessAiReportsTest.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ttests/Unit/Rules/ListenerRoleCannotHaveAdminOrManagerPermissionRuleTest.php\n\nno changes added to commit (use \"git add\" and/or \"git commit -a\")\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull\nremote: Enumerating objects: 306, done.\nremote: Counting objects: 100% (299/299), done.\nremote: Compressing objects: 100% (183/183), done.\nremote: Total 306 (delta 213), reused 171 (delta 116), pack-reused 7 (from 1)\nReceiving objects: 100% (306/306), 80.12 KiB | 1000.00 KiB/s, done.\nResolving deltas: 100% (213/213), completed with 53 local objects.\nFrom github.com:jiminny/app\n 90bca4e4b2..5604af40cf master -> origin/master\n 4e7078fd8b..0b8343d179 JY-18091-upgrade-to-php-8-5 -> origin/JY-18091-upgrade-to-php-8-5\n 098eeaa087..d5a447e492 JY-20613-allow-owner-role-on-team-setup -> origin/JY-20613-allow-owner-role-on-team-setup\n c3a76ace91..af65249d0f JY-20749-user-can-view-recorded-meetings -> origin/JY-20749-user-can-view-recorded-meetings\n d94a285ae7..7ce96cb5fe JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue\n * [new branch] JY-20842-remove-partial-updater -> origin/JY-20842-remove-partial-updater\n * [new branch] JY-20920-fix-participant-flip -> origin/JY-20920-fix-participant-flip\n * [new branch] secfix/npm-20260519 -> origin/secfix/npm-20260519\nUpdating cb4ebf0c36..5604af40cf\nFast-forward\n app/Component/ES/ChunkSize.php | 54 +++++++++++++++++++\n app/Component/ES/Processor/DTOs/SelectionList.php | 4 +-\n app/Component/ES/Processor/TargetEntitiesSelector.php | 19 ++++---\n app/Component/MeetingBot/Service/ParticipantMatcher.php | 46 ++++++++++++----\n app/Exceptions/RateLimitException.php | 19 ++++++-\n app/Http/Middleware/McpTierMiddleware.php | 27 ++--------\n app/Jobs/Crm/MatchActivityCrmData.php | 47 ++++++++++++----\n app/Jobs/Middleware/HandleHubspotRateLimit.php | 42 +++++++++++++++\n app/Mcp/Servers/JiminnyServer.php | 2 +\n app/Mcp/Tools/GetMeTool.php | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++\n app/Models/Feature/FeatureEnum.php | 1 +\n app/Services/Activity/HubSpot/ProviderResolver.php | 4 +-\n app/Services/Activity/HubSpot/ProviderResolverInterface.php | 2 +-\n app/Services/Activity/HubSpot/Providers/Provider.php | 2 +-\n app/Services/Activity/HubSpot/Providers/ProviderKixie.php | 2 +-\n app/Services/Activity/HubSpot/Providers/ProviderOrum.php | 2 +-\n app/Services/Activity/HubSpot/Providers/ProviderTwilio.php | 2 +-\n app/Services/Activity/HubSpot/Providers/ProviderTwilioFlex.php | 5 +-\n app/Services/Activity/HubSpot/Service.php | 97 +++++++++++++++++++++++++++------\n app/Services/Crm/Hubspot/Client.php | 132 +++++++++++++++++++++++++++++++++++++++++++++\n app/Services/Crm/Hubspot/HubspotClientInterface.php | 15 ++++++\n app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php | 21 ++++----\n app/Services/Crm/Hubspot/Pagination/PaginationState.php | 2 +-\n database/migrations/2026_05_13_124153_create_mcp_feature_flag.php | 25 +++++++++\n tests/Feature/Mcp/GetMeToolFeatureTest.php | 140 +++++++++++++++++++++++++++++++++++++++++++++++\n tests/Feature/Mcp/ListCallsToolFeatureTest.php | 2 +-\n tests/Feature/Mcp/McpTestHelpersTrait.php | 19 ++++++-\n tests/Unit/Component/ES/ChunkSizeTest.php | 50 +++++++++++++++++\n tests/Unit/Component/ES/Processor/DTOs/SelectionListTest.php | 27 +++++++---\n tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 39 ++++++++------\n tests/Unit/Component/MeetingBot/Service/ParticipantMatcherTest.php | 68 ++++++++++++++++++++++-\n tests/Unit/Exceptions/RateLimitExceptionTest.php | 56 +++++++++++++++++++\n tests/Unit/Jobs/Crm/MatchActivityCrmDataTest.php | 8 +--\n tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++\n tests/Unit/Services/Activity/HubSpot/ServiceTest.php | 109 +++++++++++++++++++++++++++++++++++++\n tests/Unit/Services/Crm/Hubspot/ClientTest.php | 250 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n tests/Unit/Services/Crm/Hubspot/Pagination/HubspotPaginationServiceTest.php | 283 +++++++++++++++++++++---------------------------------------------------------------------------\n 37 files changed, 1587 insertions(+), 344 deletions(-)\n create mode 100644 app/Component/ES/ChunkSize.php\n create mode 100644 app/Jobs/Middleware/HandleHubspotRateLimit.php\n create mode 100644 app/Mcp/Tools/GetMeTool.php\n create mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.php\n create mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.php\n create mode 100644 tests/Unit/Component/ES/ChunkSizeTest.php\n create mode 100644 tests/Unit/Exceptions/RateLimitExceptionTest.php\n create mode 100644 tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull\nAlready up to date.\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20676-delete-report-related-objects\nSwitched to a new branch 'JY-20676-delete-report-related-objects'\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20676-delete-report-related-objects) $ csfix\ndocker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff \nPHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.\nPHP runtime: 8.3.30\nRunning analysis on 7 cores with 10 files per process.\nParallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!\nLoaded config default from \".php-cs-fixer.dist.php\".\n 5690/5690 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%\n\n 1) app/Console/Commands/JiminnyDebugCommand.php (statement_indentation, blank_line_before_statement)\n ---------- begin diff ----------\n--- /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php\n+++ /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php\n@@ -23,6 +23,7 @@\n \n if ($action === 'redis-set') {\n $this->testRedisSet();\n+\n return;\n }\n \n@@ -45,7 +46,7 @@\n $ttl = 60;\n \n try {\n-// $result = Redis::set($testKey, $testValue, 'EX', $ttl, 'NX');\n+ // $result = Redis::set($testKey, $testValue, 'EX', $ttl, 'NX');\n $result = Redis::set($testKey, $testValue, ['nx', 'ex' => $ttl]);\n \n if ($result) {\n\n ----------- end diff -----------\n\n\nFixed 1 of 5690 files in 50.673 seconds, 67.00 MB memory used\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20676-delete-report-related-objects) $","depth":4,"on_screen":true,"value":"Last login: Mon May 18 09:17:28 on ttys007\n\nPoetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parents\n\nPoetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parents\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ co master\nerror: Your local changes to the following files would be overwritten by checkout:\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tPIPEDRIVE_V2_MIGRATION_TICKETS.md\nPlease commit your changes or stash them before you switch branches.\nAborting\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ git pull\nremote: Enumerating objects: 1047, done.\nremote: Counting objects: 100% (832/832), done.\nremote: Compressing objects: 100% (298/298), done.\nremote: Total 1047 (delta 634), reused 596 (delta 534), pack-reused 215 (from 3)\nReceiving objects: 100% (1047/1047), 353.16 KiB | 1.56 MiB/s, done.\nResolving deltas: 100% (687/687), completed with 107 local objects.\nFrom github.com:jiminny/app\n 907c54896c..34656c53ed pipedrive-sdk-poc -> origin/pipedrive-sdk-poc\n 03325ec50f..4e7078fd8b JY-18091-upgrade-to-php-8-5 -> origin/JY-18091-upgrade-to-php-8-5\n e7d231e163..bc6a3fce6b JY-20725-handle-HS-search-rate-limit -> origin/JY-20725-handle-HS-search-rate-limit\n * [new branch] JY-20749-user-can-view-recorded-meetings -> origin/JY-20749-user-can-view-recorded-meetings\n 98ca281a04..e0351be069 JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue\n 569abb5149..3906a9238a JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details -> origin/JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details\n ad6c2a86e8..50eb6afba9 JY-20846-mcp-enable-the-ai-to-know-details-about-the-user -> origin/JY-20846-mcp-enable-the-ai-to-know-details-about-the-user\n * [new branch] JY-20893-chunk-control-per-update-target -> origin/JY-20893-chunk-control-per-update-target\n 31c62924a5..cb4ebf0c36 master -> origin/master\nUpdating 907c54896c..34656c53ed\nFast-forward\n PIPEDRIVE_V2_MIGRATION_TICKETS.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 52 insertions(+)\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ co master\nM\u0000\u0000\u0000\u0000\u0000\u0000\t.env.local\nM\u0000\u0000\u0000\u0000\u0000\u0000\tconfig/logging.php\nSwitched to branch 'master'\nYour branch is behind 'origin/master' by 31 commits, and can be fast-forwarded.\n (use \"git pull\" to update your local branch)\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull\nUpdating 31c62924a5..cb4ebf0c36\nFast-forward\n app/Component/ES/Processor/Traits/SelectEntityListTrait.php | 20 ------\n app/Services/Calendar/CalendarActivityService.php | 46 +++++++++++++\n app/Services/Calendar/Command/MapActivityData.php | 106 +++-------------------------\n docs/mcp/explorer/explorer.html | 104 +++++++++++++++++++++++++---\n docs/mcp/explorer/explorer.template.html | 102 ++++++++++++++++++++++++---\n docs/mcp/tools-list.json | 373 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------\n docs/mcp/tools.md | 117 +++++++++++++++++++++++--------\n tests/Unit/Component/ES/AsyncUpdateElasticSearchTest.php | 16 +----\n tests/Unit/Component/ES/Listeners/UpdateMultipleTargetsListenerTest.php | 10 ---\n tests/Unit/Component/ES/Listeners/UpdateSingleTargetListenerTest.php | 6 --\n tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 9 ---\n tests/Unit/Component/ES/Processor/Traits/SelectEntityListTraitTest.php | 15 ++--\n tests/Unit/Component/ES/UpdateProcessManagerTest.php | 2 -\n tests/Unit/Services/Calendar/CalendarActivityServiceTest.php | 150 ++++++++++++++++++++++++++++++++++++++--\n tests/Unit/Services/Calendar/Command/MapActivityDataTest.php | 78 ++-------------------\n 15 files changed, 832 insertions(+), 322 deletions(-)\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20613-allow-owner-role-on-team-setup\nSwitched to a new branch 'JY-20613-allow-owner-role-on-team-setup'\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ csfix\ndocker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff \nPHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.\nPHP runtime: 8.3.30\nRunning analysis on 7 cores with 10 files per process.\nParallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!\nLoaded config default from \".php-cs-fixer.dist.php\".\n 5682/5682 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%\n\n\nFixed 0 of 5682 files in 56.978 seconds, 67.00 MB memory used\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ ;xd\ndocker exec -it docker_lamp_1 bash -c \"mv /usr/local/etc/php/conf.d/xdebug.ini ~/xdebug.ini\"\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\ndocker exec -it docker_lamp_1 supervisorctl restart all\njiminny-worker-processing-2:jiminny-worker-processing-2_00: stopped\njiminny-worker-processing-3:jiminny-worker-processing-3_00: stopped\njiminny-worker-processing-4:jiminny-worker-processing-4_00: stopped\njiminny-worker-processing-5:jiminny-worker-processing-5_00: stopped\njiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00: stopped\nworker-analytics:worker-analytics_00: stopped\nworker-crm-update:worker-crm-update_00: stopped\nworker-download:worker-download_00: stopped\nworker-nudges:worker-nudges_00: stopped\nartisan-schedule:artisan-schedule_00: stopped\nworker-emails:worker-emails_00: stopped\nworker-calendar:worker-calendar_00: stopped\nworker:worker_00: stopped\nworker-conferences:worker-conferences_00: stopped\nworker-crm-sync:worker-crm-sync_00: stopped\njiminny-worker-processing-1:jiminny-worker-processing-1_00: stopped\nworker-audio:worker-audio_00: stopped\nworker-es-update:worker-es-update_00: stopped\nartisan-schedule:artisan-schedule_00: started\njiminny-worker-processing-1:jiminny-worker-processing-1_00: started\njiminny-worker-processing-2:jiminny-worker-processing-2_00: started\njiminny-worker-processing-3:jiminny-worker-processing-3_00: started\njiminny-worker-processing-4:jiminny-worker-processing-4_00: started\njiminny-worker-processing-5:jiminny-worker-processing-5_00: started\njiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00: started\nworker:worker_00: started\nworker-analytics:worker-analytics_00: started\nworker-audio:worker-audio_00: started\nworker-calendar:worker-calendar_00: started\nworker-conferences:worker-conferences_00: started\nworker-crm-sync:worker-crm-sync_00: started\nworker-crm-update:worker-crm-update_00: started\nworker-download:worker-download_00: started\nworker-emails:worker-emails_00: started\nworker-es-update:worker-es-update_00: started\nworker-nudges:worker-nudges_00: started\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\ndocker exec -it docker_lamp_1 php -v\nPHP 8.3.30 (cli) (built: Mar 16 2026 22:32:32) (NTS)\nCopyright (c) The PHP Group\nZend Engine v4.3.30, Copyright (c) Zend Technologies\n with Zend OPcache v8.3.30, Copyright (c), by Zend Technologies\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ csfix\ndocker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff \nPHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.\nPHP runtime: 8.3.30\nRunning analysis on 7 cores with 10 files per process.\nParallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!\nLoaded config default from \".php-cs-fixer.dist.php\".\n 5682/5682 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%\n\n\nFixed 0 of 5682 files in 49.910 seconds, 60.00 MB memory used\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git status\nOn branch JY-20613-allow-owner-role-on-team-setup\nYour branch is ahead of 'origin/JY-20613-allow-owner-role-on-team-setup' by 1 commit.\n (use \"git push\" to publish your local commits)\n\nChanges not staged for commit:\n (use \"git add <file>...\" to update what will be committed)\n (use \"git restore <file>...\" to discard changes in working directory)\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: .env.local\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: config/logging.php\n\nUntracked files:\n (use \"git add <file>...\" to include in what will be committed)\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\t.env.nikilocal\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\t.env.other\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tWEBHOOK_FILTERING_IMPLEMENTATION.md\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Console/Commands/Crm/Hubspot/SimulateWebhooksCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Console/Commands/Reports/CreateMockAskJiminnyReportResultCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tids.txt\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tpublic/favicon.ico\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\traw_sql_query.sql\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ttests/Unit/Policies/CanAccessAiReportsTest.php\n\nno changes added to commit (use \"git add\" and/or \"git commit -a\")\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git pull\nremote: Enumerating objects: 248, done.\nremote: Counting objects: 100% (128/128), done.\nremote: Compressing objects: 100% (23/23), done.\nremote: Total 59 (delta 43), reused 44 (delta 33), pack-reused 0 (from 0)\nUnpacking objects: 100% (59/59), 10.48 KiB | 228.00 KiB/s, done.\nFrom github.com:jiminny/app\n b7df560451..190239dfd4 JY-20613-allow-owner-role-on-team-setup -> origin/JY-20613-allow-owner-role-on-team-setup\n e0351be069..d94a285ae7 JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue\n * [new branch] JY-20920-fix-participant-matcher -> origin/JY-20920-fix-participant-matcher\n cb4ebf0c36..90bca4e4b2 master -> origin/master\nMerge made by the 'ort' strategy.\n app/Component/ES/ChunkSize.php | 54 +++++++++++++++++++++++++++\n app/Component/ES/Processor/DTOs/SelectionList.php | 4 +-\n app/Component/ES/Processor/TargetEntitiesSelector.php | 19 ++++++----\n app/Http/Middleware/McpTierMiddleware.php | 27 +++-----------\n app/Mcp/Servers/JiminnyServer.php | 2 +\n app/Mcp/Tools/GetMeTool.php | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n app/Models/Feature/FeatureEnum.php | 1 +\n database/migrations/2026_05_13_124153_create_mcp_feature_flag.php | 25 +++++++++++++\n front-end/src/components/Settings/Kiosk/modals/EditTeamModal/EditTeamModal.vue | 52 ++++++++++++++++++--------\n front-end/src/components/Settings/Kiosk/modals/EditTeamModal/__tests__/EditTeamModal.spec.js | 14 +++++++\n tests/Feature/Mcp/GetMeToolFeatureTest.php | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n tests/Feature/Mcp/ListCallsToolFeatureTest.php | 2 +-\n tests/Feature/Mcp/McpTestHelpersTrait.php | 19 +++++++++-\n tests/Unit/Component/ES/ChunkSizeTest.php | 50 +++++++++++++++++++++++++\n tests/Unit/Component/ES/Processor/DTOs/SelectionListTest.php | 27 ++++++++++----\n tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 39 +++++++++++---------\n 16 files changed, 557 insertions(+), 75 deletions(-)\n create mode 100644 app/Component/ES/ChunkSize.php\n create mode 100644 app/Mcp/Tools/GetMeTool.php\n create mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.php\n create mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.php\n create mode 100644 tests/Unit/Component/ES/ChunkSizeTest.php\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git push\nEnumerating objects: 40, done.\nCounting objects: 100% (34/34), done.\nDelta compression using up to 8 threads\nCompressing objects: 100% (18/18), done.\nWriting objects: 100% (18/18), 1.58 KiB | 1.58 MiB/s, done.\nTotal 18 (delta 15), reused 0 (delta 0), pack-reused 0\nremote: Resolving deltas: 100% (15/15), completed with 13 local objects.\nTo github.com:jiminny/app.git\n 190239dfd4..ec1b261264 JY-20613-allow-owner-role-on-team-setup -> JY-20613-allow-owner-role-on-team-setup\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ gbr\n* JY-20613-allow-owner-role-on-team-setup\n pipedrive-sdk-poc\n master\n JY-20903-update_activity-stage-on-opportunity-change\n JY-20904-fix-update-es-on-activity-command\n JY-20891-improve-sms-text-relays\n JY-20725-handle-HS-search-rate-limit\n JY-20818-move-AJ-reports-to-separated-datadog-metric\n JY-20773-fix-automated-reports-user-pilot-tracking\n JY-20157-AJ-report-not-send-notification\n JY-20508-notify-before-AJ-report-expiration\n JY-20372-ai-reports-promotion-pages\n JY-20352-sync-opportunities-without-a-local-owner-user-id-is-null\n JY-20738-debug-AJ-tracking-UP\n a\n JY-18909-automated-reports-ask-jiminny\n JY-20692-fix-integration-app-token-auth-response-change\n JY-20553-debug-crm-sync-delays\n JY-20698-fix-SF-activity-types-on-new-playbook\n JY-20543-AJ-report-tracking\n JY-20384-handle-auto-sync-with-no-access-to-event-type\n JY-20458-ask-jiminny-user-definitions\n JY-19666-fix-import-contacts-account-association\n JY-19666-HS-import-contacts-and-accounts-batch-job\n JY-20458-Ask-Jiminny-Reports\n JY-20200-batch-update-CRM-objects-Salesforce\n JY-19666-HS-webhooks-add-contact-and-company\n JY-20348-trigger-setup-DI-layout-on-team-creation\n JY-20326-refactor-info-message-in-command\n JY-20317-fix-auto-log-delay-issue-on-all-channels-disabled\n JY-20312-remove-on-update-change-last-synced-at-crm-configurations\n JY-20306-SF-skip-auto-sync-for-task-based-playbook\n JY-20192-remove-deleted-team-from-saved-search-filters\n JY-20197-import-opportunity-batch-job\n JY-20293-enable-status-field-for-pipedrive-deals\n JY-20191-remove-commands-interactive-prompts\n JY-20118-change-default-sync-strategy\n JY-20183-add-cache-on-auto-log-delay\n JY-20197-add-import-opportunity-batch-job\n 20118-hs-opportunity-make-webhook-strategy-default\n JY-20118-make-default-hs-opportunity-sync-strategy-webhook-based\n JY-20196-handle-opportunity-without-note\n JY-20118-improve-opportunity-import\n JY-20189-handle-activity-search-on-deleted-groups\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ co JY-20725-handle-HS-search-rate-limit\nM\u0000\u0000\u0000\u0000\u0000\u0000\t.env.local\nM\u0000\u0000\u0000\u0000\u0000\u0000\tconfig/logging.php\nSwitched to branch 'JY-20725-handle-HS-search-rate-limit'\nYour branch is behind 'origin/JY-20725-handle-HS-search-rate-limit' by 439 commits, and can be fast-forwarded.\n (use \"git pull\" to update your local branch)\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ git pull\nUpdating 0f3e438941..bc6a3fce6b\nFast-forward\n .gitignore | 3 +-\n .windsurfrules | 168 ++---\n CLAUDE.md | 1 +\n app/Component/ActivityAnalytics/Service/CalculateTalkTimeOffsetsFromTranscription.php | 24 +-\n app/Component/AiActivityType/Services/AiActivityTypeEligibilityChecker.php | 28 +-\n app/Component/AiAutomation/Actions/PrepareUpdateDtoAction.php | 32 +-\n app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.php | 47 ++\n app/Component/AiAutomation/TestCrmAiPromptService.php | 14 +\n app/Component/AiCallScoring/Services/AiCallScoringEligibilityChecker.php | 9 +\n app/Component/ES/ElasticSearchDocumentPartialUpdater.php | 13 +-\n app/Component/ES/ElasticSearchWorkerManager.php | 86 ---\n app/Component/ES/Processor/Actions/LoadDocumentsAction.php | 80 +--\n app/Component/ES/Processor/EntityQueryBuilder.php | 12 +-\n app/Component/ES/Processor/TargetEntitiesSelector.php | 2 +-\n app/Component/ES/Processor/Traits/SkipActivityTrait.php | 25 -\n app/Component/ES/Repositories/EsResetActivityRepository.php | 11 +-\n app/Component/ES/Worker/ActivityWorker.php | 73 --\n app/Component/ES/Worker/EntityWorker.php | 44 --\n app/Component/ES/Worker/WorkerAmount.php | 60 --\n app/Component/ES/Worker/WorkerInterface.php | 15 -\n app/Component/ElasticSearch/Contract/Searchable.php | 4 +\n app/Component/Encoding/Job/AnalyzeTrackChannelsJob.php | 20 +-\n app/Component/Encoding/Service/GenerateSpeechFromSilenceService.php | 85 ++-\n app/Component/FFMpeg/Services/GetSpeechIntervalsService.php | 18 +-\n app/Component/LanguageDetection/Services/FindSpeechTimeService.php | 22 +-\n app/Component/Nudge/Job/ProcessOrganisationImmediateNudgesJob.php | 218 +++++-\n app/Component/ParagraphBreaker/Services/TranscriptionParagraphsService.php | 4 +\n app/Component/ParticipantSpeech/Services/ParticipantSpeechesCreator.php | 33 +\n app/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleter.php | 15 +\n app/Component/ParticipantSpeech/Services/ParticipantSpeechesProvider.php | 51 +-\n app/Component/ParticipantSpeech/Services/ParticipantSpeechesUploader.php | 36 +\n app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.php | 11 +\n app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/NoAssemblyIdException.php | 11 +\n app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/SuccessfulResponse.php | 6 +\n app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNotCorrectFormatException.php | 11 +\n app/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeechesService.php | 23 +-\n app/Component/Transcription/Diarization/Source/MeetingBotSource.php | 16 +-\n app/Component/Transcription/TranscriptionProcessor/TranscriptionProcessor.php | 3 +\n app/Console/Commands/Activities/ActivityHardDeleteCommand.php | 4 +-\n app/Console/Commands/Activities/Copy.php | 2 +\n app/Console/Commands/Activities/SetupIntegration/TwilioSetS3RecordingCredentialsCommand.php | 119 ++++\n app/Console/Commands/Activities/UpdateActivityElasticSearchDocumentCommand.php | 10 +-\n app/Console/Commands/Crm/BackfillOpportunityUserFromAccountCommand.php | 126 ++++\n app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.php | 19 -\n app/Console/Commands/Elasticsearch/AsyncUpdateEsEntities.php | 50 +-\n app/Console/Commands/Elasticsearch/ResetAsyncElasticSearchCommand.php | 30 +-\n app/Console/Commands/GeckoExport/GeckoExportParticipantSpeechesCommand.php | 14 +-\n app/Console/Commands/IssueMcpTokenCommand.php | 84 +++\n app/Console/Commands/JiminnyDebugCommand.php | 7 +-\n app/Console/Commands/Tracks/CleanupActivityTracksCommand.php | 2 +-\n app/Console/Kernel.php | 6 +-\n app/Contracts/Services/Calendar/CalendarTrait.php | 80 ++-\n app/Events/AutomatedReports/AutomatedReportGenerated.php | 3 +\n app/Http/Controllers/API/AiCallScoring/AiScorecardController.php | 7 +-\n app/Http/Controllers/API/TeamAiAutomationController.php | 8 +\n app/Http/Controllers/CustomerApi/CustomerApiController.php | 4 +-\n app/Http/Controllers/Kiosk/ActivityController.php | 58 +-\n app/Http/Controllers/Settings/PlaybookController.php | 15 +-\n app/Http/Kernel.php | 23 +\n app/Http/Middleware/McpAuditMiddleware.php | 156 ++++\n app/Http/Middleware/McpTierMiddleware.php | 54 ++\n app/Http/Requests/API/V2/ZapierUploadActivityRequest.php | 28 +-\n app/Jobs/Activity/Import/ImportTwilioVideoSpeechesJob.php | 25 +-\n app/Jobs/Activity/Import/IsActivityReadyForProcessingJob.php | 10 +-\n app/Jobs/Calendar/SetupCalendarSync.php | 21 +-\n app/Jobs/ImportRemoteTrackJob.php | 96 ++-\n app/Jobs/Mailbox/EmailTextRelay.php | 15 +-\n app/Mcp/Contracts/McpCallRepositoryInterface.php | 30 +\n app/Mcp/DTO/ListCallsFilters.php | 29 +\n app/Mcp/Errors/McpError.php | 123 ++++\n app/Mcp/Repositories/McpActivityHydrator.php | 145 ++++\n app/Mcp/Repositories/McpCallRepository.php | 84 +++\n app/Mcp/Repositories/McpElasticCallRepository.php | 171 +++++\n app/Mcp/Servers/JiminnyServer.php | 38 +\n app/Mcp/Tools/ListCallsTool.php | 205 ++++++\n app/Models/Activity.php | 10 +-\n app/Models/Activity/Transcription.php | 17 +-\n app/Models/ElasticSearch/OpportunityElasticSearchTrait.php | 5 +\n app/Models/Participant.php | 1 +\n app/Providers/AppServiceProvider.php | 22 +\n app/Repositories/Crm/ContactRepository.php | 69 +-\n app/Repositories/ParticipantSpeechRepository.php | 13 +-\n app/Services/Activity/ParticipantsService.php | 19 +-\n app/Services/Activity/Twilio/S3RecordingCredentialsService.php | 82 +++\n app/Services/ActivityService.php | 21 +-\n app/Services/Calendar/CalendarActivityService.php | 46 ++\n app/Services/Calendar/Command/ImportParticipants.php | 1 +\n app/Services/Calendar/Command/MapActivityData.php | 106 +--\n app/Services/Calendar/GoogleCalendarService.php | 12 +-\n app/Services/Crm/Close/Processor/OpportunityProcessor.php | 2 +-\n app/Services/Crm/Close/Service.php | 22 +-\n app/Services/Crm/Copper/Service.php | 12 +-\n app/Services/Crm/Hubspot/Service.php | 154 +++-\n app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php | 88 ++-\n app/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTrait.php | 22 +-\n app/Services/Crm/Pipedrive/Service.php | 17 +-\n app/Services/Crm/Salesforce/Service.php | 42 +-\n app/Services/Mail/Office/EmailApiClient.php | 129 +---\n app/Services/RecallAI/Commands/ScheduleBotCommand.php | 39 +-\n app/Services/RecallAI/RecallAIService.php | 22 +-\n composer.json | 3 +-\n composer.lock | 87 ++-\n config/mcp.php | 23 +\n database/migrations/2026_04_30_120000_create_mcp_audit_log_table.php | 36 +\n docs/mcp/explorer/explorer.html | 697 ++++++++++++++++++\n docs/mcp/explorer/explorer.template.html | 697 ++++++++++++++++++\n docs/mcp/explorer/generate.js | 215 ++++++\n docs/mcp/explorer/tool-explorer-meta.json | 11 +\n docs/mcp/tools-list.json | 2536 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n docs/mcp/tools.md | 621 ++++++++++++++++\n front-end/package.json | 4 +-\n front-end/src/components/Settings/OrgSettings/AiAutomation/CrmFilling/TemplateFieldForm.vue | 28 +-\n front-end/src/components/Settings/OrgSettings/Playbooks/AddEditPlaybook.vue | 10 +\n front-end/src/components/playback/comments/ActivityComment.less | 10 +-\n front-end/src/components/shared/PromptTester/PromptTester.vue | 12 +-\n front-end/src/components/shared/__tests__/PromptTester.spec.js | 35 +\n front-end/src/components/shared/modals/EntityPickerModal/__tests__/useEntitiesCache.spec.ts | 37 +\n front-end/src/components/shared/modals/EntityPickerModal/useEntitiesCache.ts | 9 +\n front-end/yarn.lock | 16 +-\n phpstan-baseline.neon | 50 --\n routes/api.php | 11 +\n sonar-project.properties | 91 ++-\n tests/Feature/Component/Nudge/ProcessOrganisationImmediateNudgesJobTest.php | 534 ++++++++++++++\n tests/Feature/Jobs/ImportRemoteTrackJobTest.php | 283 +++++++-\n tests/Feature/Mcp/IssueMcpTokenCommandTest.php | 53 ++\n tests/Feature/Mcp/ListCallsToolElasticFeatureTest.php | 155 ++++\n tests/Feature/Mcp/ListCallsToolFeatureTest.php | 352 ++++++++++\n tests/Feature/Mcp/McpTestHelpersTrait.php | 77 ++\n tests/Feature/Services/Team/TeamDeleteHandlers/Retention/RetentionRepositoryHandlerTest.php | 1 +\n tests/Stubs/SentryStub.php | 18 +\n tests/Unit/Component/ActivityAnalytics/Service/CalculateTalkTimeOffsetFromTranscriptionTest.php | 28 +-\n tests/Unit/Component/AiActivityType/Services/AiActivityTypeEligibilityCheckerTest.php | 103 ++-\n tests/Unit/Component/AiAutomation/Actions/PrepareUpdateDtoActionTest.php | 91 +++\n tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheckerTest.php | 124 ++++\n tests/Unit/Component/AiAutomation/TestCrmAiPromptServiceTest.php | 67 +-\n tests/Unit/Component/AiCallScoring/Services/AiCallScoringEligibilityCheckerTest.php | 55 ++\n tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.php | 135 ----\n tests/Unit/Component/ES/Processor/Actions/LoadDocumentsActionTest.php | 220 ++++++\n tests/Unit/Component/ES/Processor/EntityQueryBuilderTest.php | 21 +-\n tests/Unit/Component/ES/Processor/Traits/SkipActivityTraitTest.php | 51 --\n tests/Unit/Component/ES/Worker/ActivityWorkerTest.php | 174 -----\n tests/Unit/Component/ES/Worker/EntityWorkerTest.php | 97 ---\n tests/Unit/Component/ES/Worker/WorkerAmountTest.php | 116 ---\n tests/Unit/Component/Encoding/Job/AnalyzeTrackChannelsJobTest.php | 52 +-\n tests/Unit/Component/Encoding/Service/GenerateSpeechFromSilenceServiceTest.php | 171 ++---\n tests/Unit/Component/FFMpeg/Services/GetSpeechIntervalsTest.php | 36 +-\n tests/Unit/Component/LanguageDetection/Services/FindSpeechTimeServiceTest.php | 20 +-\n tests/Unit/Component/MobileSettings/MobileSettingsControllerTest.php | 5 +-\n tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCreatorTest.php | 75 ++\n tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleterTest.php | 63 ++\n tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesProviderTest.php | 134 ++++\n tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesUploaderTest.php | 57 ++\n tests/Unit/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeechesServiceTest.php | 51 +-\n tests/Unit/Component/Transcription/Diarization/Source/MeetingBotSourceTest.php | 29 +-\n tests/Unit/Contracts/Services/Calendar/CalendarTraitTest.php | 58 +-\n tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.php | 159 +++++\n tests/Unit/Jobs/Activity/Import/ImportTwilioVideoSpeechesJobTest.php | 22 +-\n tests/Unit/Jobs/Activity/Import/IsActivityReadyForProcessingJobTest.php | 26 +-\n tests/Unit/Jobs/Calendar/SetupCalendarSyncTest.php | 25 -\n tests/Unit/Services/Activity/ParticipantsServiceTest.php | 12 +-\n tests/Unit/Services/Activity/Twilio/S3RecordingCredentialsServiceTest.php | 180 +++++\n tests/Unit/Services/ActivityServiceTest.php | 132 ++++\n tests/Unit/Services/Calendar/CalendarActivityServiceTest.php | 150 +++-\n tests/Unit/Services/Calendar/Command/ImportParticipantsTest.php | 6 +-\n tests/Unit/Services/Calendar/Command/MapActivityDataTest.php | 78 +-\n tests/Unit/Services/Calendar/GoogleCalendarServiceTest.php | 116 +++\n tests/Unit/Services/Crm/Close/ServiceTest.php | 165 +++++\n tests/Unit/Services/Crm/Hubspot/ServiceTest.php | 272 ++++++-\n tests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTest.php | 25 +-\n tests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTraitMatchActivitiesTest.php | 3 +-\n tests/Unit/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTraitOpportunitiesTest.php | 40 ++\n tests/Unit/Services/Crm/Pipedrive/ImportOpportunityMatchActivitiesTest.php | 2 +\n tests/Unit/Services/Crm/Salesforce/ServiceTest.php | 139 ++++\n tests/Unit/Services/Mail/Office/EmailApiClientTest.php | 195 ++---\n tests/Unit/Services/RecallAI/RecallAIServiceTest.php | 24 +-\n 175 files changed, 12562 insertions(+), 2162 deletions(-)\n create mode 120000 CLAUDE.md\n create mode 100644 app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.php\n delete mode 100644 app/Component/ES/ElasticSearchWorkerManager.php\n delete mode 100644 app/Component/ES/Processor/Traits/SkipActivityTrait.php\n delete mode 100644 app/Component/ES/Worker/ActivityWorker.php\n delete mode 100644 app/Component/ES/Worker/EntityWorker.php\n delete mode 100644 app/Component/ES/Worker/WorkerAmount.php\n delete mode 100644 app/Component/ES/Worker/WorkerInterface.php\n create mode 100644 app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.php\n create mode 100644 app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/NoAssemblyIdException.php\n create mode 100644 app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNotCorrectFormatException.php\n create mode 100644 app/Console/Commands/Activities/SetupIntegration/TwilioSetS3RecordingCredentialsCommand.php\n create mode 100644 app/Console/Commands/Crm/BackfillOpportunityUserFromAccountCommand.php\n delete mode 100644 app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.php\n create mode 100644 app/Console/Commands/IssueMcpTokenCommand.php\n create mode 100644 app/Http/Middleware/McpAuditMiddleware.php\n create mode 100644 app/Http/Middleware/McpTierMiddleware.php\n create mode 100644 app/Mcp/Contracts/McpCallRepositoryInterface.php\n create mode 100644 app/Mcp/DTO/ListCallsFilters.php\n create mode 100644 app/Mcp/Errors/McpError.php\n create mode 100644 app/Mcp/Repositories/McpActivityHydrator.php\n create mode 100644 app/Mcp/Repositories/McpCallRepository.php\n create mode 100644 app/Mcp/Repositories/McpElasticCallRepository.php\n create mode 100644 app/Mcp/Servers/JiminnyServer.php\n create mode 100644 app/Mcp/Tools/ListCallsTool.php\n create mode 100644 app/Services/Activity/Twilio/S3RecordingCredentialsService.php\n create mode 100644 config/mcp.php\n create mode 100644 database/migrations/2026_04_30_120000_create_mcp_audit_log_table.php\n create mode 100644 docs/mcp/explorer/explorer.html\n create mode 100644 docs/mcp/explorer/explorer.template.html\n create mode 100644 docs/mcp/explorer/generate.js\n create mode 100644 docs/mcp/explorer/tool-explorer-meta.json\n create mode 100644 docs/mcp/tools-list.json\n create mode 100644 docs/mcp/tools.md\n create mode 100644 front-end/src/components/shared/modals/EntityPickerModal/__tests__/useEntitiesCache.spec.ts\n create mode 100644 tests/Feature/Component/Nudge/ProcessOrganisationImmediateNudgesJobTest.php\n create mode 100644 tests/Feature/Mcp/IssueMcpTokenCommandTest.php\n create mode 100644 tests/Feature/Mcp/ListCallsToolElasticFeatureTest.php\n create mode 100644 tests/Feature/Mcp/ListCallsToolFeatureTest.php\n create mode 100644 tests/Feature/Mcp/McpTestHelpersTrait.php\n create mode 100644 tests/Stubs/SentryStub.php\n create mode 100644 tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheckerTest.php\n delete mode 100644 tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.php\n create mode 100644 tests/Unit/Component/ES/Processor/Actions/LoadDocumentsActionTest.php\n delete mode 100644 tests/Unit/Component/ES/Processor/Traits/SkipActivityTraitTest.php\n delete mode 100644 tests/Unit/Component/ES/Worker/ActivityWorkerTest.php\n delete mode 100644 tests/Unit/Component/ES/Worker/EntityWorkerTest.php\n delete mode 100644 tests/Unit/Component/ES/Worker/WorkerAmountTest.php\n create mode 100644 tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCreatorTest.php\n create mode 100644 tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.php\n create mode 100644 tests/Unit/Services/Activity/Twilio/S3RecordingCredentialsServiceTest.php\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ git status\nOn branch master\nYour branch is behind 'origin/master' by 114 commits, and can be fast-forwarded.\n (use \"git pull\" to update your local branch)\n\nChanges not staged for commit:\n (use \"git add <file>...\" to update what will be committed)\n (use \"git restore <file>...\" to discard changes in working directory)\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: .env.local\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Component/SCIM/Constants.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Component/SCIM/ScimProvisioning.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Component/Twilio/Conference/ConferenceManager/SoftPhoneManager.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Console/Commands/JiminnyDebugCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/DTO/SCIM/AAD/Request/CoreUserRequest.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/DTO/SCIM/AAD/Response/CoreUser.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Services/Telephony/TextMessagingService.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: config/logging.php\n\nUntracked files:\n (use \"git add <file>...\" to include in what will be committed)\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\t.env.nikilocal\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\t.env.other\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tWEBHOOK_FILTERING_IMPLEMENTATION.md\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Component/SCIM/Mutators/Attributes/User/RoleAttr.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Console/Commands/Crm/Hubspot/SimulateWebhooksCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Console/Commands/Reports/CreateMockAskJiminnyReportResultCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Rules/ListenerRoleCannotHaveAdminOrManagerPermissionRule.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tids.txt\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tpublic/favicon.ico\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\traw_sql_query.sql\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ttests/Unit/Component/SCIM/Mutators/Attributes/User/RoleAttrTest.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ttests/Unit/Policies/CanAccessAiReportsTest.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ttests/Unit/Rules/ListenerRoleCannotHaveAdminOrManagerPermissionRuleTest.php\n\nno changes added to commit (use \"git add\" and/or \"git commit -a\")\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull\nremote: Enumerating objects: 306, done.\nremote: Counting objects: 100% (299/299), done.\nremote: Compressing objects: 100% (183/183), done.\nremote: Total 306 (delta 213), reused 171 (delta 116), pack-reused 7 (from 1)\nReceiving objects: 100% (306/306), 80.12 KiB | 1000.00 KiB/s, done.\nResolving deltas: 100% (213/213), completed with 53 local objects.\nFrom github.com:jiminny/app\n 90bca4e4b2..5604af40cf master -> origin/master\n 4e7078fd8b..0b8343d179 JY-18091-upgrade-to-php-8-5 -> origin/JY-18091-upgrade-to-php-8-5\n 098eeaa087..d5a447e492 JY-20613-allow-owner-role-on-team-setup -> origin/JY-20613-allow-owner-role-on-team-setup\n c3a76ace91..af65249d0f JY-20749-user-can-view-recorded-meetings -> origin/JY-20749-user-can-view-recorded-meetings\n d94a285ae7..7ce96cb5fe JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue\n * [new branch] JY-20842-remove-partial-updater -> origin/JY-20842-remove-partial-updater\n * [new branch] JY-20920-fix-participant-flip -> origin/JY-20920-fix-participant-flip\n * [new branch] secfix/npm-20260519 -> origin/secfix/npm-20260519\nUpdating cb4ebf0c36..5604af40cf\nFast-forward\n app/Component/ES/ChunkSize.php | 54 +++++++++++++++++++\n app/Component/ES/Processor/DTOs/SelectionList.php | 4 +-\n app/Component/ES/Processor/TargetEntitiesSelector.php | 19 ++++---\n app/Component/MeetingBot/Service/ParticipantMatcher.php | 46 ++++++++++++----\n app/Exceptions/RateLimitException.php | 19 ++++++-\n app/Http/Middleware/McpTierMiddleware.php | 27 ++--------\n app/Jobs/Crm/MatchActivityCrmData.php | 47 ++++++++++++----\n app/Jobs/Middleware/HandleHubspotRateLimit.php | 42 +++++++++++++++\n app/Mcp/Servers/JiminnyServer.php | 2 +\n app/Mcp/Tools/GetMeTool.php | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++\n app/Models/Feature/FeatureEnum.php | 1 +\n app/Services/Activity/HubSpot/ProviderResolver.php | 4 +-\n app/Services/Activity/HubSpot/ProviderResolverInterface.php | 2 +-\n app/Services/Activity/HubSpot/Providers/Provider.php | 2 +-\n app/Services/Activity/HubSpot/Providers/ProviderKixie.php | 2 +-\n app/Services/Activity/HubSpot/Providers/ProviderOrum.php | 2 +-\n app/Services/Activity/HubSpot/Providers/ProviderTwilio.php | 2 +-\n app/Services/Activity/HubSpot/Providers/ProviderTwilioFlex.php | 5 +-\n app/Services/Activity/HubSpot/Service.php | 97 +++++++++++++++++++++++++++------\n app/Services/Crm/Hubspot/Client.php | 132 +++++++++++++++++++++++++++++++++++++++++++++\n app/Services/Crm/Hubspot/HubspotClientInterface.php | 15 ++++++\n app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php | 21 ++++----\n app/Services/Crm/Hubspot/Pagination/PaginationState.php | 2 +-\n database/migrations/2026_05_13_124153_create_mcp_feature_flag.php | 25 +++++++++\n tests/Feature/Mcp/GetMeToolFeatureTest.php | 140 +++++++++++++++++++++++++++++++++++++++++++++++\n tests/Feature/Mcp/ListCallsToolFeatureTest.php | 2 +-\n tests/Feature/Mcp/McpTestHelpersTrait.php | 19 ++++++-\n tests/Unit/Component/ES/ChunkSizeTest.php | 50 +++++++++++++++++\n tests/Unit/Component/ES/Processor/DTOs/SelectionListTest.php | 27 +++++++---\n tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 39 ++++++++------\n tests/Unit/Component/MeetingBot/Service/ParticipantMatcherTest.php | 68 ++++++++++++++++++++++-\n tests/Unit/Exceptions/RateLimitExceptionTest.php | 56 +++++++++++++++++++\n tests/Unit/Jobs/Crm/MatchActivityCrmDataTest.php | 8 +--\n tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++\n tests/Unit/Services/Activity/HubSpot/ServiceTest.php | 109 +++++++++++++++++++++++++++++++++++++\n tests/Unit/Services/Crm/Hubspot/ClientTest.php | 250 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n tests/Unit/Services/Crm/Hubspot/Pagination/HubspotPaginationServiceTest.php | 283 +++++++++++++++++++++---------------------------------------------------------------------------\n 37 files changed, 1587 insertions(+), 344 deletions(-)\n create mode 100644 app/Component/ES/ChunkSize.php\n create mode 100644 app/Jobs/Middleware/HandleHubspotRateLimit.php\n create mode 100644 app/Mcp/Tools/GetMeTool.php\n create mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.php\n create mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.php\n create mode 100644 tests/Unit/Component/ES/ChunkSizeTest.php\n create mode 100644 tests/Unit/Exceptions/RateLimitExceptionTest.php\n create mode 100644 tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull\nAlready up to date.\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20676-delete-report-related-objects\nSwitched to a new branch 'JY-20676-delete-report-related-objects'\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20676-delete-report-related-objects) $ csfix\ndocker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff \nPHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.\nPHP runtime: 8.3.30\nRunning analysis on 7 cores with 10 files per process.\nParallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!\nLoaded config default from \".php-cs-fixer.dist.php\".\n 5690/5690 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%\n\n 1) app/Console/Commands/JiminnyDebugCommand.php (statement_indentation, blank_line_before_statement)\n ---------- begin diff ----------\n--- /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php\n+++ /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php\n@@ -23,6 +23,7 @@\n \n if ($action === 'redis-set') {\n $this->testRedisSet();\n+\n return;\n }\n \n@@ -45,7 +46,7 @@\n $ttl = 60;\n \n try {\n-// $result = Redis::set($testKey, $testValue, 'EX', $ttl, 'NX');\n+ // $result = Redis::set($testKey, $testValue, 'EX', $ttl, 'NX');\n $result = Redis::set($testKey, $testValue, ['nx', 'ex' => $ttl]);\n \n if ($result) {\n\n ----------- end diff -----------\n\n\nFixed 1 of 5690 files in 50.673 seconds, 67.00 MB memory used\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20676-delete-report-related-objects) $","is_focused":true},{"role":"AXRadioButton","text":"DOCKER","depth":2,"bounds":{"left":0.0,"top":0.05888889,"width":0.19826388,"height":0.026666667},"on_screen":true,"role_description":"radio button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close Tab","depth":3,"bounds":{"left":0.004166667,"top":0.06333333,"width":0.011111111,"height":0.017777778},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"DEV (docker)","depth":2,"bounds":{"left":0.19826388,"top":0.05888889,"width":0.19826388,"height":0.026666667},"on_screen":true,"role_description":"radio button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close Tab","depth":3,"bounds":{"left":0.20243056,"top":0.06333333,"width":0.011111111,"height":0.017777778},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"APP (-zsh)","depth":2,"bounds":{"left":0.39652777,"top":0.05888889,"width":0.19791667,"height":0.026666667},"on_screen":true,"role_description":"radio button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close Tab","depth":3,"bounds":{"left":0.40069443,"top":0.06333333,"width":0.011111111,"height":0.017777778},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"ffmpeg","depth":2,"bounds":{"left":0.59444445,"top":0.05888889,"width":0.19791667,"height":0.026666667},"on_screen":true,"role_description":"radio button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close Tab","depth":3,"bounds":{"left":0.5986111,"top":0.06333333,"width":0.011111111,"height":0.017777778},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"-zsh","depth":2,"bounds":{"left":0.79236114,"top":0.05888889,"width":0.19791667,"height":0.026666667},"on_screen":true,"role_description":"radio button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close Tab","depth":3,"bounds":{"left":0.7965278,"top":0.06333333,"width":0.011111111,"height":0.017777778},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"⌥⌘1","depth":1,"bounds":{"left":0.9618056,"top":0.032222223,"width":0.038194418,"height":0.018888889},"on_screen":true,"automation_id":"_NS:8","role_description":"text"},{"role":"AXStaticText","text":"APP (-zsh)","depth":1,"bounds":{"left":0.47777778,"top":0.033333335,"width":0.05138889,"height":0.017777778},"on_screen":true,"role_description":"text"}]...
|
2802650493718167367
|
-1358120912881272742
|
visual_change
|
accessibility
|
NULL
|
Last login: Mon May 18 09:17:28 on ttys007
Poetry Last login: Mon May 18 09:17:28 on ttys007
Poetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parents
Poetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parents
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ co master
error: Your local changes to the following files would be overwritten by checkout:
PIPEDRIVE_V2_MIGRATION_TICKETS.md
Please commit your changes or stash them before you switch branches.
Aborting
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ git pull
remote: Enumerating objects: 1047, done.
remote: Counting objects: 100% (832/832), done.
remote: Compressing objects: 100% (298/298), done.
remote: Total 1047 (delta 634), reused 596 (delta 534), pack-reused 215 (from 3)
Receiving objects: 100% (1047/1047), 353.16 KiB | 1.56 MiB/s, done.
Resolving deltas: 100% (687/687), completed with 107 local objects.
From github.com:jiminny/app
907c54896c..34656c53ed pipedrive-sdk-poc -> origin/pipedrive-sdk-poc
03325ec50f..4e7078fd8b JY-18091-upgrade-to-php-8-5 -> origin/JY-18091-upgrade-to-php-8-5
e7d231e163..bc6a3fce6b JY-20725-handle-HS-search-rate-limit -> origin/JY-20725-handle-HS-search-rate-limit
* [new branch] JY-20749-user-can-view-recorded-meetings -> origin/JY-20749-user-can-view-recorded-meetings
98ca281a04..e0351be069 JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue
569abb5149..3906a9238a JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details -> origin/JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details
ad6c2a86e8..50eb6afba9 JY-20846-mcp-enable-the-ai-to-know-details-about-the-user -> origin/JY-20846-mcp-enable-the-ai-to-know-details-about-the-user
* [new branch] JY-20893-chunk-control-per-update-target -> origin/JY-20893-chunk-control-per-update-target
31c62924a5..cb4ebf0c36 master -> origin/master
Updating 907c54896c..34656c53ed
Fast-forward
PIPEDRIVE_V2_MIGRATION_TICKETS.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 52 insertions(+)
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ co master
M .env.local
M config/logging.php
Switched to branch 'master'
Your branch is behind 'origin/master' by 31 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull
Updating 31c62924a5..cb4ebf0c36
Fast-forward
app/Component/ES/Processor/Traits/SelectEntityListTrait.php | 20 ------
app/Services/Calendar/CalendarActivityService.php | 46 +++++++++++++
app/Services/Calendar/Command/MapActivityData.php | 106 +++-------------------------
docs/mcp/explorer/explorer.html | 104 +++++++++++++++++++++++++---
docs/mcp/explorer/explorer.template.html | 102 ++++++++++++++++++++++++---
docs/mcp/tools-list.json | 373 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
docs/mcp/tools.md | 117 +++++++++++++++++++++++--------
tests/Unit/Component/ES/AsyncUpdateElasticSearchTest.php | 16 +----
tests/Unit/Component/ES/Listeners/UpdateMultipleTargetsListenerTest.php | 10 ---
tests/Unit/Component/ES/Listeners/UpdateSingleTargetListenerTest.php | 6 --
tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 9 ---
tests/Unit/Component/ES/Processor/Traits/SelectEntityListTraitTest.php | 15 ++--
tests/Unit/Component/ES/UpdateProcessManagerTest.php | 2 -
tests/Unit/Services/Calendar/CalendarActivityServiceTest.php | 150 ++++++++++++++++++++++++++++++++++++++--
tests/Unit/Services/Calendar/Command/MapActivityDataTest.php | 78 ++-------------------
15 files changed, 832 insertions(+), 322 deletions(-)
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20613-allow-owner-role-on-team-setup
Switched to a new branch 'JY-20613-allow-owner-role-on-team-setup'
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ csfix
docker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff
PHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.
PHP runtime: 8.3.30
Running analysis on 7 cores with 10 files per process.
Parallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!
Loaded config default from ".php-cs-fixer.dist.php".
5682/5682 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
Fixed 0 of 5682 files in 56.978 seconds, 67.00 MB memory used
What's next:
Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1
Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ csfix
docker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff
PHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.
PHP runtime: 8.3.30
Running analysis on 7 cores with 10 files per process.
Parallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!
Loaded config default from ".php-cs-fixer.dist.php".
5682/5682 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
Fixed 0 of 5682 files in 49.910 seconds, 60.00 MB memory used
What's next:
Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1
Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git pull
remote: Enumerating objects: 248, done.
remote: Counting objects: 100% (128/128), done.
remote: Compressing objects: 100% (23/23), done.
remote: Total 59 (delta 43), reused 44 (delta 33), pack-reused 0 (from 0)
Unpacking objects: 100% (59/59), 10.48 KiB | 228.00 KiB/s, done.
From github.com:jiminny/app
b7df560451..190239dfd4 JY-20613-allow-owner-role-on-team-setup -> origin/JY-20613-allow-owner-role-on-team-setup
e0351be069..d94a285ae7 JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue
* [new branch] JY-20920-fix-participant-matcher -> origin/JY-20920-fix-participant-matcher
cb4ebf0c36..90bca4e4b2 master -> origin/master
Merge made by the 'ort' strategy.
app/Component/ES/ChunkSize.php | 54 +++++++++++++++++++++++++++
app/Component/ES/Processor/DTOs/SelectionList.php | 4 +-
app/Component/ES/Processor/TargetEntitiesSelector.php | 19 ++++++----
app/Http/Middleware/McpTierMiddleware.php | 27 +++-----------
app/Mcp/Servers/JiminnyServer.php | 2 +
app/Mcp/Tools/GetMeTool.php | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
app/Models/Feature/FeatureEnum.php | 1 +
database/migrations/2026_05_13_124153_create_mcp_feature_flag.php | 25 +++++++++++++
front-end/src/components/Settings/Kiosk/modals/EditTeamModal/EditTeamModal.vue | 52 ++++++++++++++++++--------
front-end/src/components/Settings/Kiosk/modals/EditTeamModal/__tests__/EditTeamModal.spec.js | 14 +++++++
tests/Feature/Mcp/GetMeToolFeatureTest.php | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/Feature/Mcp/ListCallsToolFeatureTest.php | 2 +-
tests/Feature/Mcp/McpTestHelpersTrait.php | 19 +++++++++-
tests/Unit/Component/ES/ChunkSizeTest.php | 50 +++++++++++++++++++++++++
tests/Unit/Component/ES/Processor/DTOs/SelectionListTest.php | 27 ++++++++++----
tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 39 +++++++++++---------
16 files changed, 557 insertions(+), 75 deletions(-)
create mode 100644 app/Component/ES/ChunkSize.php
create mode 100644 app/Mcp/Tools/GetMeTool.php
create mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.php
create mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.php
create mode 100644 tests/Unit/Component/ES/ChunkSizeTest.php
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git push
Enumerating objects: 40, done.
Counting objects: 100% (34/34), done.
Delta compression using up to 8 threads
Compressing objects: 100% (18/18), done.
Writing objects: 100% (18/18), 1.58 KiB | 1.58 MiB/s, done.
Total 18 (delta 15), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (15/15), completed with 13 local objects.
To github.com:jiminny/app.git
190239dfd4..ec1b261264 JY-20613-allow-owner-role-on-team-setup -> JY-20613-allow-owner-role-on-team-setup
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ gbr
* JY-20613-allow-owner-role-on-team-setup
pipedrive-sdk-poc
master
JY-20903-update_activity-stage-on-opportunity-change
JY-20904-fix-update-es-on-activity-command
JY-20891-improve-sms-text-relays
JY-20725-handle-HS-search-rate-limit
JY-20818-move-AJ-reports-to-separated-datadog-metric
JY-20773-fix-automated-reports-user-pilot-tracking
JY-20157-AJ-report-not-send-notification
JY-20508-notify-before-AJ-report-expiration
JY-20372-ai-reports-promotion-pages
JY-20352-sync-opportunities-without-a-local-owner-user-id-is-null
JY-20738-debug-AJ-tracking-UP
a
JY-18909-automated-reports-ask-jiminny
JY-20692-fix-integration-app-[API_KEY]
JY-20553-debug-crm-sync-delays
JY-20698-fix-SF-activity-types-on-new-playbook
JY-20543-AJ-report-tracking
JY-20384-handle-auto-sync-with-no-access-to-event-type
JY-20458-ask-jiminny-user-definitions
JY-19666-fix-import-contacts-account-association
JY-19666-HS-import-contacts-and-accounts-batch-job
JY-20458-Ask-Jiminny-Reports
JY-20200-batch-update-CRM-objects-Salesforce
JY-19666-HS-webhooks-add-contact-and-company
JY-20348-trigger-setup-DI-layout-on-team-creation
JY-20326-refactor-info-message-in-command
JY-20317-fix-auto-log-delay-issue-on-all-channels-disabled
JY-20312-remove-on-update-change-last-synced-at-crm-configurations
JY-20306-SF-skip-auto-sync-for-task-based-playbook
JY-20192-remove-deleted-team-from-saved-search-filters
JY-20197-import-opportunity-batch-job
JY-20293-enable-status-field-for-pipedrive-deals
JY-20191-remove-commands-interactive-prompts
JY-20118-change-default-sync-strategy
JY-20183-add-cache-on-auto-log-delay
JY-20197-add-import-opportunity-batch-job
20118-hs-opportunity-make-webhook-strategy-default
JY-20118-make-default-hs-opportunity-sync-strategy-webhook-based
JY-20196-handle-opportunity-without-note
JY-20118-improve-opportunity-import
JY-20189-handle-activity-search-on-deleted-groups
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ co JY-20725-handle-HS-search-rate-limit
M .env.local
M config/logging.php
Switched to branch 'JY-20725-handle-HS-search-rate-limit'
Your branch is behind 'origin/JY-20725-handle-HS-search-rate-limit' by 439 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ git pull
Updating 0f3e438941..bc6a3fce6b
Fast-forward
.gitignore | 3 +-
.windsurfrules | 168 ++---
CLAUDE.md | 1 +
app/Component/ActivityAnalytics/Service/CalculateTalkTimeOffsetsFromTranscription.php | 24 +-
app/Component/AiActivityType/Services/AiActivityTypeEligibilityChecker.php | 28 +-
app/Component/AiAutomation/Actions/PrepareUpdateDtoAction.php | 32 +-
app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.php | 47 ++
app/Component/AiAutomation/TestCrmAiPromptService.php | 14 +
app/Component/AiCallScoring/Services/AiCallScoringEligibilityChecker.php | 9 +
app/Component/ES/ElasticSearchDocumentPartialUpdater.php | 13 +-
app/Component/ES/ElasticSearchWorkerManager.php | 86 ---
app/Component/ES/Processor/Actions/LoadDocumentsAction.php | 80 +--
app/Component/ES/Processor/EntityQueryBuilder.php | 12 +-
app/Component/ES/Processor/TargetEntitiesSelector.php | 2 +-
app/Component/ES/Processor/Traits/SkipActivityTrait.php | 25 -
app/Component/ES/Repositories/EsResetActivityRepository.php | 11 +-
app/Component/ES/Worker/ActivityWorker.php | 73 --
app/Component/ES/Worker/EntityWorker.php | 44 --
app/Component/ES/Worker/WorkerAmount.php | 60 --
app/Component/ES/Worker/WorkerInterface.php | 15 -
app/Component/ElasticSearch/Contract/Searchable.php | 4 +
app/Component/Encoding/Job/AnalyzeTrackChannelsJob.php | 20 +-
app/Component/Encoding/Service/GenerateSpeechFromSilenceService.php | 85 ++-
app/Component/FFMpeg/Services/GetSpeechIntervalsService.php | 18 +-
app/Component/LanguageDetection/Services/FindSpeechTimeService.php | 22 +-
app/Component/Nudge/Job/ProcessOrganisationImmediateNudgesJob.php | 218 +++++-
app/Component/ParagraphBreaker/Services/TranscriptionParagraphsService.php | 4 +
app/Component/ParticipantSpeech/Services/ParticipantSpeechesCreator.php | 33 +
app/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleter.php | 15 +
app/Component/ParticipantSpeech/Services/ParticipantSpeechesProvider.php | 51 +-
app/Component/ParticipantSpeech/Services/ParticipantSpeechesUploader.php | 36 +
app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.php | 11 +
app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/NoAssemblyIdException.php | 11 +
app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/SuccessfulResponse.php | 6 +
app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNotCorrectFormatException.php | 11 +
app/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeechesService.php | 23 +-
app/Component/Transcription/Diarization/Source/MeetingBotSource.php | 16 +-
app/Component/Transcription/TranscriptionProcessor/TranscriptionProcessor.php | 3 +
app/Console/Commands/Activities/ActivityHardDeleteCommand.php | 4 +-
app/Console/Commands/Activities/Copy.php | 2 +
app/Console/Commands/Activities/SetupIntegration/TwilioSetS3RecordingCredentialsCommand.php | 119 ++++
app/Console/Commands/Activities/UpdateActivityElasticSearchDocumentCommand.php | 10 +-
app/Console/Commands/Crm/BackfillOpportunityUserFromAccountCommand.php | 126 ++++
app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.php | 19 -
app/Console/Commands/Elasticsearch/AsyncUpdateEsEntities.php | 50 +-
app/Console/Commands/Elasticsearch/ResetAsyncElasticSearchCommand.php | 30 +-
app/Console/Commands/GeckoExport/GeckoExportParticipantSpeechesCommand.php | 14 +-
app/Console/Commands/IssueMcpTokenCommand.php | 84 +++
app/Console/Commands/JiminnyDebugCommand.php | 7 +-
app/Console/Commands/Tracks/CleanupActivityTracksCommand.php | 2 +-
app/Console/Kernel.php | 6 +-
app/Contracts/Services/Calendar/CalendarTrait.php | 80 ++-
app/Events/AutomatedReports/AutomatedReportGenerated.php | 3 +
app/Http/Controllers/API/AiCallScoring/AiScorecardController.php | 7 +-
app/Http/Controllers/API/TeamAiAutomationController.php | 8 +
app/Http/Controllers/CustomerApi/CustomerApiController.php | 4 +-
app/Http/Controllers/Kiosk/ActivityController.php | 58 +-
app/Http/Controllers/Settings/PlaybookController.php | 15 +-
app/Http/Kernel.php | 23 +
app/Http/Middleware/McpAuditMiddleware.php | 156 ++++
app/Http/Middleware/McpTierMiddleware.php | 54 ++
app/Http/Requests/API/V2/ZapierUploadActivityRequest.php | 28 +-
app/Jobs/Activity/Import/ImportTwilioVideoSpeechesJob.php | 25 +-
app/Jobs/Activity/Import/IsActivityReadyForProcessingJob.php | 10 +-
app/Jobs/Calendar/SetupCalendarSync.php | 21 +-
app/Jobs/ImportRemoteTrackJob.php | 96 ++-
app/Jobs/Mailbox/EmailTextRelay.php | 15 +-
app/Mcp/Contracts/McpCallRepositoryInterface.php | 30 +
app/Mcp/DTO/ListCallsFilters.php | 29 +
app/Mcp/Errors/McpError.php | 123 ++++
app/Mcp/Repositories/McpActivityHydrator.php | 145 ++++
app/Mcp/Repositories/McpCallRepository.php | 84 +++
app/Mcp/Repositories/McpElasticCallRepository.php | 171 +++++
app/Mcp/Servers/JiminnyServer.php | 38 +
app/Mcp/Tools/ListCallsTool.php | 205 ++++++
app/Models/Activity.php | 10 +-
app/Models/Activity/Transcription.php | 17 +-
app/Models/ElasticSearch/OpportunityElasticSearchTrait.php | 5 +
app/Models/Participant.php | 1 +
app/Providers/AppServiceProvider.php | 22 +
app/Repositories/Crm/ContactRepository.php | 69 +-
app/Repositories/ParticipantSpeechRepository.php | 13 +-
app/Services/Activity/ParticipantsService.php | 19 +-
app/Services/Activity/Twilio/S3RecordingCredentialsService.php | 82 +++
app/Services/ActivityService.php | 21 +-
app/Services/Calendar/CalendarActivityService.php | 46 ++
app/Services/Calendar/Command/ImportParticipants.php | 1 +
app/Services/Calendar/Command/MapActivityData.php | 106 +--
app/Services/Calendar/GoogleCalendarService.php | 12 +-
app/Services/Crm/Close/Processor/OpportunityProcessor.php | 2 +-
app/Services/Crm/Close/Service.php | 22 +-
app/Services/Crm/Copper/Service.php | 12 +-
app/Services/Crm/Hubspot/Service.php | 154 +++-
app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php | 88 ++-
app/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTrait.php | 22 +-
app/Services/Crm/Pipedrive/Service.php | 17 +-
app/Services/Crm/Salesforce/Service.php | 42 +-
app/Services/Mail/Office/EmailApiClient.php | 129 +---
app/Services/RecallAI/Commands/ScheduleBotCommand.php | 39 +-
app/Services/RecallAI/RecallAIService.php | 22 +-
composer.json | 3 +-
composer.lock | 87 ++-
config/mcp.php | 23 +
database/migrations/2026_04_30_120000_create_mcp_audit_log_table.php | 36 +
docs/mcp/explorer/explorer.html | 697 ++++++++++++++++++
docs/mcp/explorer/explorer.template.html | 697 ++++++++++++++++++
docs/mcp/explorer/generate.js | 215 ++++++
docs/mcp/explorer/tool-explorer-meta.json | 11 +
docs/mcp/tools-list.json | 2536 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
docs/mcp/tools.md | 621 ++++++++++++++++
front-end/package.json | 4 +-
front-end/src/components/Settings/OrgSettings/AiAutomation/CrmFilling/TemplateFieldForm.vue | 28 +-
front-end/src/components/Settings/OrgSettings/Playbooks/AddEditPlaybook.vue | 10 +
front-end/src/components/playback/comments/ActivityComment.less | 10 +-
front-end/src/components/shared/PromptTester/PromptTester.vue | 12 +-
front-end/src/components/shared/__tests__/PromptTester.spec.js | 35 +
front-end/src/components/shared/modals/EntityPickerModal/__tests__/useEntitiesCache.spec.ts | 37 +
front-end/src/components/shared/modals/EntityPickerModal/useEntitiesCache.ts | 9 +
front-end/yarn.lock | 16 +-
phpstan-baseline.neon | 50 --
routes/api.php | 11 +
sonar-project.properties | 91 ++-
tests/Feature/Component/Nudge/ProcessOrganisationImmediateNudgesJobTest.php | 534 ++++++++++++++
tests/Feature/Jobs/ImportRemoteTrackJobTest.php | 283 +++++++-
tests/Feature/Mcp/IssueMcpTokenCommandTest.php | 53 ++
tests/Feature/Mcp/ListCallsToolElasticFeatureTest.php | 155 ++++
tests/Feature/Mcp/ListCallsToolFeatureTest.php | 352 ++++++++++
tests/Feature/Mcp/McpTestHelpersTrait.php | 77 ++
tests/Feature/Services/Team/TeamDeleteHandlers/Retention/RetentionRepositoryHandlerTest.php | 1 +
tests/Stubs/SentryStub.php | 18 +
tests/Unit/Component/ActivityAnalytics/Service/CalculateTalkTimeOffsetFromTranscriptionTest.php | 28 +-
tests/Unit/Component/AiActivityType/Services/AiActivityTypeEligibilityCheckerTest.php | 103 ++-
tests/Unit/Component/AiAutomation/Actions/PrepareUpdateDtoActionTest.php | 91 +++
tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheckerTest.php | 124 ++++
tests/Unit/Component/AiAutomation/TestCrmAiPromptServiceTest.php | 67 +-
tests/Unit/Component/AiCallScoring/Services/AiCallScoringEligibilityCheckerTest.php | 55 ++
tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.php | 135 ----
tests/Unit/Component/ES/Processor/Actions/LoadDocumentsActionTest.php | 220 ++++++
tests/Unit/Component/ES/Processor/EntityQueryBuilderTest.php | 21 +-
tests/Unit/Component/ES/Processor/Traits/SkipActivityTraitTest.php | 51 --
tests/Unit/Component/ES/Worker/ActivityWorkerTest.php | 174 -----
tests/Unit/Component/ES/Worker/EntityWorkerTest.php | 97 ---
tests/Unit/Component/ES/Worker/WorkerAmountTest.php | 116 ---
tests/Unit/Component/Encoding/Job/AnalyzeTrackChannelsJobTest.php | 52 +-
tests/Unit/Component/Encoding/Service/GenerateSpeechFromSilenceServiceTest.php | 171 ++---
tests/Unit/Component/FFMpeg/Services/GetSpeechIntervalsTest.php | 36 +-
tests/Unit/Component/LanguageDetection/Services/FindSpeechTimeServiceTest.php | 20 +-
tests/Unit/Component/MobileSettings/MobileSettingsControllerTest.php | 5 +-
tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCreatorTest.php | 75 ++
tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleterTest.php | 63 ++
tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesProviderTest.php | 134 ++++
tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesUploaderTest.php | 57 ++
tests/Unit/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeechesServiceTest.php | 51 +-
tests/Unit/Component/Transcription/Diarization/Source/MeetingBotSourceTest.php | 29 +-
tests/Unit/Contracts/Services/Calendar/CalendarTraitTest.php | 58 +-
tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.php | 159 +++++
tests/Unit/Jobs/Activity/Import/ImportTwilioVideoSpeechesJobTest.php | 22 +-
tests/Unit/Jobs/Activity/Import/IsActivityReadyForProcessingJobTest.php | 26 +-
tests/Unit/Jobs/Calendar/SetupCalendarSyncTest.php | 25 -
tests/Unit/Services/Activity/ParticipantsServiceTest.php | 12 +-
tests/Unit/Services/Activity/Twilio/S3RecordingCredentialsServiceTest.php | 180 +++++
tests/Unit/Services/ActivityServiceTest.php | 132 ++++
tests/Unit/Services/Calendar/CalendarActivityServiceTest.php | 150 +++-
tests/Unit/Services/Calendar/Command/ImportParticipantsTest.php | 6 +-
tests/Unit/Services/Calendar/Command/MapActivityDataTest.php | 78 +-
tests/Unit/Services/Calendar/GoogleCalendarServiceTest.php | 116 +++
tests/Unit/Services/Crm/Close/ServiceTest.php | 165 +++++
tests/Unit/Services/Crm/Hubspot/ServiceTest.php | 272 ++++++-
tests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTest.php | 25 +-
tests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTraitMatchActivitiesTest.php | 3 +-
tests/Unit/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTraitOpportunitiesTest.php | 40 ++
tests/Unit/Services/Crm/Pipedrive/ImportOpportunityMatchActivitiesTest.php | 2 +
tests/Unit/Services/Crm/Salesforce/ServiceTest.php | 139 ++++
tests/Unit/Services/Mail/Office/EmailApiClientTest.php | 195 ++---
tests/Unit/Services/RecallAI/RecallAIServiceTest.php | 24 +-
175 files changed, 12562 insertions(+), 2162 deletions(-)
create mode 120000 CLAUDE.md
create mode 100644 app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.php
delete mode 100644 app/Component/ES/ElasticSearchWorkerManager.php
delete mode 100644 app/Component/ES/Processor/Traits/SkipActivityTrait.php
delete mode 100644 app/Component/ES/Worker/ActivityWorker.php
delete mode 100644 app/Component/ES/Worker/EntityWorker.php
delete mode 100644 app/Component/ES/Worker/WorkerAmount.php
delete mode 100644 app/Component/ES/Worker/WorkerInterface.php
create mode 100644 app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.php
create mode 100644 app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/NoAssemblyIdException.php
create mode 100644 app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNotCorrectFormatException.php
create mode 100644 app/Console/Commands/Activities/SetupIntegration/TwilioSetS3RecordingCredentialsCommand.php
create mode 100644 app/Console/Commands/Crm/BackfillOpportunityUserFromAccountCommand.php
delete mode 100644 app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.php
create mode 100644 app/Console/Commands/IssueMcpTokenCommand.php
create mode 100644 app/Http/Middleware/McpAuditMiddleware.php
create mode 100644 app/Http/Middleware/McpTierMiddleware.php
create mode 100644 app/Mcp/Contracts/McpCallRepositoryInterface.php
create mode 100644 app/Mcp/DTO/ListCallsFilters.php
create mode 100644 app/Mcp/Errors/McpError.php
create mode 100644 app/Mcp/Repositories/McpActivityHydrator.php
create mode 100644 app/Mcp/Repositories/McpCallRepository.php
create mode 100644 app/Mcp/Repositories/McpElasticCallRepository.php
create mode 100644 app/Mcp/Servers/JiminnyServer.php
create mode 100644 app/Mcp/Tools/ListCallsTool.php
create mode 100644 app/Services/Activity/Twilio/S3RecordingCredentialsService.php
create mode 100644 config/mcp.php
create mode 100644 database/migrations/2026_04_30_120000_create_mcp_audit_log_table.php
create mode 100644 docs/mcp/explorer/explorer.html
create mode 100644 docs/mcp/explorer/explorer.template.html
create mode 100644 docs/mcp/explorer/generate.js
create mode 100644 docs/mcp/explorer/tool-explorer-meta.json
create mode 100644 docs/mcp/tools-list.json
create mode 100644 docs/mcp/tools.md
create mode 100644 front-end/src/components/shared/modals/EntityPickerModal/__tests__/useEntitiesCache.spec.ts
create mode 100644 tests/Feature/Component/Nudge/ProcessOrganisationImmediateNudgesJobTest.php
create mode 100644 tests/Feature/Mcp/IssueMcpTokenCommandTest.php
create mode 100644 tests/Feature/Mcp/ListCallsToolElasticFeatureTest.php
create mode 100644 tests/Feature/Mcp/ListCallsToolFeatureTest.php
create mode 100644 tests/Feature/Mcp/McpTestHelpersTrait.php
create mode 100644 tests/Stubs/SentryStub.php
create mode 100644 tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheckerTest.php
delete mode 100644 tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.php
create mode 100644 tests/Unit/Component/ES/Processor/Actions/LoadDocumentsActionTest.php
delete mode 100644 tests/Unit/Component/ES/Processor/Traits/SkipActivityTraitTest.php
delete mode 100644 tests/Unit/Component/ES/Worker/ActivityWorkerTest.php
delete mode 100644 tests/Unit/Component/ES/Worker/EntityWorkerTest.php
delete mode 100644 tests/Unit/Component/ES/Worker/WorkerAmountTest.php
create mode 100644 tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCreatorTest.php
create mode 100644 tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.php
create mode 100644 tests/Unit/Services/Activity/Twilio/S3RecordingCredentialsServiceTest.php
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ git status
On branch master
Your branch is behind 'origin/master' by 114 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: .env.local
modified: app/Component/SCIM/Constants.php
modified: app/Component/SCIM/ScimProvisioning.php
modified: app/Component/Twilio/Conference/ConferenceManager/SoftPhoneManager.php
modified: app/Console/Commands/JiminnyDebugCommand.php
modified: app/DTO/SCIM/AAD/Request/CoreUserRequest.php
modified: app/DTO/SCIM/AAD/Response/CoreUser.php
modified: app/Services/Telephony/TextMessagingService.php
modified: config/logging.php
Untracked files:
(use "git add <file>..." to include in what will be committed)
.env.nikilocal
.env.other
WEBHOOK_FILTERING_IMPLEMENTATION.md
app/Component/SCIM/Mutators/Attributes/User/RoleAttr.php
app/Console/Commands/Crm/Hubspot/SimulateWebhooksCommand.php
app/Console/Commands/Reports/CreateMockAskJiminnyReportResultCommand.php
app/Rules/ListenerRoleCannotHaveAdminOrManagerPermissionRule.php
ids.txt
public/favicon.ico
raw_sql_query.sql
tests/Unit/Component/SCIM/Mutators/Attributes/User/RoleAttrTest.php
tests/Unit/Policies/CanAccessAiReportsTest.php
tests/Unit/Rules/ListenerRoleCannotHaveAdminOrManagerPermissionRuleTest.php
no changes added to commit (use "git add" and/or "git commit -a")
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull
remote: Enumerating objects: 306, done.
remote: Counting objects: 100% (299/299), done.
remote: Compressing objects: 100% (183/183), done.
remote: Total 306 (delta 213), reused 171 (delta 116), pack-reused 7 (from 1)
Receiving objects: 100% (306/306), 80.12 KiB | 1000.00 KiB/s, done.
Resolving deltas: 100% (213/213), completed with 53 local objects.
From github.com:jiminny/app
90bca4e4b2..5604af40cf master -> origin/master
4e7078fd8b..0b8343d179 JY-18091-upgrade-to-php-8-5 -> origin/JY-18091-upgrade-to-php-8-5
098eeaa087..d5a447e492 JY-20613-allow-owner-role-on-team-setup -> origin/JY-20613-allow-owner-role-on-team-setup
c3a76ace91..af65249d0f JY-20749-user-can-view-recorded-meetings -> origin/JY-20749-user-can-view-recorded-meetings
d94a285ae7..7ce96cb5fe JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue
* [new branch] JY-20842-remove-partial-updater -> origin/JY-20842-remove-partial-updater
* [new branch] JY-20920-fix-participant-flip -> origin/JY-20920-fix-participant-flip
* [new branch] secfix/npm-20260519 -> origin/secfix/npm-20260519
Updating cb4ebf0c36..5604af40cf
Fast-forward
app/Component/ES/ChunkSize.php | 54 +++++++++++++++++++
app/Component/ES/Processor/DTOs/SelectionList.php | 4 +-
app/Component/ES/Processor/TargetEntitiesSelector.php | 19 ++++---
app/Component/MeetingBot/Service/ParticipantMatcher.php | 46 ++++++++++++----
app/Exceptions/RateLimitException.php | 19 ++++++-
app/Http/Middleware/McpTierMiddleware.php | 27 ++--------
app/Jobs/Crm/MatchActivityCrmData.php | 47 ++++++++++++----
app/Jobs/Middleware/HandleHubspotRateLimit.php | 42 +++++++++++++++
app/Mcp/Servers/JiminnyServer.php | 2 +
app/Mcp/Tools/GetMeTool.php | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++
app/Models/Feature/FeatureEnum.php | 1 +
app/Services/Activity/HubSpot/ProviderResolver.php | 4 +-
app/Services/Activity/HubSpot/ProviderResolverInterface.php | 2 +-
app/Services/Activity/HubSpot/Providers/Provider.php | 2 +-
app/Services/Activity/HubSpot/Providers/ProviderKixie.php | 2 +-
app/Services/Activity/HubSpot/Providers/ProviderOrum.php | 2 +-
app/Services/Activity/HubSpot/Providers/ProviderTwilio.php | 2 +-
app/Services/Activity/HubSpot/Providers/ProviderTwilioFlex.php | 5 +-
app/Services/Activity/HubSpot/Service.php | 97 +++++++++++++++++++++++++++------
app/Services/Crm/Hubspot/Client.php | 132 +++++++++++++++++++++++++++++++++++++++++++++
app/Services/Crm/Hubspot/HubspotClientInterface.php | 15 ++++++
app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php | 21 ++++----
app/Services/Crm/Hubspot/Pagination/PaginationState.php | 2 +-
database/migrations/2026_05_13_124153_create_mcp_feature_flag.php | 25 +++++++++
tests/Feature/Mcp/GetMeToolFeatureTest.php | 140 +++++++++++++++++++++++++++++++++++++++++++++++
tests/Feature/Mcp/ListCallsToolFeatureTest.php | 2 +-
tests/Feature/Mcp/McpTestHelpersTrait.php | 19 ++++++-
tests/Unit/Component/ES/ChunkSizeTest.php | 50 +++++++++++++++++
tests/Unit/Component/ES/Processor/DTOs/SelectionListTest.php | 27 +++++++---
tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 39 ++++++++------
tests/Unit/Component/MeetingBot/Service/ParticipantMatcherTest.php | 68 ++++++++++++++++++++++-
tests/Unit/Exceptions/RateLimitExceptionTest.php | 56 +++++++++++++++++++
tests/Unit/Jobs/Crm/MatchActivityCrmDataTest.php | 8 +--
tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++
tests/Unit/Services/Activity/HubSpot/ServiceTest.php | 109 +++++++++++++++++++++++++++++++++++++
tests/Unit/Services/Crm/Hubspot/ClientTest.php | 250 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/Unit/Services/Crm/Hubspot/Pagination/HubspotPaginationServiceTest.php | 283 +++++++++++++++++++++---------------------------------------------------------------------------
37 files changed, 1587 insertions(+), 344 deletions(-)
create mode 100644 app/Component/ES/ChunkSize.php
create mode 100644 app/Jobs/Middleware/HandleHubspotRateLimit.php
create mode 100644 app/Mcp/Tools/GetMeTool.php
create mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.php
create mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.php
create mode 100644 tests/Unit/Component/ES/ChunkSizeTest.php
create mode 100644 tests/Unit/Exceptions/RateLimitExceptionTest.php
create mode 100644 tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull
Already up to date.
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20676-delete-report-related-objects
Switched to a new branch 'JY-20676-delete-report-related-objects'
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20676-delete-report-related-objects) $ csfix
docker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff
PHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.
PHP runtime: 8.3.30
Running analysis on 7 cores with 10 files per process.
Parallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!
Loaded config default from ".php-cs-fixer.dist.php".
5690/5690 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
1) app/Console/Commands/JiminnyDebugCommand.php (statement_indentation, blank_line_before_statement)
---------- begin diff ----------
--- /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php
+++ /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php
@@ -23,6 +23,7 @@
if ($action === 'redis-set') {
$this->testRedisSet();
+
return;
}
@@ -45,7 +46,7 @@
$ttl = 60;
try {
-// $result = Redis::set($testKey, $testValue, 'EX', $ttl, 'NX');
+ // $result = Redis::set($testKey, $testValue, 'EX', $ttl, 'NX');
$result = Redis::set($testKey, $testValue, ['nx', 'ex' => $ttl]);
if ($result) {
----------- end diff -----------
Fixed 1 of 5690 files i...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
57002
|
NULL
|
0
|
2026-05-19T08:48:22.372746+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779180502372_m2.jpg...
|
iTerm2
|
APP (docker)
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Last login: Mon May 18 09:17:28 on ttys007
Poetry Last login: Mon May 18 09:17:28 on ttys007
Poetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parents
Poetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parents
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ co master
error: Your local changes to the following files would be overwritten by checkout:
PIPEDRIVE_V2_MIGRATION_TICKETS.md
Please commit your changes or stash them before you switch branches.
Aborting
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ git pull
remote: Enumerating objects: 1047, done.
remote: Counting objects: 100% (832/832), done.
remote: Compressing objects: 100% (298/298), done.
remote: Total 1047 (delta 634), reused 596 (delta 534), pack-reused 215 (from 3)
Receiving objects: 100% (1047/1047), 353.16 KiB | 1.56 MiB/s, done.
Resolving deltas: 100% (687/687), completed with 107 local objects.
From github.com:jiminny/app
907c54896c..34656c53ed pipedrive-sdk-poc -> origin/pipedrive-sdk-poc
03325ec50f..4e7078fd8b JY-18091-upgrade-to-php-8-5 -> origin/JY-18091-upgrade-to-php-8-5
e7d231e163..bc6a3fce6b JY-20725-handle-HS-search-rate-limit -> origin/JY-20725-handle-HS-search-rate-limit
* [new branch] JY-20749-user-can-view-recorded-meetings -> origin/JY-20749-user-can-view-recorded-meetings
98ca281a04..e0351be069 JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue
569abb5149..3906a9238a JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details -> origin/JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details
ad6c2a86e8..50eb6afba9 JY-20846-mcp-enable-the-ai-to-know-details-about-the-user -> origin/JY-20846-mcp-enable-the-ai-to-know-details-about-the-user
* [new branch] JY-20893-chunk-control-per-update-target -> origin/JY-20893-chunk-control-per-update-target
31c62924a5..cb4ebf0c36 master -> origin/master
Updating 907c54896c..34656c53ed
Fast-forward
PIPEDRIVE_V2_MIGRATION_TICKETS.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 52 insertions(+)
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ co master
M .env.local
M config/logging.php
Switched to branch 'master'
Your branch is behind 'origin/master' by 31 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull
Updating 31c62924a5..cb4ebf0c36
Fast-forward
app/Component/ES/Processor/Traits/SelectEntityListTrait.php | 20 ------
app/Services/Calendar/CalendarActivityService.php | 46 +++++++++++++
app/Services/Calendar/Command/MapActivityData.php | 106 +++-------------------------
docs/mcp/explorer/explorer.html | 104 +++++++++++++++++++++++++---
docs/mcp/explorer/explorer.template.html | 102 ++++++++++++++++++++++++---
docs/mcp/tools-list.json | 373 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
docs/mcp/tools.md | 117 +++++++++++++++++++++++--------
tests/Unit/Component/ES/AsyncUpdateElasticSearchTest.php | 16 +----
tests/Unit/Component/ES/Listeners/UpdateMultipleTargetsListenerTest.php | 10 ---
tests/Unit/Component/ES/Listeners/UpdateSingleTargetListenerTest.php | 6 --
tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 9 ---
tests/Unit/Component/ES/Processor/Traits/SelectEntityListTraitTest.php | 15 ++--
tests/Unit/Component/ES/UpdateProcessManagerTest.php | 2 -
tests/Unit/Services/Calendar/CalendarActivityServiceTest.php | 150 ++++++++++++++++++++++++++++++++++++++--
tests/Unit/Services/Calendar/Command/MapActivityDataTest.php | 78 ++-------------------
15 files changed, 832 insertions(+), 322 deletions(-)
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20613-allow-owner-role-on-team-setup
Switched to a new branch 'JY-20613-allow-owner-role-on-team-setup'
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ csfix
docker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff
PHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.
PHP runtime: 8.3.30
Running analysis on 7 cores with 10 files per process.
Parallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!
Loaded config default from ".php-cs-fixer.dist.php".
5682/5682 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
Fixed 0 of 5682 files in 56.978 seconds, 67.00 MB memory used
What's next:
Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1
Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ csfix
docker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff
PHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.
PHP runtime: 8.3.30
Running analysis on 7 cores with 10 files per process.
Parallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!
Loaded config default from ".php-cs-fixer.dist.php".
5682/5682 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
Fixed 0 of 5682 files in 49.910 seconds, 60.00 MB memory used
What's next:
Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1
Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git pull
remote: Enumerating objects: 248, done.
remote: Counting objects: 100% (128/128), done.
remote: Compressing objects: 100% (23/23), done.
remote: Total 59 (delta 43), reused 44 (delta 33), pack-reused 0 (from 0)
Unpacking objects: 100% (59/59), 10.48 KiB | 228.00 KiB/s, done.
From github.com:jiminny/app
b7df560451..190239dfd4 JY-20613-allow-owner-role-on-team-setup -> origin/JY-20613-allow-owner-role-on-team-setup
e0351be069..d94a285ae7 JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue
* [new branch] JY-20920-fix-participant-matcher -> origin/JY-20920-fix-participant-matcher
cb4ebf0c36..90bca4e4b2 master -> origin/master
Merge made by the 'ort' strategy.
app/Component/ES/ChunkSize.php | 54 +++++++++++++++++++++++++++
app/Component/ES/Processor/DTOs/SelectionList.php | 4 +-
app/Component/ES/Processor/TargetEntitiesSelector.php | 19 ++++++----
app/Http/Middleware/McpTierMiddleware.php | 27 +++-----------
app/Mcp/Servers/JiminnyServer.php | 2 +
app/Mcp/Tools/GetMeTool.php | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
app/Models/Feature/FeatureEnum.php | 1 +
database/migrations/2026_05_13_124153_create_mcp_feature_flag.php | 25 +++++++++++++
front-end/src/components/Settings/Kiosk/modals/EditTeamModal/EditTeamModal.vue | 52 ++++++++++++++++++--------
front-end/src/components/Settings/Kiosk/modals/EditTeamModal/__tests__/EditTeamModal.spec.js | 14 +++++++
tests/Feature/Mcp/GetMeToolFeatureTest.php | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/Feature/Mcp/ListCallsToolFeatureTest.php | 2 +-
tests/Feature/Mcp/McpTestHelpersTrait.php | 19 +++++++++-
tests/Unit/Component/ES/ChunkSizeTest.php | 50 +++++++++++++++++++++++++
tests/Unit/Component/ES/Processor/DTOs/SelectionListTest.php | 27 ++++++++++----
tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 39 +++++++++++---------
16 files changed, 557 insertions(+), 75 deletions(-)
create mode 100644 app/Component/ES/ChunkSize.php
create mode 100644 app/Mcp/Tools/GetMeTool.php
create mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.php
create mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.php
create mode 100644 tests/Unit/Component/ES/ChunkSizeTest.php
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git push
Enumerating objects: 40, done.
Counting objects: 100% (34/34), done.
Delta compression using up to 8 threads
Compressing objects: 100% (18/18), done.
Writing objects: 100% (18/18), 1.58 KiB | 1.58 MiB/s, done.
Total 18 (delta 15), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (15/15), completed with 13 local objects.
To github.com:jiminny/app.git
190239dfd4..ec1b261264 JY-20613-allow-owner-role-on-team-setup -> JY-20613-allow-owner-role-on-team-setup
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ gbr
* JY-20613-allow-owner-role-on-team-setup
pipedrive-sdk-poc
master
JY-20903-update_activity-stage-on-opportunity-change
JY-20904-fix-update-es-on-activity-command
JY-20891-improve-sms-text-relays
JY-20725-handle-HS-search-rate-limit
JY-20818-move-AJ-reports-to-separated-datadog-metric
JY-20773-fix-automated-reports-user-pilot-tracking
JY-20157-AJ-report-not-send-notification
JY-20508-notify-before-AJ-report-expiration
JY-20372-ai-reports-promotion-pages
JY-20352-sync-opportunities-without-a-local-owner-user-id-is-null
JY-20738-debug-AJ-tracking-UP
a
JY-18909-automated-reports-ask-jiminny
JY-20692-fix-integration-app-[API_KEY]
JY-20553-debug-crm-sync-delays
JY-20698-fix-SF-activity-types-on-new-playbook
JY-20543-AJ-report-tracking
JY-20384-handle-auto-sync-with-no-access-to-event-type
JY-20458-ask-jiminny-user-definitions
JY-19666-fix-import-contacts-account-association
JY-19666-HS-import-contacts-and-accounts-batch-job
JY-20458-Ask-Jiminny-Reports
JY-20200-batch-update-CRM-objects-Salesforce
JY-19666-HS-webhooks-add-contact-and-company
JY-20348-trigger-setup-DI-layout-on-team-creation
JY-20326-refactor-info-message-in-command
JY-20317-fix-auto-log-delay-issue-on-all-channels-disabled
JY-20312-remove-on-update-change-last-synced-at-crm-configurations
JY-20306-SF-skip-auto-sync-for-task-based-playbook
JY-20192-remove-deleted-team-from-saved-search-filters
JY-20197-import-opportunity-batch-job
JY-20293-enable-status-field-for-pipedrive-deals
JY-20191-remove-commands-interactive-prompts
JY-20118-change-default-sync-strategy
JY-20183-add-cache-on-auto-log-delay
JY-20197-add-import-opportunity-batch-job
20118-hs-opportunity-make-webhook-strategy-default
JY-20118-make-default-hs-opportunity-sync-strategy-webhook-based
JY-20196-handle-opportunity-without-note
JY-20118-improve-opportunity-import
JY-20189-handle-activity-search-on-deleted-groups
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ co JY-20725-handle-HS-search-rate-limit
M .env.local
M config/logging.php
Switched to branch 'JY-20725-handle-HS-search-rate-limit'
Your branch is behind 'origin/JY-20725-handle-HS-search-rate-limit' by 439 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ git pull
Updating 0f3e438941..bc6a3fce6b
Fast-forward
.gitignore | 3 +-
.windsurfrules | 168 ++---
CLAUDE.md | 1 +
app/Component/ActivityAnalytics/Service/CalculateTalkTimeOffsetsFromTranscription.php | 24 +-
app/Component/AiActivityType/Services/AiActivityTypeEligibilityChecker.php | 28 +-
app/Component/AiAutomation/Actions/PrepareUpdateDtoAction.php | 32 +-
app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.php | 47 ++
app/Component/AiAutomation/TestCrmAiPromptService.php | 14 +
app/Component/AiCallScoring/Services/AiCallScoringEligibilityChecker.php | 9 +
app/Component/ES/ElasticSearchDocumentPartialUpdater.php | 13 +-
app/Component/ES/ElasticSearchWorkerManager.php | 86 ---
app/Component/ES/Processor/Actions/LoadDocumentsAction.php | 80 +--
app/Component/ES/Processor/EntityQueryBuilder.php | 12 +-
app/Component/ES/Processor/TargetEntitiesSelector.php | 2 +-
app/Component/ES/Processor/Traits/SkipActivityTrait.php | 25 -
app/Component/ES/Repositories/EsResetActivityRepository.php | 11 +-
app/Component/ES/Worker/ActivityWorker.php | 73 --
app/Component/ES/Worker/EntityWorker.php | 44 --
app/Component/ES/Worker/WorkerAmount.php | 60 --
app/Component/ES/Worker/WorkerInterface.php | 15 -
app/Component/ElasticSearch/Contract/Searchable.php | 4 +
app/Component/Encoding/Job/AnalyzeTrackChannelsJob.php | 20 +-
app/Component/Encoding/Service/GenerateSpeechFromSilenceService.php | 85 ++-
app/Component/FFMpeg/Services/GetSpeechIntervalsService.php | 18 +-
app/Component/LanguageDetection/Services/FindSpeechTimeService.php | 22 +-
app/Component/Nudge/Job/ProcessOrganisationImmediateNudgesJob.php | 218 +++++-
app/Component/ParagraphBreaker/Services/TranscriptionParagraphsService.php | 4 +
app/Component/ParticipantSpeech/Services/ParticipantSpeechesCreator.php | 33 +
app/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleter.php | 15 +
app/Component/ParticipantSpeech/Services/ParticipantSpeechesProvider.php | 51 +-
app/Component/ParticipantSpeech/Services/ParticipantSpeechesUploader.php | 36 +
app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.php | 11 +
app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/NoAssemblyIdException.php | 11 +
app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/SuccessfulResponse.php | 6 +
app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNotCorrectFormatException.php | 11 +
app/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeechesService.php | 23 +-
app/Component/Transcription/Diarization/Source/MeetingBotSource.php | 16 +-
app/Component/Transcription/TranscriptionProcessor/TranscriptionProcessor.php | 3 +
app/Console/Commands/Activities/ActivityHardDeleteCommand.php | 4 +-
app/Console/Commands/Activities/Copy.php | 2 +
app/Console/Commands/Activities/SetupIntegration/TwilioSetS3RecordingCredentialsCommand.php | 119 ++++
app/Console/Commands/Activities/UpdateActivityElasticSearchDocumentCommand.php | 10 +-
app/Console/Commands/Crm/BackfillOpportunityUserFromAccountCommand.php | 126 ++++
app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.php | 19 -
app/Console/Commands/Elasticsearch/AsyncUpdateEsEntities.php | 50 +-
app/Console/Commands/Elasticsearch/ResetAsyncElasticSearchCommand.php | 30 +-
app/Console/Commands/GeckoExport/GeckoExportParticipantSpeechesCommand.php | 14 +-
app/Console/Commands/IssueMcpTokenCommand.php | 84 +++
app/Console/Commands/JiminnyDebugCommand.php | 7 +-
app/Console/Commands/Tracks/CleanupActivityTracksCommand.php | 2 +-
app/Console/Kernel.php | 6 +-
app/Contracts/Services/Calendar/CalendarTrait.php | 80 ++-
app/Events/AutomatedReports/AutomatedReportGenerated.php | 3 +
app/Http/Controllers/API/AiCallScoring/AiScorecardController.php | 7 +-
app/Http/Controllers/API/TeamAiAutomationController.php | 8 +
app/Http/Controllers/CustomerApi/CustomerApiController.php | 4 +-
app/Http/Controllers/Kiosk/ActivityController.php | 58 +-
app/Http/Controllers/Settings/PlaybookController.php | 15 +-
app/Http/Kernel.php | 23 +
app/Http/Middleware/McpAuditMiddleware.php | 156 ++++
app/Http/Middleware/McpTierMiddleware.php | 54 ++
app/Http/Requests/API/V2/ZapierUploadActivityRequest.php | 28 +-
app/Jobs/Activity/Import/ImportTwilioVideoSpeechesJob.php | 25 +-
app/Jobs/Activity/Import/IsActivityReadyForProcessingJob.php | 10 +-
app/Jobs/Calendar/SetupCalendarSync.php | 21 +-
app/Jobs/ImportRemoteTrackJob.php | 96 ++-
app/Jobs/Mailbox/EmailTextRelay.php | 15 +-
app/Mcp/Contracts/McpCallRepositoryInterface.php | 30 +
app/Mcp/DTO/ListCallsFilters.php | 29 +
app/Mcp/Errors/McpError.php | 123 ++++
app/Mcp/Repositories/McpActivityHydrator.php | 145 ++++
app/Mcp/Repositories/McpCallRepository.php | 84 +++
app/Mcp/Repositories/McpElasticCallRepository.php | 171 +++++
app/Mcp/Servers/JiminnyServer.php | 38 +
app/Mcp/Tools/ListCallsTool.php | 205 ++++++
app/Models/Activity.php | 10 +-
app/Models/Activity/Transcription.php | 17 +-
app/Models/ElasticSearch/OpportunityElasticSearchTrait.php | 5 +
app/Models/Participant.php | 1 +
app/Providers/AppServiceProvider.php | 22 +
app/Repositories/Crm/ContactRepository.php | 69 +-
app/Repositories/ParticipantSpeechRepository.php | 13 +-
app/Services/Activity/ParticipantsService.php | 19 +-
app/Services/Activity/Twilio/S3RecordingCredentialsService.php | 82 +++
app/Services/ActivityService.php | 21 +-
app/Services/Calendar/CalendarActivityService.php | 46 ++
app/Services/Calendar/Command/ImportParticipants.php | 1 +
app/Services/Calendar/Command/MapActivityData.php | 106 +--
app/Services/Calendar/GoogleCalendarService.php | 12 +-
app/Services/Crm/Close/Processor/OpportunityProcessor.php | 2 +-
app/Services/Crm/Close/Service.php | 22 +-
app/Services/Crm/Copper/Service.php | 12 +-
app/Services/Crm/Hubspot/Service.php | 154 +++-
app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php | 88 ++-
app/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTrait.php | 22 +-
app/Services/Crm/Pipedrive/Service.php | 17 +-
app/Services/Crm/Salesforce/Service.php | 42 +-
app/Services/Mail/Office/EmailApiClient.php | 129 +---
app/Services/RecallAI/Commands/ScheduleBotCommand.php | 39 +-
app/Services/RecallAI/RecallAIService.php | 22 +-
composer.json | 3 +-
composer.lock | 87 ++-
config/mcp.php | 23 +
database/migrations/2026_04_30_120000_create_mcp_audit_log_table.php | 36 +
docs/mcp/explorer/explorer.html | 697 ++++++++++++++++++
docs/mcp/explorer/explorer.template.html | 697 ++++++++++++++++++
docs/mcp/explorer/generate.js | 215 ++++++
docs/mcp/explorer/tool-explorer-meta.json | 11 +
docs/mcp/tools-list.json | 2536 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
docs/mcp/tools.md | 621 ++++++++++++++++
front-end/package.json | 4 +-
front-end/src/components/Settings/OrgSettings/AiAutomation/CrmFilling/TemplateFieldForm.vue | 28 +-
front-end/src/components/Settings/OrgSettings/Playbooks/AddEditPlaybook.vue | 10 +
front-end/src/components/playback/comments/ActivityComment.less | 10 +-
front-end/src/components/shared/PromptTester/PromptTester.vue | 12 +-
front-end/src/components/shared/__tests__/PromptTester.spec.js | 35 +
front-end/src/components/shared/modals/EntityPickerModal/__tests__/useEntitiesCache.spec.ts | 37 +
front-end/src/components/shared/modals/EntityPickerModal/useEntitiesCache.ts | 9 +
front-end/yarn.lock | 16 +-
phpstan-baseline.neon | 50 --
routes/api.php | 11 +
sonar-project.properties | 91 ++-
tests/Feature/Component/Nudge/ProcessOrganisationImmediateNudgesJobTest.php | 534 ++++++++++++++
tests/Feature/Jobs/ImportRemoteTrackJobTest.php | 283 +++++++-
tests/Feature/Mcp/IssueMcpTokenCommandTest.php | 53 ++
tests/Feature/Mcp/ListCallsToolElasticFeatureTest.php | 155 ++++
tests/Feature/Mcp/ListCallsToolFeatureTest.php | 352 ++++++++++
tests/Feature/Mcp/McpTestHelpersTrait.php | 77 ++
tests/Feature/Services/Team/TeamDeleteHandlers/Retention/RetentionRepositoryHandlerTest.php | 1 +
tests/Stubs/SentryStub.php | 18 +
tests/Unit/Component/ActivityAnalytics/Service/CalculateTalkTimeOffsetFromTranscriptionTest.php | 28 +-
tests/Unit/Component/AiActivityType/Services/AiActivityTypeEligibilityCheckerTest.php | 103 ++-
tests/Unit/Component/AiAutomation/Actions/PrepareUpdateDtoActionTest.php | 91 +++
tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheckerTest.php | 124 ++++
tests/Unit/Component/AiAutomation/TestCrmAiPromptServiceTest.php | 67 +-
tests/Unit/Component/AiCallScoring/Services/AiCallScoringEligibilityCheckerTest.php | 55 ++
tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.php | 135 ----
tests/Unit/Component/ES/Processor/Actions/LoadDocumentsActionTest.php | 220 ++++++
tests/Unit/Component/ES/Processor/EntityQueryBuilderTest.php | 21 +-
tests/Unit/Component/ES/Processor/Traits/SkipActivityTraitTest.php | 51 --
tests/Unit/Component/ES/Worker/ActivityWorkerTest.php | 174 -----
tests/Unit/Component/ES/Worker/EntityWorkerTest.php | 97 ---
tests/Unit/Component/ES/Worker/WorkerAmountTest.php | 116 ---
tests/Unit/Component/Encoding/Job/AnalyzeTrackChannelsJobTest.php | 52 +-
tests/Unit/Component/Encoding/Service/GenerateSpeechFromSilenceServiceTest.php | 171 ++---
tests/Unit/Component/FFMpeg/Services/GetSpeechIntervalsTest.php | 36 +-
tests/Unit/Component/LanguageDetection/Services/FindSpeechTimeServiceTest.php | 20 +-
tests/Unit/Component/MobileSettings/MobileSettingsControllerTest.php | 5 +-
tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCreatorTest.php | 75 ++
tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleterTest.php | 63 ++
tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesProviderTest.php | 134 ++++
tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesUploaderTest.php | 57 ++
tests/Unit/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeechesServiceTest.php | 51 +-
tests/Unit/Component/Transcription/Diarization/Source/MeetingBotSourceTest.php | 29 +-
tests/Unit/Contracts/Services/Calendar/CalendarTraitTest.php | 58 +-
tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.php | 159 +++++
tests/Unit/Jobs/Activity/Import/ImportTwilioVideoSpeechesJobTest.php | 22 +-
tests/Unit/Jobs/Activity/Import/IsActivityReadyForProcessingJobTest.php | 26 +-
tests/Unit/Jobs/Calendar/SetupCalendarSyncTest.php | 25 -
tests/Unit/Services/Activity/ParticipantsServiceTest.php | 12 +-
tests/Unit/Services/Activity/Twilio/S3RecordingCredentialsServiceTest.php | 180 +++++
tests/Unit/Services/ActivityServiceTest.php | 132 ++++
tests/Unit/Services/Calendar/CalendarActivityServiceTest.php | 150 +++-
tests/Unit/Services/Calendar/Command/ImportParticipantsTest.php | 6 +-
tests/Unit/Services/Calendar/Command/MapActivityDataTest.php | 78 +-
tests/Unit/Services/Calendar/GoogleCalendarServiceTest.php | 116 +++
tests/Unit/Services/Crm/Close/ServiceTest.php | 165 +++++
tests/Unit/Services/Crm/Hubspot/ServiceTest.php | 272 ++++++-
tests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTest.php | 25 +-
tests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTraitMatchActivitiesTest.php | 3 +-
tests/Unit/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTraitOpportunitiesTest.php | 40 ++
tests/Unit/Services/Crm/Pipedrive/ImportOpportunityMatchActivitiesTest.php | 2 +
tests/Unit/Services/Crm/Salesforce/ServiceTest.php | 139 ++++
tests/Unit/Services/Mail/Office/EmailApiClientTest.php | 195 ++---
tests/Unit/Services/RecallAI/RecallAIServiceTest.php | 24 +-
175 files changed, 12562 insertions(+), 2162 deletions(-)
create mode 120000 CLAUDE.md
create mode 100644 app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.php
delete mode 100644 app/Component/ES/ElasticSearchWorkerManager.php
delete mode 100644 app/Component/ES/Processor/Traits/SkipActivityTrait.php
delete mode 100644 app/Component/ES/Worker/ActivityWorker.php
delete mode 100644 app/Component/ES/Worker/EntityWorker.php
delete mode 100644 app/Component/ES/Worker/WorkerAmount.php
delete mode 100644 app/Component/ES/Worker/WorkerInterface.php
create mode 100644 app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.php
create mode 100644 app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/NoAssemblyIdException.php
create mode 100644 app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNotCorrectFormatException.php
create mode 100644 app/Console/Commands/Activities/SetupIntegration/TwilioSetS3RecordingCredentialsCommand.php
create mode 100644 app/Console/Commands/Crm/BackfillOpportunityUserFromAccountCommand.php
delete mode 100644 app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.php
create mode 100644 app/Console/Commands/IssueMcpTokenCommand.php
create mode 100644 app/Http/Middleware/McpAuditMiddleware.php
create mode 100644 app/Http/Middleware/McpTierMiddleware.php
create mode 100644 app/Mcp/Contracts/McpCallRepositoryInterface.php
create mode 100644 app/Mcp/DTO/ListCallsFilters.php
create mode 100644 app/Mcp/Errors/McpError.php
create mode 100644 app/Mcp/Repositories/McpActivityHydrator.php
create mode 100644 app/Mcp/Repositories/McpCallRepository.php
create mode 100644 app/Mcp/Repositories/McpElasticCallRepository.php
create mode 100644 app/Mcp/Servers/JiminnyServer.php
create mode 100644 app/Mcp/Tools/ListCallsTool.php
create mode 100644 app/Services/Activity/Twilio/S3RecordingCredentialsService.php
create mode 100644 config/mcp.php
create mode 100644 database/migrations/2026_04_30_120000_create_mcp_audit_log_table.php
create mode 100644 docs/mcp/explorer/explorer.html
create mode 100644 docs/mcp/explorer/explorer.template.html
create mode 100644 docs/mcp/explorer/generate.js
create mode 100644 docs/mcp/explorer/tool-explorer-meta.json
create mode 100644 docs/mcp/tools-list.json
create mode 100644 docs/mcp/tools.md
create mode 100644 front-end/src/components/shared/modals/EntityPickerModal/__tests__/useEntitiesCache.spec.ts
create mode 100644 tests/Feature/Component/Nudge/ProcessOrganisationImmediateNudgesJobTest.php
create mode 100644 tests/Feature/Mcp/IssueMcpTokenCommandTest.php
create mode 100644 tests/Feature/Mcp/ListCallsToolElasticFeatureTest.php
create mode 100644 tests/Feature/Mcp/ListCallsToolFeatureTest.php
create mode 100644 tests/Feature/Mcp/McpTestHelpersTrait.php
create mode 100644 tests/Stubs/SentryStub.php
create mode 100644 tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheckerTest.php
delete mode 100644 tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.php
create mode 100644 tests/Unit/Component/ES/Processor/Actions/LoadDocumentsActionTest.php
delete mode 100644 tests/Unit/Component/ES/Processor/Traits/SkipActivityTraitTest.php
delete mode 100644 tests/Unit/Component/ES/Worker/ActivityWorkerTest.php
delete mode 100644 tests/Unit/Component/ES/Worker/EntityWorkerTest.php
delete mode 100644 tests/Unit/Component/ES/Worker/WorkerAmountTest.php
create mode 100644 tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCreatorTest.php
create mode 100644 tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.php
create mode 100644 tests/Unit/Services/Activity/Twilio/S3RecordingCredentialsServiceTest.php
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ git status
On branch master
Your branch is behind 'origin/master' by 114 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: .env.local
modified: app/Component/SCIM/Constants.php
modified: app/Component/SCIM/ScimProvisioning.php
modified: app/Component/Twilio/Conference/ConferenceManager/SoftPhoneManager.php
modified: app/Console/Commands/JiminnyDebugCommand.php
modified: app/DTO/SCIM/AAD/Request/CoreUserRequest.php
modified: app/DTO/SCIM/AAD/Response/CoreUser.php
modified: app/Services/Telephony/TextMessagingService.php
modified: config/logging.php
Untracked files:
(use "git add <file>..." to include in what will be committed)
.env.nikilocal
.env.other
WEBHOOK_FILTERING_IMPLEMENTATION.md
app/Component/SCIM/Mutators/Attributes/User/RoleAttr.php
app/Console/Commands/Crm/Hubspot/SimulateWebhooksCommand.php
app/Console/Commands/Reports/CreateMockAskJiminnyReportResultCommand.php
app/Rules/ListenerRoleCannotHaveAdminOrManagerPermissionRule.php
ids.txt
public/favicon.ico
raw_sql_query.sql
tests/Unit/Component/SCIM/Mutators/Attributes/User/RoleAttrTest.php
tests/Unit/Policies/CanAccessAiReportsTest.php
tests/Unit/Rules/ListenerRoleCannotHaveAdminOrManagerPermissionRuleTest.php
no changes added to commit (use "git add" and/or "git commit -a")
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull
remote: Enumerating objects: 306, done.
remote: Counting objects: 100% (299/299), done.
remote: Compressing objects: 100% (183/183), done.
remote: Total 306 (delta 213), reused 171 (delta 116), pack-reused 7 (from 1)
Receiving objects: 100% (306/306), 80.12 KiB | 1000.00 KiB/s, done.
Resolving deltas: 100% (213/213), completed with 53 local objects.
From github.com:jiminny/app
90bca4e4b2..5604af40cf master -> origin/master
4e7078fd8b..0b8343d179 JY-18091-upgrade-to-php-8-5 -> origin/JY-18091-upgrade-to-php-8-5
098eeaa087..d5a447e492 JY-20613-allow-owner-role-on-team-setup -> origin/JY-20613-allow-owner-role-on-team-setup
c3a76ace91..af65249d0f JY-20749-user-can-view-recorded-meetings -> origin/JY-20749-user-can-view-recorded-meetings
d94a285ae7..7ce96cb5fe JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue
* [new branch] JY-20842-remove-partial-updater -> origin/JY-20842-remove-partial-updater
* [new branch] JY-20920-fix-participant-flip -> origin/JY-20920-fix-participant-flip
* [new branch] secfix/npm-20260519 -> origin/secfix/npm-20260519
Updating cb4ebf0c36..5604af40cf
Fast-forward
app/Component/ES/ChunkSize.php | 54 +++++++++++++++++++
app/Component/ES/Processor/DTOs/SelectionList.php | 4 +-
app/Component/ES/Processor/TargetEntitiesSelector.php | 19 ++++---
app/Component/MeetingBot/Service/ParticipantMatcher.php | 46 ++++++++++++----
app/Exceptions/RateLimitException.php | 19 ++++++-
app/Http/Middleware/McpTierMiddleware.php | 27 ++--------
app/Jobs/Crm/MatchActivityCrmData.php | 47 ++++++++++++----
app/Jobs/Middleware/HandleHubspotRateLimit.php | 42 +++++++++++++++
app/Mcp/Servers/JiminnyServer.php | 2 +
app/Mcp/Tools/GetMeTool.php | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++
app/Models/Feature/FeatureEnum.php | 1 +
app/Services/Activity/HubSpot/ProviderResolver.php | 4 +-
app/Services/Activity/HubSpot/ProviderResolverInterface.php | 2 +-
app/Services/Activity/HubSpot/Providers/Provider.php | 2 +-
app/Services/Activity/HubSpot/Providers/ProviderKixie.php | 2 +-
app/Services/Activity/HubSpot/Providers/ProviderOrum.php | 2 +-
app/Services/Activity/HubSpot/Providers/ProviderTwilio.php | 2 +-
app/Services/Activity/HubSpot/Providers/ProviderTwilioFlex.php | 5 +-
app/Services/Activity/HubSpot/Service.php | 97 +++++++++++++++++++++++++++------
app/Services/Crm/Hubspot/Client.php | 132 +++++++++++++++++++++++++++++++++++++++++++++
app/Services/Crm/Hubspot/HubspotClientInterface.php | 15 ++++++
app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php | 21 ++++----
app/Services/Crm/Hubspot/Pagination/PaginationState.php | 2 +-
database/migrations/2026_05_13_124153_create_mcp_feature_flag.php | 25 +++++++++
tests/Feature/Mcp/GetMeToolFeatureTest.php | 140 +++++++++++++++++++++++++++++++++++++++++++++++
tests/Feature/Mcp/ListCallsToolFeatureTest.php | 2 +-
tests/Feature/Mcp/McpTestHelpersTrait.php | 19 ++++++-
tests/Unit/Component/ES/ChunkSizeTest.php | 50 +++++++++++++++++
tests/Unit/Component/ES/Processor/DTOs/SelectionListTest.php | 27 +++++++---
tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 39 ++++++++------
tests/Unit/Component/MeetingBot/Service/ParticipantMatcherTest.php | 68 ++++++++++++++++++++++-
tests/Unit/Exceptions/RateLimitExceptionTest.php | 56 +++++++++++++++++++
tests/Unit/Jobs/Crm/MatchActivityCrmDataTest.php | 8 +--
tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++
tests/Unit/Services/Activity/HubSpot/ServiceTest.php | 109 +++++++++++++++++++++++++++++++++++++
tests/Unit/Services/Crm/Hubspot/ClientTest.php | 250 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/Unit/Services/Crm/Hubspot/Pagination/HubspotPaginationServiceTest.php | 283 +++++++++++++++++++++---------------------------------------------------------------------------
37 files changed, 1587 insertions(+), 344 deletions(-)
create mode 100644 app/Component/ES/ChunkSize.php
create mode 100644 app/Jobs/Middleware/HandleHubspotRateLimit.php
create mode 100644 app/Mcp/Tools/GetMeTool.php
create mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.php
create mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.php
create mode 100644 tests/Unit/Component/ES/ChunkSizeTest.php
create mode 100644 tests/Unit/Exceptions/RateLimitExceptionTest.php
create mode 100644 tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull
Already up to date.
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20676-delete-report-related-objects
Switched to a new branch 'JY-20676-delete-report-related-objects'
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20676-delete-report-related-objects) $ csfix
docker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff
PHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.
PHP runtime: 8.3.30
Running analysis on 7 cores with 10 files per process.
Parallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!
Loaded config default from ".php-cs-fixer.dist.php".
4781/5690 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░] 84%
DOCKER
Close Tab
DEV (docker)
Close Tab
APP (docker)
Close Tab
screenpipe"
Close Tab
-zsh
Close Tab
⌥⌘1
APP (docker)...
|
[{"role":"AXTextArea","text [{"role":"AXTextArea","text":"Last login: Mon May 18 09:17:28 on ttys007\n\nPoetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parents\n\nPoetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parents\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ co master\nerror: Your local changes to the following files would be overwritten by checkout:\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tPIPEDRIVE_V2_MIGRATION_TICKETS.md\nPlease commit your changes or stash them before you switch branches.\nAborting\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ git pull\nremote: Enumerating objects: 1047, done.\nremote: Counting objects: 100% (832/832), done.\nremote: Compressing objects: 100% (298/298), done.\nremote: Total 1047 (delta 634), reused 596 (delta 534), pack-reused 215 (from 3)\nReceiving objects: 100% (1047/1047), 353.16 KiB | 1.56 MiB/s, done.\nResolving deltas: 100% (687/687), completed with 107 local objects.\nFrom github.com:jiminny/app\n 907c54896c..34656c53ed pipedrive-sdk-poc -> origin/pipedrive-sdk-poc\n 03325ec50f..4e7078fd8b JY-18091-upgrade-to-php-8-5 -> origin/JY-18091-upgrade-to-php-8-5\n e7d231e163..bc6a3fce6b JY-20725-handle-HS-search-rate-limit -> origin/JY-20725-handle-HS-search-rate-limit\n * [new branch] JY-20749-user-can-view-recorded-meetings -> origin/JY-20749-user-can-view-recorded-meetings\n 98ca281a04..e0351be069 JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue\n 569abb5149..3906a9238a JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details -> origin/JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details\n ad6c2a86e8..50eb6afba9 JY-20846-mcp-enable-the-ai-to-know-details-about-the-user -> origin/JY-20846-mcp-enable-the-ai-to-know-details-about-the-user\n * [new branch] JY-20893-chunk-control-per-update-target -> origin/JY-20893-chunk-control-per-update-target\n 31c62924a5..cb4ebf0c36 master -> origin/master\nUpdating 907c54896c..34656c53ed\nFast-forward\n PIPEDRIVE_V2_MIGRATION_TICKETS.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 52 insertions(+)\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ co master\nM\u0000\u0000\u0000\u0000\u0000\u0000\t.env.local\nM\u0000\u0000\u0000\u0000\u0000\u0000\tconfig/logging.php\nSwitched to branch 'master'\nYour branch is behind 'origin/master' by 31 commits, and can be fast-forwarded.\n (use \"git pull\" to update your local branch)\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull\nUpdating 31c62924a5..cb4ebf0c36\nFast-forward\n app/Component/ES/Processor/Traits/SelectEntityListTrait.php | 20 ------\n app/Services/Calendar/CalendarActivityService.php | 46 +++++++++++++\n app/Services/Calendar/Command/MapActivityData.php | 106 +++-------------------------\n docs/mcp/explorer/explorer.html | 104 +++++++++++++++++++++++++---\n docs/mcp/explorer/explorer.template.html | 102 ++++++++++++++++++++++++---\n docs/mcp/tools-list.json | 373 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------\n docs/mcp/tools.md | 117 +++++++++++++++++++++++--------\n tests/Unit/Component/ES/AsyncUpdateElasticSearchTest.php | 16 +----\n tests/Unit/Component/ES/Listeners/UpdateMultipleTargetsListenerTest.php | 10 ---\n tests/Unit/Component/ES/Listeners/UpdateSingleTargetListenerTest.php | 6 --\n tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 9 ---\n tests/Unit/Component/ES/Processor/Traits/SelectEntityListTraitTest.php | 15 ++--\n tests/Unit/Component/ES/UpdateProcessManagerTest.php | 2 -\n tests/Unit/Services/Calendar/CalendarActivityServiceTest.php | 150 ++++++++++++++++++++++++++++++++++++++--\n tests/Unit/Services/Calendar/Command/MapActivityDataTest.php | 78 ++-------------------\n 15 files changed, 832 insertions(+), 322 deletions(-)\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20613-allow-owner-role-on-team-setup\nSwitched to a new branch 'JY-20613-allow-owner-role-on-team-setup'\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ csfix\ndocker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff \nPHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.\nPHP runtime: 8.3.30\nRunning analysis on 7 cores with 10 files per process.\nParallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!\nLoaded config default from \".php-cs-fixer.dist.php\".\n 5682/5682 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%\n\n\nFixed 0 of 5682 files in 56.978 seconds, 67.00 MB memory used\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ ;xd\ndocker exec -it docker_lamp_1 bash -c \"mv /usr/local/etc/php/conf.d/xdebug.ini ~/xdebug.ini\"\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\ndocker exec -it docker_lamp_1 supervisorctl restart all\njiminny-worker-processing-2:jiminny-worker-processing-2_00: stopped\njiminny-worker-processing-3:jiminny-worker-processing-3_00: stopped\njiminny-worker-processing-4:jiminny-worker-processing-4_00: stopped\njiminny-worker-processing-5:jiminny-worker-processing-5_00: stopped\njiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00: stopped\nworker-analytics:worker-analytics_00: stopped\nworker-crm-update:worker-crm-update_00: stopped\nworker-download:worker-download_00: stopped\nworker-nudges:worker-nudges_00: stopped\nartisan-schedule:artisan-schedule_00: stopped\nworker-emails:worker-emails_00: stopped\nworker-calendar:worker-calendar_00: stopped\nworker:worker_00: stopped\nworker-conferences:worker-conferences_00: stopped\nworker-crm-sync:worker-crm-sync_00: stopped\njiminny-worker-processing-1:jiminny-worker-processing-1_00: stopped\nworker-audio:worker-audio_00: stopped\nworker-es-update:worker-es-update_00: stopped\nartisan-schedule:artisan-schedule_00: started\njiminny-worker-processing-1:jiminny-worker-processing-1_00: started\njiminny-worker-processing-2:jiminny-worker-processing-2_00: started\njiminny-worker-processing-3:jiminny-worker-processing-3_00: started\njiminny-worker-processing-4:jiminny-worker-processing-4_00: started\njiminny-worker-processing-5:jiminny-worker-processing-5_00: started\njiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00: started\nworker:worker_00: started\nworker-analytics:worker-analytics_00: started\nworker-audio:worker-audio_00: started\nworker-calendar:worker-calendar_00: started\nworker-conferences:worker-conferences_00: started\nworker-crm-sync:worker-crm-sync_00: started\nworker-crm-update:worker-crm-update_00: started\nworker-download:worker-download_00: started\nworker-emails:worker-emails_00: started\nworker-es-update:worker-es-update_00: started\nworker-nudges:worker-nudges_00: started\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\ndocker exec -it docker_lamp_1 php -v\nPHP 8.3.30 (cli) (built: Mar 16 2026 22:32:32) (NTS)\nCopyright (c) The PHP Group\nZend Engine v4.3.30, Copyright (c) Zend Technologies\n with Zend OPcache v8.3.30, Copyright (c), by Zend Technologies\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ csfix\ndocker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff \nPHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.\nPHP runtime: 8.3.30\nRunning analysis on 7 cores with 10 files per process.\nParallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!\nLoaded config default from \".php-cs-fixer.dist.php\".\n 5682/5682 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%\n\n\nFixed 0 of 5682 files in 49.910 seconds, 60.00 MB memory used\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git status\nOn branch JY-20613-allow-owner-role-on-team-setup\nYour branch is ahead of 'origin/JY-20613-allow-owner-role-on-team-setup' by 1 commit.\n (use \"git push\" to publish your local commits)\n\nChanges not staged for commit:\n (use \"git add <file>...\" to update what will be committed)\n (use \"git restore <file>...\" to discard changes in working directory)\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: .env.local\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: config/logging.php\n\nUntracked files:\n (use \"git add <file>...\" to include in what will be committed)\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\t.env.nikilocal\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\t.env.other\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tWEBHOOK_FILTERING_IMPLEMENTATION.md\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Console/Commands/Crm/Hubspot/SimulateWebhooksCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Console/Commands/Reports/CreateMockAskJiminnyReportResultCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tids.txt\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tpublic/favicon.ico\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\traw_sql_query.sql\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ttests/Unit/Policies/CanAccessAiReportsTest.php\n\nno changes added to commit (use \"git add\" and/or \"git commit -a\")\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git pull\nremote: Enumerating objects: 248, done.\nremote: Counting objects: 100% (128/128), done.\nremote: Compressing objects: 100% (23/23), done.\nremote: Total 59 (delta 43), reused 44 (delta 33), pack-reused 0 (from 0)\nUnpacking objects: 100% (59/59), 10.48 KiB | 228.00 KiB/s, done.\nFrom github.com:jiminny/app\n b7df560451..190239dfd4 JY-20613-allow-owner-role-on-team-setup -> origin/JY-20613-allow-owner-role-on-team-setup\n e0351be069..d94a285ae7 JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue\n * [new branch] JY-20920-fix-participant-matcher -> origin/JY-20920-fix-participant-matcher\n cb4ebf0c36..90bca4e4b2 master -> origin/master\nMerge made by the 'ort' strategy.\n app/Component/ES/ChunkSize.php | 54 +++++++++++++++++++++++++++\n app/Component/ES/Processor/DTOs/SelectionList.php | 4 +-\n app/Component/ES/Processor/TargetEntitiesSelector.php | 19 ++++++----\n app/Http/Middleware/McpTierMiddleware.php | 27 +++-----------\n app/Mcp/Servers/JiminnyServer.php | 2 +\n app/Mcp/Tools/GetMeTool.php | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n app/Models/Feature/FeatureEnum.php | 1 +\n database/migrations/2026_05_13_124153_create_mcp_feature_flag.php | 25 +++++++++++++\n front-end/src/components/Settings/Kiosk/modals/EditTeamModal/EditTeamModal.vue | 52 ++++++++++++++++++--------\n front-end/src/components/Settings/Kiosk/modals/EditTeamModal/__tests__/EditTeamModal.spec.js | 14 +++++++\n tests/Feature/Mcp/GetMeToolFeatureTest.php | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n tests/Feature/Mcp/ListCallsToolFeatureTest.php | 2 +-\n tests/Feature/Mcp/McpTestHelpersTrait.php | 19 +++++++++-\n tests/Unit/Component/ES/ChunkSizeTest.php | 50 +++++++++++++++++++++++++\n tests/Unit/Component/ES/Processor/DTOs/SelectionListTest.php | 27 ++++++++++----\n tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 39 +++++++++++---------\n 16 files changed, 557 insertions(+), 75 deletions(-)\n create mode 100644 app/Component/ES/ChunkSize.php\n create mode 100644 app/Mcp/Tools/GetMeTool.php\n create mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.php\n create mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.php\n create mode 100644 tests/Unit/Component/ES/ChunkSizeTest.php\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git push\nEnumerating objects: 40, done.\nCounting objects: 100% (34/34), done.\nDelta compression using up to 8 threads\nCompressing objects: 100% (18/18), done.\nWriting objects: 100% (18/18), 1.58 KiB | 1.58 MiB/s, done.\nTotal 18 (delta 15), reused 0 (delta 0), pack-reused 0\nremote: Resolving deltas: 100% (15/15), completed with 13 local objects.\nTo github.com:jiminny/app.git\n 190239dfd4..ec1b261264 JY-20613-allow-owner-role-on-team-setup -> JY-20613-allow-owner-role-on-team-setup\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ gbr\n* JY-20613-allow-owner-role-on-team-setup\n pipedrive-sdk-poc\n master\n JY-20903-update_activity-stage-on-opportunity-change\n JY-20904-fix-update-es-on-activity-command\n JY-20891-improve-sms-text-relays\n JY-20725-handle-HS-search-rate-limit\n JY-20818-move-AJ-reports-to-separated-datadog-metric\n JY-20773-fix-automated-reports-user-pilot-tracking\n JY-20157-AJ-report-not-send-notification\n JY-20508-notify-before-AJ-report-expiration\n JY-20372-ai-reports-promotion-pages\n JY-20352-sync-opportunities-without-a-local-owner-user-id-is-null\n JY-20738-debug-AJ-tracking-UP\n a\n JY-18909-automated-reports-ask-jiminny\n JY-20692-fix-integration-app-token-auth-response-change\n JY-20553-debug-crm-sync-delays\n JY-20698-fix-SF-activity-types-on-new-playbook\n JY-20543-AJ-report-tracking\n JY-20384-handle-auto-sync-with-no-access-to-event-type\n JY-20458-ask-jiminny-user-definitions\n JY-19666-fix-import-contacts-account-association\n JY-19666-HS-import-contacts-and-accounts-batch-job\n JY-20458-Ask-Jiminny-Reports\n JY-20200-batch-update-CRM-objects-Salesforce\n JY-19666-HS-webhooks-add-contact-and-company\n JY-20348-trigger-setup-DI-layout-on-team-creation\n JY-20326-refactor-info-message-in-command\n JY-20317-fix-auto-log-delay-issue-on-all-channels-disabled\n JY-20312-remove-on-update-change-last-synced-at-crm-configurations\n JY-20306-SF-skip-auto-sync-for-task-based-playbook\n JY-20192-remove-deleted-team-from-saved-search-filters\n JY-20197-import-opportunity-batch-job\n JY-20293-enable-status-field-for-pipedrive-deals\n JY-20191-remove-commands-interactive-prompts\n JY-20118-change-default-sync-strategy\n JY-20183-add-cache-on-auto-log-delay\n JY-20197-add-import-opportunity-batch-job\n 20118-hs-opportunity-make-webhook-strategy-default\n JY-20118-make-default-hs-opportunity-sync-strategy-webhook-based\n JY-20196-handle-opportunity-without-note\n JY-20118-improve-opportunity-import\n JY-20189-handle-activity-search-on-deleted-groups\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ co JY-20725-handle-HS-search-rate-limit\nM\u0000\u0000\u0000\u0000\u0000\u0000\t.env.local\nM\u0000\u0000\u0000\u0000\u0000\u0000\tconfig/logging.php\nSwitched to branch 'JY-20725-handle-HS-search-rate-limit'\nYour branch is behind 'origin/JY-20725-handle-HS-search-rate-limit' by 439 commits, and can be fast-forwarded.\n (use \"git pull\" to update your local branch)\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ git pull\nUpdating 0f3e438941..bc6a3fce6b\nFast-forward\n .gitignore | 3 +-\n .windsurfrules | 168 ++---\n CLAUDE.md | 1 +\n app/Component/ActivityAnalytics/Service/CalculateTalkTimeOffsetsFromTranscription.php | 24 +-\n app/Component/AiActivityType/Services/AiActivityTypeEligibilityChecker.php | 28 +-\n app/Component/AiAutomation/Actions/PrepareUpdateDtoAction.php | 32 +-\n app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.php | 47 ++\n app/Component/AiAutomation/TestCrmAiPromptService.php | 14 +\n app/Component/AiCallScoring/Services/AiCallScoringEligibilityChecker.php | 9 +\n app/Component/ES/ElasticSearchDocumentPartialUpdater.php | 13 +-\n app/Component/ES/ElasticSearchWorkerManager.php | 86 ---\n app/Component/ES/Processor/Actions/LoadDocumentsAction.php | 80 +--\n app/Component/ES/Processor/EntityQueryBuilder.php | 12 +-\n app/Component/ES/Processor/TargetEntitiesSelector.php | 2 +-\n app/Component/ES/Processor/Traits/SkipActivityTrait.php | 25 -\n app/Component/ES/Repositories/EsResetActivityRepository.php | 11 +-\n app/Component/ES/Worker/ActivityWorker.php | 73 --\n app/Component/ES/Worker/EntityWorker.php | 44 --\n app/Component/ES/Worker/WorkerAmount.php | 60 --\n app/Component/ES/Worker/WorkerInterface.php | 15 -\n app/Component/ElasticSearch/Contract/Searchable.php | 4 +\n app/Component/Encoding/Job/AnalyzeTrackChannelsJob.php | 20 +-\n app/Component/Encoding/Service/GenerateSpeechFromSilenceService.php | 85 ++-\n app/Component/FFMpeg/Services/GetSpeechIntervalsService.php | 18 +-\n app/Component/LanguageDetection/Services/FindSpeechTimeService.php | 22 +-\n app/Component/Nudge/Job/ProcessOrganisationImmediateNudgesJob.php | 218 +++++-\n app/Component/ParagraphBreaker/Services/TranscriptionParagraphsService.php | 4 +\n app/Component/ParticipantSpeech/Services/ParticipantSpeechesCreator.php | 33 +\n app/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleter.php | 15 +\n app/Component/ParticipantSpeech/Services/ParticipantSpeechesProvider.php | 51 +-\n app/Component/ParticipantSpeech/Services/ParticipantSpeechesUploader.php | 36 +\n app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.php | 11 +\n app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/NoAssemblyIdException.php | 11 +\n app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/SuccessfulResponse.php | 6 +\n app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNotCorrectFormatException.php | 11 +\n app/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeechesService.php | 23 +-\n app/Component/Transcription/Diarization/Source/MeetingBotSource.php | 16 +-\n app/Component/Transcription/TranscriptionProcessor/TranscriptionProcessor.php | 3 +\n app/Console/Commands/Activities/ActivityHardDeleteCommand.php | 4 +-\n app/Console/Commands/Activities/Copy.php | 2 +\n app/Console/Commands/Activities/SetupIntegration/TwilioSetS3RecordingCredentialsCommand.php | 119 ++++\n app/Console/Commands/Activities/UpdateActivityElasticSearchDocumentCommand.php | 10 +-\n app/Console/Commands/Crm/BackfillOpportunityUserFromAccountCommand.php | 126 ++++\n app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.php | 19 -\n app/Console/Commands/Elasticsearch/AsyncUpdateEsEntities.php | 50 +-\n app/Console/Commands/Elasticsearch/ResetAsyncElasticSearchCommand.php | 30 +-\n app/Console/Commands/GeckoExport/GeckoExportParticipantSpeechesCommand.php | 14 +-\n app/Console/Commands/IssueMcpTokenCommand.php | 84 +++\n app/Console/Commands/JiminnyDebugCommand.php | 7 +-\n app/Console/Commands/Tracks/CleanupActivityTracksCommand.php | 2 +-\n app/Console/Kernel.php | 6 +-\n app/Contracts/Services/Calendar/CalendarTrait.php | 80 ++-\n app/Events/AutomatedReports/AutomatedReportGenerated.php | 3 +\n app/Http/Controllers/API/AiCallScoring/AiScorecardController.php | 7 +-\n app/Http/Controllers/API/TeamAiAutomationController.php | 8 +\n app/Http/Controllers/CustomerApi/CustomerApiController.php | 4 +-\n app/Http/Controllers/Kiosk/ActivityController.php | 58 +-\n app/Http/Controllers/Settings/PlaybookController.php | 15 +-\n app/Http/Kernel.php | 23 +\n app/Http/Middleware/McpAuditMiddleware.php | 156 ++++\n app/Http/Middleware/McpTierMiddleware.php | 54 ++\n app/Http/Requests/API/V2/ZapierUploadActivityRequest.php | 28 +-\n app/Jobs/Activity/Import/ImportTwilioVideoSpeechesJob.php | 25 +-\n app/Jobs/Activity/Import/IsActivityReadyForProcessingJob.php | 10 +-\n app/Jobs/Calendar/SetupCalendarSync.php | 21 +-\n app/Jobs/ImportRemoteTrackJob.php | 96 ++-\n app/Jobs/Mailbox/EmailTextRelay.php | 15 +-\n app/Mcp/Contracts/McpCallRepositoryInterface.php | 30 +\n app/Mcp/DTO/ListCallsFilters.php | 29 +\n app/Mcp/Errors/McpError.php | 123 ++++\n app/Mcp/Repositories/McpActivityHydrator.php | 145 ++++\n app/Mcp/Repositories/McpCallRepository.php | 84 +++\n app/Mcp/Repositories/McpElasticCallRepository.php | 171 +++++\n app/Mcp/Servers/JiminnyServer.php | 38 +\n app/Mcp/Tools/ListCallsTool.php | 205 ++++++\n app/Models/Activity.php | 10 +-\n app/Models/Activity/Transcription.php | 17 +-\n app/Models/ElasticSearch/OpportunityElasticSearchTrait.php | 5 +\n app/Models/Participant.php | 1 +\n app/Providers/AppServiceProvider.php | 22 +\n app/Repositories/Crm/ContactRepository.php | 69 +-\n app/Repositories/ParticipantSpeechRepository.php | 13 +-\n app/Services/Activity/ParticipantsService.php | 19 +-\n app/Services/Activity/Twilio/S3RecordingCredentialsService.php | 82 +++\n app/Services/ActivityService.php | 21 +-\n app/Services/Calendar/CalendarActivityService.php | 46 ++\n app/Services/Calendar/Command/ImportParticipants.php | 1 +\n app/Services/Calendar/Command/MapActivityData.php | 106 +--\n app/Services/Calendar/GoogleCalendarService.php | 12 +-\n app/Services/Crm/Close/Processor/OpportunityProcessor.php | 2 +-\n app/Services/Crm/Close/Service.php | 22 +-\n app/Services/Crm/Copper/Service.php | 12 +-\n app/Services/Crm/Hubspot/Service.php | 154 +++-\n app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php | 88 ++-\n app/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTrait.php | 22 +-\n app/Services/Crm/Pipedrive/Service.php | 17 +-\n app/Services/Crm/Salesforce/Service.php | 42 +-\n app/Services/Mail/Office/EmailApiClient.php | 129 +---\n app/Services/RecallAI/Commands/ScheduleBotCommand.php | 39 +-\n app/Services/RecallAI/RecallAIService.php | 22 +-\n composer.json | 3 +-\n composer.lock | 87 ++-\n config/mcp.php | 23 +\n database/migrations/2026_04_30_120000_create_mcp_audit_log_table.php | 36 +\n docs/mcp/explorer/explorer.html | 697 ++++++++++++++++++\n docs/mcp/explorer/explorer.template.html | 697 ++++++++++++++++++\n docs/mcp/explorer/generate.js | 215 ++++++\n docs/mcp/explorer/tool-explorer-meta.json | 11 +\n docs/mcp/tools-list.json | 2536 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n docs/mcp/tools.md | 621 ++++++++++++++++\n front-end/package.json | 4 +-\n front-end/src/components/Settings/OrgSettings/AiAutomation/CrmFilling/TemplateFieldForm.vue | 28 +-\n front-end/src/components/Settings/OrgSettings/Playbooks/AddEditPlaybook.vue | 10 +\n front-end/src/components/playback/comments/ActivityComment.less | 10 +-\n front-end/src/components/shared/PromptTester/PromptTester.vue | 12 +-\n front-end/src/components/shared/__tests__/PromptTester.spec.js | 35 +\n front-end/src/components/shared/modals/EntityPickerModal/__tests__/useEntitiesCache.spec.ts | 37 +\n front-end/src/components/shared/modals/EntityPickerModal/useEntitiesCache.ts | 9 +\n front-end/yarn.lock | 16 +-\n phpstan-baseline.neon | 50 --\n routes/api.php | 11 +\n sonar-project.properties | 91 ++-\n tests/Feature/Component/Nudge/ProcessOrganisationImmediateNudgesJobTest.php | 534 ++++++++++++++\n tests/Feature/Jobs/ImportRemoteTrackJobTest.php | 283 +++++++-\n tests/Feature/Mcp/IssueMcpTokenCommandTest.php | 53 ++\n tests/Feature/Mcp/ListCallsToolElasticFeatureTest.php | 155 ++++\n tests/Feature/Mcp/ListCallsToolFeatureTest.php | 352 ++++++++++\n tests/Feature/Mcp/McpTestHelpersTrait.php | 77 ++\n tests/Feature/Services/Team/TeamDeleteHandlers/Retention/RetentionRepositoryHandlerTest.php | 1 +\n tests/Stubs/SentryStub.php | 18 +\n tests/Unit/Component/ActivityAnalytics/Service/CalculateTalkTimeOffsetFromTranscriptionTest.php | 28 +-\n tests/Unit/Component/AiActivityType/Services/AiActivityTypeEligibilityCheckerTest.php | 103 ++-\n tests/Unit/Component/AiAutomation/Actions/PrepareUpdateDtoActionTest.php | 91 +++\n tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheckerTest.php | 124 ++++\n tests/Unit/Component/AiAutomation/TestCrmAiPromptServiceTest.php | 67 +-\n tests/Unit/Component/AiCallScoring/Services/AiCallScoringEligibilityCheckerTest.php | 55 ++\n tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.php | 135 ----\n tests/Unit/Component/ES/Processor/Actions/LoadDocumentsActionTest.php | 220 ++++++\n tests/Unit/Component/ES/Processor/EntityQueryBuilderTest.php | 21 +-\n tests/Unit/Component/ES/Processor/Traits/SkipActivityTraitTest.php | 51 --\n tests/Unit/Component/ES/Worker/ActivityWorkerTest.php | 174 -----\n tests/Unit/Component/ES/Worker/EntityWorkerTest.php | 97 ---\n tests/Unit/Component/ES/Worker/WorkerAmountTest.php | 116 ---\n tests/Unit/Component/Encoding/Job/AnalyzeTrackChannelsJobTest.php | 52 +-\n tests/Unit/Component/Encoding/Service/GenerateSpeechFromSilenceServiceTest.php | 171 ++---\n tests/Unit/Component/FFMpeg/Services/GetSpeechIntervalsTest.php | 36 +-\n tests/Unit/Component/LanguageDetection/Services/FindSpeechTimeServiceTest.php | 20 +-\n tests/Unit/Component/MobileSettings/MobileSettingsControllerTest.php | 5 +-\n tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCreatorTest.php | 75 ++\n tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleterTest.php | 63 ++\n tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesProviderTest.php | 134 ++++\n tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesUploaderTest.php | 57 ++\n tests/Unit/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeechesServiceTest.php | 51 +-\n tests/Unit/Component/Transcription/Diarization/Source/MeetingBotSourceTest.php | 29 +-\n tests/Unit/Contracts/Services/Calendar/CalendarTraitTest.php | 58 +-\n tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.php | 159 +++++\n tests/Unit/Jobs/Activity/Import/ImportTwilioVideoSpeechesJobTest.php | 22 +-\n tests/Unit/Jobs/Activity/Import/IsActivityReadyForProcessingJobTest.php | 26 +-\n tests/Unit/Jobs/Calendar/SetupCalendarSyncTest.php | 25 -\n tests/Unit/Services/Activity/ParticipantsServiceTest.php | 12 +-\n tests/Unit/Services/Activity/Twilio/S3RecordingCredentialsServiceTest.php | 180 +++++\n tests/Unit/Services/ActivityServiceTest.php | 132 ++++\n tests/Unit/Services/Calendar/CalendarActivityServiceTest.php | 150 +++-\n tests/Unit/Services/Calendar/Command/ImportParticipantsTest.php | 6 +-\n tests/Unit/Services/Calendar/Command/MapActivityDataTest.php | 78 +-\n tests/Unit/Services/Calendar/GoogleCalendarServiceTest.php | 116 +++\n tests/Unit/Services/Crm/Close/ServiceTest.php | 165 +++++\n tests/Unit/Services/Crm/Hubspot/ServiceTest.php | 272 ++++++-\n tests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTest.php | 25 +-\n tests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTraitMatchActivitiesTest.php | 3 +-\n tests/Unit/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTraitOpportunitiesTest.php | 40 ++\n tests/Unit/Services/Crm/Pipedrive/ImportOpportunityMatchActivitiesTest.php | 2 +\n tests/Unit/Services/Crm/Salesforce/ServiceTest.php | 139 ++++\n tests/Unit/Services/Mail/Office/EmailApiClientTest.php | 195 ++---\n tests/Unit/Services/RecallAI/RecallAIServiceTest.php | 24 +-\n 175 files changed, 12562 insertions(+), 2162 deletions(-)\n create mode 120000 CLAUDE.md\n create mode 100644 app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.php\n delete mode 100644 app/Component/ES/ElasticSearchWorkerManager.php\n delete mode 100644 app/Component/ES/Processor/Traits/SkipActivityTrait.php\n delete mode 100644 app/Component/ES/Worker/ActivityWorker.php\n delete mode 100644 app/Component/ES/Worker/EntityWorker.php\n delete mode 100644 app/Component/ES/Worker/WorkerAmount.php\n delete mode 100644 app/Component/ES/Worker/WorkerInterface.php\n create mode 100644 app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.php\n create mode 100644 app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/NoAssemblyIdException.php\n create mode 100644 app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNotCorrectFormatException.php\n create mode 100644 app/Console/Commands/Activities/SetupIntegration/TwilioSetS3RecordingCredentialsCommand.php\n create mode 100644 app/Console/Commands/Crm/BackfillOpportunityUserFromAccountCommand.php\n delete mode 100644 app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.php\n create mode 100644 app/Console/Commands/IssueMcpTokenCommand.php\n create mode 100644 app/Http/Middleware/McpAuditMiddleware.php\n create mode 100644 app/Http/Middleware/McpTierMiddleware.php\n create mode 100644 app/Mcp/Contracts/McpCallRepositoryInterface.php\n create mode 100644 app/Mcp/DTO/ListCallsFilters.php\n create mode 100644 app/Mcp/Errors/McpError.php\n create mode 100644 app/Mcp/Repositories/McpActivityHydrator.php\n create mode 100644 app/Mcp/Repositories/McpCallRepository.php\n create mode 100644 app/Mcp/Repositories/McpElasticCallRepository.php\n create mode 100644 app/Mcp/Servers/JiminnyServer.php\n create mode 100644 app/Mcp/Tools/ListCallsTool.php\n create mode 100644 app/Services/Activity/Twilio/S3RecordingCredentialsService.php\n create mode 100644 config/mcp.php\n create mode 100644 database/migrations/2026_04_30_120000_create_mcp_audit_log_table.php\n create mode 100644 docs/mcp/explorer/explorer.html\n create mode 100644 docs/mcp/explorer/explorer.template.html\n create mode 100644 docs/mcp/explorer/generate.js\n create mode 100644 docs/mcp/explorer/tool-explorer-meta.json\n create mode 100644 docs/mcp/tools-list.json\n create mode 100644 docs/mcp/tools.md\n create mode 100644 front-end/src/components/shared/modals/EntityPickerModal/__tests__/useEntitiesCache.spec.ts\n create mode 100644 tests/Feature/Component/Nudge/ProcessOrganisationImmediateNudgesJobTest.php\n create mode 100644 tests/Feature/Mcp/IssueMcpTokenCommandTest.php\n create mode 100644 tests/Feature/Mcp/ListCallsToolElasticFeatureTest.php\n create mode 100644 tests/Feature/Mcp/ListCallsToolFeatureTest.php\n create mode 100644 tests/Feature/Mcp/McpTestHelpersTrait.php\n create mode 100644 tests/Stubs/SentryStub.php\n create mode 100644 tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheckerTest.php\n delete mode 100644 tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.php\n create mode 100644 tests/Unit/Component/ES/Processor/Actions/LoadDocumentsActionTest.php\n delete mode 100644 tests/Unit/Component/ES/Processor/Traits/SkipActivityTraitTest.php\n delete mode 100644 tests/Unit/Component/ES/Worker/ActivityWorkerTest.php\n delete mode 100644 tests/Unit/Component/ES/Worker/EntityWorkerTest.php\n delete mode 100644 tests/Unit/Component/ES/Worker/WorkerAmountTest.php\n create mode 100644 tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCreatorTest.php\n create mode 100644 tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.php\n create mode 100644 tests/Unit/Services/Activity/Twilio/S3RecordingCredentialsServiceTest.php\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ git status\nOn branch master\nYour branch is behind 'origin/master' by 114 commits, and can be fast-forwarded.\n (use \"git pull\" to update your local branch)\n\nChanges not staged for commit:\n (use \"git add <file>...\" to update what will be committed)\n (use \"git restore <file>...\" to discard changes in working directory)\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: .env.local\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Component/SCIM/Constants.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Component/SCIM/ScimProvisioning.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Component/Twilio/Conference/ConferenceManager/SoftPhoneManager.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Console/Commands/JiminnyDebugCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/DTO/SCIM/AAD/Request/CoreUserRequest.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/DTO/SCIM/AAD/Response/CoreUser.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Services/Telephony/TextMessagingService.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: config/logging.php\n\nUntracked files:\n (use \"git add <file>...\" to include in what will be committed)\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\t.env.nikilocal\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\t.env.other\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tWEBHOOK_FILTERING_IMPLEMENTATION.md\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Component/SCIM/Mutators/Attributes/User/RoleAttr.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Console/Commands/Crm/Hubspot/SimulateWebhooksCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Console/Commands/Reports/CreateMockAskJiminnyReportResultCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Rules/ListenerRoleCannotHaveAdminOrManagerPermissionRule.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tids.txt\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tpublic/favicon.ico\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\traw_sql_query.sql\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ttests/Unit/Component/SCIM/Mutators/Attributes/User/RoleAttrTest.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ttests/Unit/Policies/CanAccessAiReportsTest.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ttests/Unit/Rules/ListenerRoleCannotHaveAdminOrManagerPermissionRuleTest.php\n\nno changes added to commit (use \"git add\" and/or \"git commit -a\")\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull\nremote: Enumerating objects: 306, done.\nremote: Counting objects: 100% (299/299), done.\nremote: Compressing objects: 100% (183/183), done.\nremote: Total 306 (delta 213), reused 171 (delta 116), pack-reused 7 (from 1)\nReceiving objects: 100% (306/306), 80.12 KiB | 1000.00 KiB/s, done.\nResolving deltas: 100% (213/213), completed with 53 local objects.\nFrom github.com:jiminny/app\n 90bca4e4b2..5604af40cf master -> origin/master\n 4e7078fd8b..0b8343d179 JY-18091-upgrade-to-php-8-5 -> origin/JY-18091-upgrade-to-php-8-5\n 098eeaa087..d5a447e492 JY-20613-allow-owner-role-on-team-setup -> origin/JY-20613-allow-owner-role-on-team-setup\n c3a76ace91..af65249d0f JY-20749-user-can-view-recorded-meetings -> origin/JY-20749-user-can-view-recorded-meetings\n d94a285ae7..7ce96cb5fe JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue\n * [new branch] JY-20842-remove-partial-updater -> origin/JY-20842-remove-partial-updater\n * [new branch] JY-20920-fix-participant-flip -> origin/JY-20920-fix-participant-flip\n * [new branch] secfix/npm-20260519 -> origin/secfix/npm-20260519\nUpdating cb4ebf0c36..5604af40cf\nFast-forward\n app/Component/ES/ChunkSize.php | 54 +++++++++++++++++++\n app/Component/ES/Processor/DTOs/SelectionList.php | 4 +-\n app/Component/ES/Processor/TargetEntitiesSelector.php | 19 ++++---\n app/Component/MeetingBot/Service/ParticipantMatcher.php | 46 ++++++++++++----\n app/Exceptions/RateLimitException.php | 19 ++++++-\n app/Http/Middleware/McpTierMiddleware.php | 27 ++--------\n app/Jobs/Crm/MatchActivityCrmData.php | 47 ++++++++++++----\n app/Jobs/Middleware/HandleHubspotRateLimit.php | 42 +++++++++++++++\n app/Mcp/Servers/JiminnyServer.php | 2 +\n app/Mcp/Tools/GetMeTool.php | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++\n app/Models/Feature/FeatureEnum.php | 1 +\n app/Services/Activity/HubSpot/ProviderResolver.php | 4 +-\n app/Services/Activity/HubSpot/ProviderResolverInterface.php | 2 +-\n app/Services/Activity/HubSpot/Providers/Provider.php | 2 +-\n app/Services/Activity/HubSpot/Providers/ProviderKixie.php | 2 +-\n app/Services/Activity/HubSpot/Providers/ProviderOrum.php | 2 +-\n app/Services/Activity/HubSpot/Providers/ProviderTwilio.php | 2 +-\n app/Services/Activity/HubSpot/Providers/ProviderTwilioFlex.php | 5 +-\n app/Services/Activity/HubSpot/Service.php | 97 +++++++++++++++++++++++++++------\n app/Services/Crm/Hubspot/Client.php | 132 +++++++++++++++++++++++++++++++++++++++++++++\n app/Services/Crm/Hubspot/HubspotClientInterface.php | 15 ++++++\n app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php | 21 ++++----\n app/Services/Crm/Hubspot/Pagination/PaginationState.php | 2 +-\n database/migrations/2026_05_13_124153_create_mcp_feature_flag.php | 25 +++++++++\n tests/Feature/Mcp/GetMeToolFeatureTest.php | 140 +++++++++++++++++++++++++++++++++++++++++++++++\n tests/Feature/Mcp/ListCallsToolFeatureTest.php | 2 +-\n tests/Feature/Mcp/McpTestHelpersTrait.php | 19 ++++++-\n tests/Unit/Component/ES/ChunkSizeTest.php | 50 +++++++++++++++++\n tests/Unit/Component/ES/Processor/DTOs/SelectionListTest.php | 27 +++++++---\n tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 39 ++++++++------\n tests/Unit/Component/MeetingBot/Service/ParticipantMatcherTest.php | 68 ++++++++++++++++++++++-\n tests/Unit/Exceptions/RateLimitExceptionTest.php | 56 +++++++++++++++++++\n tests/Unit/Jobs/Crm/MatchActivityCrmDataTest.php | 8 +--\n tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++\n tests/Unit/Services/Activity/HubSpot/ServiceTest.php | 109 +++++++++++++++++++++++++++++++++++++\n tests/Unit/Services/Crm/Hubspot/ClientTest.php | 250 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n tests/Unit/Services/Crm/Hubspot/Pagination/HubspotPaginationServiceTest.php | 283 +++++++++++++++++++++---------------------------------------------------------------------------\n 37 files changed, 1587 insertions(+), 344 deletions(-)\n create mode 100644 app/Component/ES/ChunkSize.php\n create mode 100644 app/Jobs/Middleware/HandleHubspotRateLimit.php\n create mode 100644 app/Mcp/Tools/GetMeTool.php\n create mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.php\n create mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.php\n create mode 100644 tests/Unit/Component/ES/ChunkSizeTest.php\n create mode 100644 tests/Unit/Exceptions/RateLimitExceptionTest.php\n create mode 100644 tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull\nAlready up to date.\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20676-delete-report-related-objects\nSwitched to a new branch 'JY-20676-delete-report-related-objects'\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20676-delete-report-related-objects) $ csfix\ndocker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff \nPHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.\nPHP runtime: 8.3.30\nRunning analysis on 7 cores with 10 files per process.\nParallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!\nLoaded config default from \".php-cs-fixer.dist.php\".\n 4781/5690 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░] 84%","depth":4,"on_screen":true,"value":"Last login: Mon May 18 09:17:28 on ttys007\n\nPoetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parents\n\nPoetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parents\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ co master\nerror: Your local changes to the following files would be overwritten by checkout:\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tPIPEDRIVE_V2_MIGRATION_TICKETS.md\nPlease commit your changes or stash them before you switch branches.\nAborting\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ git pull\nremote: Enumerating objects: 1047, done.\nremote: Counting objects: 100% (832/832), done.\nremote: Compressing objects: 100% (298/298), done.\nremote: Total 1047 (delta 634), reused 596 (delta 534), pack-reused 215 (from 3)\nReceiving objects: 100% (1047/1047), 353.16 KiB | 1.56 MiB/s, done.\nResolving deltas: 100% (687/687), completed with 107 local objects.\nFrom github.com:jiminny/app\n 907c54896c..34656c53ed pipedrive-sdk-poc -> origin/pipedrive-sdk-poc\n 03325ec50f..4e7078fd8b JY-18091-upgrade-to-php-8-5 -> origin/JY-18091-upgrade-to-php-8-5\n e7d231e163..bc6a3fce6b JY-20725-handle-HS-search-rate-limit -> origin/JY-20725-handle-HS-search-rate-limit\n * [new branch] JY-20749-user-can-view-recorded-meetings -> origin/JY-20749-user-can-view-recorded-meetings\n 98ca281a04..e0351be069 JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue\n 569abb5149..3906a9238a JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details -> origin/JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details\n ad6c2a86e8..50eb6afba9 JY-20846-mcp-enable-the-ai-to-know-details-about-the-user -> origin/JY-20846-mcp-enable-the-ai-to-know-details-about-the-user\n * [new branch] JY-20893-chunk-control-per-update-target -> origin/JY-20893-chunk-control-per-update-target\n 31c62924a5..cb4ebf0c36 master -> origin/master\nUpdating 907c54896c..34656c53ed\nFast-forward\n PIPEDRIVE_V2_MIGRATION_TICKETS.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 52 insertions(+)\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ co master\nM\u0000\u0000\u0000\u0000\u0000\u0000\t.env.local\nM\u0000\u0000\u0000\u0000\u0000\u0000\tconfig/logging.php\nSwitched to branch 'master'\nYour branch is behind 'origin/master' by 31 commits, and can be fast-forwarded.\n (use \"git pull\" to update your local branch)\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull\nUpdating 31c62924a5..cb4ebf0c36\nFast-forward\n app/Component/ES/Processor/Traits/SelectEntityListTrait.php | 20 ------\n app/Services/Calendar/CalendarActivityService.php | 46 +++++++++++++\n app/Services/Calendar/Command/MapActivityData.php | 106 +++-------------------------\n docs/mcp/explorer/explorer.html | 104 +++++++++++++++++++++++++---\n docs/mcp/explorer/explorer.template.html | 102 ++++++++++++++++++++++++---\n docs/mcp/tools-list.json | 373 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------\n docs/mcp/tools.md | 117 +++++++++++++++++++++++--------\n tests/Unit/Component/ES/AsyncUpdateElasticSearchTest.php | 16 +----\n tests/Unit/Component/ES/Listeners/UpdateMultipleTargetsListenerTest.php | 10 ---\n tests/Unit/Component/ES/Listeners/UpdateSingleTargetListenerTest.php | 6 --\n tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 9 ---\n tests/Unit/Component/ES/Processor/Traits/SelectEntityListTraitTest.php | 15 ++--\n tests/Unit/Component/ES/UpdateProcessManagerTest.php | 2 -\n tests/Unit/Services/Calendar/CalendarActivityServiceTest.php | 150 ++++++++++++++++++++++++++++++++++++++--\n tests/Unit/Services/Calendar/Command/MapActivityDataTest.php | 78 ++-------------------\n 15 files changed, 832 insertions(+), 322 deletions(-)\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20613-allow-owner-role-on-team-setup\nSwitched to a new branch 'JY-20613-allow-owner-role-on-team-setup'\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ csfix\ndocker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff \nPHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.\nPHP runtime: 8.3.30\nRunning analysis on 7 cores with 10 files per process.\nParallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!\nLoaded config default from \".php-cs-fixer.dist.php\".\n 5682/5682 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%\n\n\nFixed 0 of 5682 files in 56.978 seconds, 67.00 MB memory used\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ ;xd\ndocker exec -it docker_lamp_1 bash -c \"mv /usr/local/etc/php/conf.d/xdebug.ini ~/xdebug.ini\"\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\ndocker exec -it docker_lamp_1 supervisorctl restart all\njiminny-worker-processing-2:jiminny-worker-processing-2_00: stopped\njiminny-worker-processing-3:jiminny-worker-processing-3_00: stopped\njiminny-worker-processing-4:jiminny-worker-processing-4_00: stopped\njiminny-worker-processing-5:jiminny-worker-processing-5_00: stopped\njiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00: stopped\nworker-analytics:worker-analytics_00: stopped\nworker-crm-update:worker-crm-update_00: stopped\nworker-download:worker-download_00: stopped\nworker-nudges:worker-nudges_00: stopped\nartisan-schedule:artisan-schedule_00: stopped\nworker-emails:worker-emails_00: stopped\nworker-calendar:worker-calendar_00: stopped\nworker:worker_00: stopped\nworker-conferences:worker-conferences_00: stopped\nworker-crm-sync:worker-crm-sync_00: stopped\njiminny-worker-processing-1:jiminny-worker-processing-1_00: stopped\nworker-audio:worker-audio_00: stopped\nworker-es-update:worker-es-update_00: stopped\nartisan-schedule:artisan-schedule_00: started\njiminny-worker-processing-1:jiminny-worker-processing-1_00: started\njiminny-worker-processing-2:jiminny-worker-processing-2_00: started\njiminny-worker-processing-3:jiminny-worker-processing-3_00: started\njiminny-worker-processing-4:jiminny-worker-processing-4_00: started\njiminny-worker-processing-5:jiminny-worker-processing-5_00: started\njiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00: started\nworker:worker_00: started\nworker-analytics:worker-analytics_00: started\nworker-audio:worker-audio_00: started\nworker-calendar:worker-calendar_00: started\nworker-conferences:worker-conferences_00: started\nworker-crm-sync:worker-crm-sync_00: started\nworker-crm-update:worker-crm-update_00: started\nworker-download:worker-download_00: started\nworker-emails:worker-emails_00: started\nworker-es-update:worker-es-update_00: started\nworker-nudges:worker-nudges_00: started\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\ndocker exec -it docker_lamp_1 php -v\nPHP 8.3.30 (cli) (built: Mar 16 2026 22:32:32) (NTS)\nCopyright (c) The PHP Group\nZend Engine v4.3.30, Copyright (c) Zend Technologies\n with Zend OPcache v8.3.30, Copyright (c), by Zend Technologies\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ csfix\ndocker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff \nPHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.\nPHP runtime: 8.3.30\nRunning analysis on 7 cores with 10 files per process.\nParallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!\nLoaded config default from \".php-cs-fixer.dist.php\".\n 5682/5682 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%\n\n\nFixed 0 of 5682 files in 49.910 seconds, 60.00 MB memory used\n\nWhat's next:\n Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1\n Learn more at https://docs.docker.com/go/debug-cli/\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git status\nOn branch JY-20613-allow-owner-role-on-team-setup\nYour branch is ahead of 'origin/JY-20613-allow-owner-role-on-team-setup' by 1 commit.\n (use \"git push\" to publish your local commits)\n\nChanges not staged for commit:\n (use \"git add <file>...\" to update what will be committed)\n (use \"git restore <file>...\" to discard changes in working directory)\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: .env.local\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: config/logging.php\n\nUntracked files:\n (use \"git add <file>...\" to include in what will be committed)\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\t.env.nikilocal\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\t.env.other\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tWEBHOOK_FILTERING_IMPLEMENTATION.md\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Console/Commands/Crm/Hubspot/SimulateWebhooksCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Console/Commands/Reports/CreateMockAskJiminnyReportResultCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tids.txt\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tpublic/favicon.ico\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\traw_sql_query.sql\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ttests/Unit/Policies/CanAccessAiReportsTest.php\n\nno changes added to commit (use \"git add\" and/or \"git commit -a\")\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git pull\nremote: Enumerating objects: 248, done.\nremote: Counting objects: 100% (128/128), done.\nremote: Compressing objects: 100% (23/23), done.\nremote: Total 59 (delta 43), reused 44 (delta 33), pack-reused 0 (from 0)\nUnpacking objects: 100% (59/59), 10.48 KiB | 228.00 KiB/s, done.\nFrom github.com:jiminny/app\n b7df560451..190239dfd4 JY-20613-allow-owner-role-on-team-setup -> origin/JY-20613-allow-owner-role-on-team-setup\n e0351be069..d94a285ae7 JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue\n * [new branch] JY-20920-fix-participant-matcher -> origin/JY-20920-fix-participant-matcher\n cb4ebf0c36..90bca4e4b2 master -> origin/master\nMerge made by the 'ort' strategy.\n app/Component/ES/ChunkSize.php | 54 +++++++++++++++++++++++++++\n app/Component/ES/Processor/DTOs/SelectionList.php | 4 +-\n app/Component/ES/Processor/TargetEntitiesSelector.php | 19 ++++++----\n app/Http/Middleware/McpTierMiddleware.php | 27 +++-----------\n app/Mcp/Servers/JiminnyServer.php | 2 +\n app/Mcp/Tools/GetMeTool.php | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n app/Models/Feature/FeatureEnum.php | 1 +\n database/migrations/2026_05_13_124153_create_mcp_feature_flag.php | 25 +++++++++++++\n front-end/src/components/Settings/Kiosk/modals/EditTeamModal/EditTeamModal.vue | 52 ++++++++++++++++++--------\n front-end/src/components/Settings/Kiosk/modals/EditTeamModal/__tests__/EditTeamModal.spec.js | 14 +++++++\n tests/Feature/Mcp/GetMeToolFeatureTest.php | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n tests/Feature/Mcp/ListCallsToolFeatureTest.php | 2 +-\n tests/Feature/Mcp/McpTestHelpersTrait.php | 19 +++++++++-\n tests/Unit/Component/ES/ChunkSizeTest.php | 50 +++++++++++++++++++++++++\n tests/Unit/Component/ES/Processor/DTOs/SelectionListTest.php | 27 ++++++++++----\n tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 39 +++++++++++---------\n 16 files changed, 557 insertions(+), 75 deletions(-)\n create mode 100644 app/Component/ES/ChunkSize.php\n create mode 100644 app/Mcp/Tools/GetMeTool.php\n create mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.php\n create mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.php\n create mode 100644 tests/Unit/Component/ES/ChunkSizeTest.php\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git push\nEnumerating objects: 40, done.\nCounting objects: 100% (34/34), done.\nDelta compression using up to 8 threads\nCompressing objects: 100% (18/18), done.\nWriting objects: 100% (18/18), 1.58 KiB | 1.58 MiB/s, done.\nTotal 18 (delta 15), reused 0 (delta 0), pack-reused 0\nremote: Resolving deltas: 100% (15/15), completed with 13 local objects.\nTo github.com:jiminny/app.git\n 190239dfd4..ec1b261264 JY-20613-allow-owner-role-on-team-setup -> JY-20613-allow-owner-role-on-team-setup\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ gbr\n* JY-20613-allow-owner-role-on-team-setup\n pipedrive-sdk-poc\n master\n JY-20903-update_activity-stage-on-opportunity-change\n JY-20904-fix-update-es-on-activity-command\n JY-20891-improve-sms-text-relays\n JY-20725-handle-HS-search-rate-limit\n JY-20818-move-AJ-reports-to-separated-datadog-metric\n JY-20773-fix-automated-reports-user-pilot-tracking\n JY-20157-AJ-report-not-send-notification\n JY-20508-notify-before-AJ-report-expiration\n JY-20372-ai-reports-promotion-pages\n JY-20352-sync-opportunities-without-a-local-owner-user-id-is-null\n JY-20738-debug-AJ-tracking-UP\n a\n JY-18909-automated-reports-ask-jiminny\n JY-20692-fix-integration-app-token-auth-response-change\n JY-20553-debug-crm-sync-delays\n JY-20698-fix-SF-activity-types-on-new-playbook\n JY-20543-AJ-report-tracking\n JY-20384-handle-auto-sync-with-no-access-to-event-type\n JY-20458-ask-jiminny-user-definitions\n JY-19666-fix-import-contacts-account-association\n JY-19666-HS-import-contacts-and-accounts-batch-job\n JY-20458-Ask-Jiminny-Reports\n JY-20200-batch-update-CRM-objects-Salesforce\n JY-19666-HS-webhooks-add-contact-and-company\n JY-20348-trigger-setup-DI-layout-on-team-creation\n JY-20326-refactor-info-message-in-command\n JY-20317-fix-auto-log-delay-issue-on-all-channels-disabled\n JY-20312-remove-on-update-change-last-synced-at-crm-configurations\n JY-20306-SF-skip-auto-sync-for-task-based-playbook\n JY-20192-remove-deleted-team-from-saved-search-filters\n JY-20197-import-opportunity-batch-job\n JY-20293-enable-status-field-for-pipedrive-deals\n JY-20191-remove-commands-interactive-prompts\n JY-20118-change-default-sync-strategy\n JY-20183-add-cache-on-auto-log-delay\n JY-20197-add-import-opportunity-batch-job\n 20118-hs-opportunity-make-webhook-strategy-default\n JY-20118-make-default-hs-opportunity-sync-strategy-webhook-based\n JY-20196-handle-opportunity-without-note\n JY-20118-improve-opportunity-import\n JY-20189-handle-activity-search-on-deleted-groups\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ co JY-20725-handle-HS-search-rate-limit\nM\u0000\u0000\u0000\u0000\u0000\u0000\t.env.local\nM\u0000\u0000\u0000\u0000\u0000\u0000\tconfig/logging.php\nSwitched to branch 'JY-20725-handle-HS-search-rate-limit'\nYour branch is behind 'origin/JY-20725-handle-HS-search-rate-limit' by 439 commits, and can be fast-forwarded.\n (use \"git pull\" to update your local branch)\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ git pull\nUpdating 0f3e438941..bc6a3fce6b\nFast-forward\n .gitignore | 3 +-\n .windsurfrules | 168 ++---\n CLAUDE.md | 1 +\n app/Component/ActivityAnalytics/Service/CalculateTalkTimeOffsetsFromTranscription.php | 24 +-\n app/Component/AiActivityType/Services/AiActivityTypeEligibilityChecker.php | 28 +-\n app/Component/AiAutomation/Actions/PrepareUpdateDtoAction.php | 32 +-\n app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.php | 47 ++\n app/Component/AiAutomation/TestCrmAiPromptService.php | 14 +\n app/Component/AiCallScoring/Services/AiCallScoringEligibilityChecker.php | 9 +\n app/Component/ES/ElasticSearchDocumentPartialUpdater.php | 13 +-\n app/Component/ES/ElasticSearchWorkerManager.php | 86 ---\n app/Component/ES/Processor/Actions/LoadDocumentsAction.php | 80 +--\n app/Component/ES/Processor/EntityQueryBuilder.php | 12 +-\n app/Component/ES/Processor/TargetEntitiesSelector.php | 2 +-\n app/Component/ES/Processor/Traits/SkipActivityTrait.php | 25 -\n app/Component/ES/Repositories/EsResetActivityRepository.php | 11 +-\n app/Component/ES/Worker/ActivityWorker.php | 73 --\n app/Component/ES/Worker/EntityWorker.php | 44 --\n app/Component/ES/Worker/WorkerAmount.php | 60 --\n app/Component/ES/Worker/WorkerInterface.php | 15 -\n app/Component/ElasticSearch/Contract/Searchable.php | 4 +\n app/Component/Encoding/Job/AnalyzeTrackChannelsJob.php | 20 +-\n app/Component/Encoding/Service/GenerateSpeechFromSilenceService.php | 85 ++-\n app/Component/FFMpeg/Services/GetSpeechIntervalsService.php | 18 +-\n app/Component/LanguageDetection/Services/FindSpeechTimeService.php | 22 +-\n app/Component/Nudge/Job/ProcessOrganisationImmediateNudgesJob.php | 218 +++++-\n app/Component/ParagraphBreaker/Services/TranscriptionParagraphsService.php | 4 +\n app/Component/ParticipantSpeech/Services/ParticipantSpeechesCreator.php | 33 +\n app/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleter.php | 15 +\n app/Component/ParticipantSpeech/Services/ParticipantSpeechesProvider.php | 51 +-\n app/Component/ParticipantSpeech/Services/ParticipantSpeechesUploader.php | 36 +\n app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.php | 11 +\n app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/NoAssemblyIdException.php | 11 +\n app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/SuccessfulResponse.php | 6 +\n app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNotCorrectFormatException.php | 11 +\n app/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeechesService.php | 23 +-\n app/Component/Transcription/Diarization/Source/MeetingBotSource.php | 16 +-\n app/Component/Transcription/TranscriptionProcessor/TranscriptionProcessor.php | 3 +\n app/Console/Commands/Activities/ActivityHardDeleteCommand.php | 4 +-\n app/Console/Commands/Activities/Copy.php | 2 +\n app/Console/Commands/Activities/SetupIntegration/TwilioSetS3RecordingCredentialsCommand.php | 119 ++++\n app/Console/Commands/Activities/UpdateActivityElasticSearchDocumentCommand.php | 10 +-\n app/Console/Commands/Crm/BackfillOpportunityUserFromAccountCommand.php | 126 ++++\n app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.php | 19 -\n app/Console/Commands/Elasticsearch/AsyncUpdateEsEntities.php | 50 +-\n app/Console/Commands/Elasticsearch/ResetAsyncElasticSearchCommand.php | 30 +-\n app/Console/Commands/GeckoExport/GeckoExportParticipantSpeechesCommand.php | 14 +-\n app/Console/Commands/IssueMcpTokenCommand.php | 84 +++\n app/Console/Commands/JiminnyDebugCommand.php | 7 +-\n app/Console/Commands/Tracks/CleanupActivityTracksCommand.php | 2 +-\n app/Console/Kernel.php | 6 +-\n app/Contracts/Services/Calendar/CalendarTrait.php | 80 ++-\n app/Events/AutomatedReports/AutomatedReportGenerated.php | 3 +\n app/Http/Controllers/API/AiCallScoring/AiScorecardController.php | 7 +-\n app/Http/Controllers/API/TeamAiAutomationController.php | 8 +\n app/Http/Controllers/CustomerApi/CustomerApiController.php | 4 +-\n app/Http/Controllers/Kiosk/ActivityController.php | 58 +-\n app/Http/Controllers/Settings/PlaybookController.php | 15 +-\n app/Http/Kernel.php | 23 +\n app/Http/Middleware/McpAuditMiddleware.php | 156 ++++\n app/Http/Middleware/McpTierMiddleware.php | 54 ++\n app/Http/Requests/API/V2/ZapierUploadActivityRequest.php | 28 +-\n app/Jobs/Activity/Import/ImportTwilioVideoSpeechesJob.php | 25 +-\n app/Jobs/Activity/Import/IsActivityReadyForProcessingJob.php | 10 +-\n app/Jobs/Calendar/SetupCalendarSync.php | 21 +-\n app/Jobs/ImportRemoteTrackJob.php | 96 ++-\n app/Jobs/Mailbox/EmailTextRelay.php | 15 +-\n app/Mcp/Contracts/McpCallRepositoryInterface.php | 30 +\n app/Mcp/DTO/ListCallsFilters.php | 29 +\n app/Mcp/Errors/McpError.php | 123 ++++\n app/Mcp/Repositories/McpActivityHydrator.php | 145 ++++\n app/Mcp/Repositories/McpCallRepository.php | 84 +++\n app/Mcp/Repositories/McpElasticCallRepository.php | 171 +++++\n app/Mcp/Servers/JiminnyServer.php | 38 +\n app/Mcp/Tools/ListCallsTool.php | 205 ++++++\n app/Models/Activity.php | 10 +-\n app/Models/Activity/Transcription.php | 17 +-\n app/Models/ElasticSearch/OpportunityElasticSearchTrait.php | 5 +\n app/Models/Participant.php | 1 +\n app/Providers/AppServiceProvider.php | 22 +\n app/Repositories/Crm/ContactRepository.php | 69 +-\n app/Repositories/ParticipantSpeechRepository.php | 13 +-\n app/Services/Activity/ParticipantsService.php | 19 +-\n app/Services/Activity/Twilio/S3RecordingCredentialsService.php | 82 +++\n app/Services/ActivityService.php | 21 +-\n app/Services/Calendar/CalendarActivityService.php | 46 ++\n app/Services/Calendar/Command/ImportParticipants.php | 1 +\n app/Services/Calendar/Command/MapActivityData.php | 106 +--\n app/Services/Calendar/GoogleCalendarService.php | 12 +-\n app/Services/Crm/Close/Processor/OpportunityProcessor.php | 2 +-\n app/Services/Crm/Close/Service.php | 22 +-\n app/Services/Crm/Copper/Service.php | 12 +-\n app/Services/Crm/Hubspot/Service.php | 154 +++-\n app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php | 88 ++-\n app/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTrait.php | 22 +-\n app/Services/Crm/Pipedrive/Service.php | 17 +-\n app/Services/Crm/Salesforce/Service.php | 42 +-\n app/Services/Mail/Office/EmailApiClient.php | 129 +---\n app/Services/RecallAI/Commands/ScheduleBotCommand.php | 39 +-\n app/Services/RecallAI/RecallAIService.php | 22 +-\n composer.json | 3 +-\n composer.lock | 87 ++-\n config/mcp.php | 23 +\n database/migrations/2026_04_30_120000_create_mcp_audit_log_table.php | 36 +\n docs/mcp/explorer/explorer.html | 697 ++++++++++++++++++\n docs/mcp/explorer/explorer.template.html | 697 ++++++++++++++++++\n docs/mcp/explorer/generate.js | 215 ++++++\n docs/mcp/explorer/tool-explorer-meta.json | 11 +\n docs/mcp/tools-list.json | 2536 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n docs/mcp/tools.md | 621 ++++++++++++++++\n front-end/package.json | 4 +-\n front-end/src/components/Settings/OrgSettings/AiAutomation/CrmFilling/TemplateFieldForm.vue | 28 +-\n front-end/src/components/Settings/OrgSettings/Playbooks/AddEditPlaybook.vue | 10 +\n front-end/src/components/playback/comments/ActivityComment.less | 10 +-\n front-end/src/components/shared/PromptTester/PromptTester.vue | 12 +-\n front-end/src/components/shared/__tests__/PromptTester.spec.js | 35 +\n front-end/src/components/shared/modals/EntityPickerModal/__tests__/useEntitiesCache.spec.ts | 37 +\n front-end/src/components/shared/modals/EntityPickerModal/useEntitiesCache.ts | 9 +\n front-end/yarn.lock | 16 +-\n phpstan-baseline.neon | 50 --\n routes/api.php | 11 +\n sonar-project.properties | 91 ++-\n tests/Feature/Component/Nudge/ProcessOrganisationImmediateNudgesJobTest.php | 534 ++++++++++++++\n tests/Feature/Jobs/ImportRemoteTrackJobTest.php | 283 +++++++-\n tests/Feature/Mcp/IssueMcpTokenCommandTest.php | 53 ++\n tests/Feature/Mcp/ListCallsToolElasticFeatureTest.php | 155 ++++\n tests/Feature/Mcp/ListCallsToolFeatureTest.php | 352 ++++++++++\n tests/Feature/Mcp/McpTestHelpersTrait.php | 77 ++\n tests/Feature/Services/Team/TeamDeleteHandlers/Retention/RetentionRepositoryHandlerTest.php | 1 +\n tests/Stubs/SentryStub.php | 18 +\n tests/Unit/Component/ActivityAnalytics/Service/CalculateTalkTimeOffsetFromTranscriptionTest.php | 28 +-\n tests/Unit/Component/AiActivityType/Services/AiActivityTypeEligibilityCheckerTest.php | 103 ++-\n tests/Unit/Component/AiAutomation/Actions/PrepareUpdateDtoActionTest.php | 91 +++\n tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheckerTest.php | 124 ++++\n tests/Unit/Component/AiAutomation/TestCrmAiPromptServiceTest.php | 67 +-\n tests/Unit/Component/AiCallScoring/Services/AiCallScoringEligibilityCheckerTest.php | 55 ++\n tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.php | 135 ----\n tests/Unit/Component/ES/Processor/Actions/LoadDocumentsActionTest.php | 220 ++++++\n tests/Unit/Component/ES/Processor/EntityQueryBuilderTest.php | 21 +-\n tests/Unit/Component/ES/Processor/Traits/SkipActivityTraitTest.php | 51 --\n tests/Unit/Component/ES/Worker/ActivityWorkerTest.php | 174 -----\n tests/Unit/Component/ES/Worker/EntityWorkerTest.php | 97 ---\n tests/Unit/Component/ES/Worker/WorkerAmountTest.php | 116 ---\n tests/Unit/Component/Encoding/Job/AnalyzeTrackChannelsJobTest.php | 52 +-\n tests/Unit/Component/Encoding/Service/GenerateSpeechFromSilenceServiceTest.php | 171 ++---\n tests/Unit/Component/FFMpeg/Services/GetSpeechIntervalsTest.php | 36 +-\n tests/Unit/Component/LanguageDetection/Services/FindSpeechTimeServiceTest.php | 20 +-\n tests/Unit/Component/MobileSettings/MobileSettingsControllerTest.php | 5 +-\n tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCreatorTest.php | 75 ++\n tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleterTest.php | 63 ++\n tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesProviderTest.php | 134 ++++\n tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesUploaderTest.php | 57 ++\n tests/Unit/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeechesServiceTest.php | 51 +-\n tests/Unit/Component/Transcription/Diarization/Source/MeetingBotSourceTest.php | 29 +-\n tests/Unit/Contracts/Services/Calendar/CalendarTraitTest.php | 58 +-\n tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.php | 159 +++++\n tests/Unit/Jobs/Activity/Import/ImportTwilioVideoSpeechesJobTest.php | 22 +-\n tests/Unit/Jobs/Activity/Import/IsActivityReadyForProcessingJobTest.php | 26 +-\n tests/Unit/Jobs/Calendar/SetupCalendarSyncTest.php | 25 -\n tests/Unit/Services/Activity/ParticipantsServiceTest.php | 12 +-\n tests/Unit/Services/Activity/Twilio/S3RecordingCredentialsServiceTest.php | 180 +++++\n tests/Unit/Services/ActivityServiceTest.php | 132 ++++\n tests/Unit/Services/Calendar/CalendarActivityServiceTest.php | 150 +++-\n tests/Unit/Services/Calendar/Command/ImportParticipantsTest.php | 6 +-\n tests/Unit/Services/Calendar/Command/MapActivityDataTest.php | 78 +-\n tests/Unit/Services/Calendar/GoogleCalendarServiceTest.php | 116 +++\n tests/Unit/Services/Crm/Close/ServiceTest.php | 165 +++++\n tests/Unit/Services/Crm/Hubspot/ServiceTest.php | 272 ++++++-\n tests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTest.php | 25 +-\n tests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTraitMatchActivitiesTest.php | 3 +-\n tests/Unit/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTraitOpportunitiesTest.php | 40 ++\n tests/Unit/Services/Crm/Pipedrive/ImportOpportunityMatchActivitiesTest.php | 2 +\n tests/Unit/Services/Crm/Salesforce/ServiceTest.php | 139 ++++\n tests/Unit/Services/Mail/Office/EmailApiClientTest.php | 195 ++---\n tests/Unit/Services/RecallAI/RecallAIServiceTest.php | 24 +-\n 175 files changed, 12562 insertions(+), 2162 deletions(-)\n create mode 120000 CLAUDE.md\n create mode 100644 app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.php\n delete mode 100644 app/Component/ES/ElasticSearchWorkerManager.php\n delete mode 100644 app/Component/ES/Processor/Traits/SkipActivityTrait.php\n delete mode 100644 app/Component/ES/Worker/ActivityWorker.php\n delete mode 100644 app/Component/ES/Worker/EntityWorker.php\n delete mode 100644 app/Component/ES/Worker/WorkerAmount.php\n delete mode 100644 app/Component/ES/Worker/WorkerInterface.php\n create mode 100644 app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.php\n create mode 100644 app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/NoAssemblyIdException.php\n create mode 100644 app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNotCorrectFormatException.php\n create mode 100644 app/Console/Commands/Activities/SetupIntegration/TwilioSetS3RecordingCredentialsCommand.php\n create mode 100644 app/Console/Commands/Crm/BackfillOpportunityUserFromAccountCommand.php\n delete mode 100644 app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.php\n create mode 100644 app/Console/Commands/IssueMcpTokenCommand.php\n create mode 100644 app/Http/Middleware/McpAuditMiddleware.php\n create mode 100644 app/Http/Middleware/McpTierMiddleware.php\n create mode 100644 app/Mcp/Contracts/McpCallRepositoryInterface.php\n create mode 100644 app/Mcp/DTO/ListCallsFilters.php\n create mode 100644 app/Mcp/Errors/McpError.php\n create mode 100644 app/Mcp/Repositories/McpActivityHydrator.php\n create mode 100644 app/Mcp/Repositories/McpCallRepository.php\n create mode 100644 app/Mcp/Repositories/McpElasticCallRepository.php\n create mode 100644 app/Mcp/Servers/JiminnyServer.php\n create mode 100644 app/Mcp/Tools/ListCallsTool.php\n create mode 100644 app/Services/Activity/Twilio/S3RecordingCredentialsService.php\n create mode 100644 config/mcp.php\n create mode 100644 database/migrations/2026_04_30_120000_create_mcp_audit_log_table.php\n create mode 100644 docs/mcp/explorer/explorer.html\n create mode 100644 docs/mcp/explorer/explorer.template.html\n create mode 100644 docs/mcp/explorer/generate.js\n create mode 100644 docs/mcp/explorer/tool-explorer-meta.json\n create mode 100644 docs/mcp/tools-list.json\n create mode 100644 docs/mcp/tools.md\n create mode 100644 front-end/src/components/shared/modals/EntityPickerModal/__tests__/useEntitiesCache.spec.ts\n create mode 100644 tests/Feature/Component/Nudge/ProcessOrganisationImmediateNudgesJobTest.php\n create mode 100644 tests/Feature/Mcp/IssueMcpTokenCommandTest.php\n create mode 100644 tests/Feature/Mcp/ListCallsToolElasticFeatureTest.php\n create mode 100644 tests/Feature/Mcp/ListCallsToolFeatureTest.php\n create mode 100644 tests/Feature/Mcp/McpTestHelpersTrait.php\n create mode 100644 tests/Stubs/SentryStub.php\n create mode 100644 tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheckerTest.php\n delete mode 100644 tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.php\n create mode 100644 tests/Unit/Component/ES/Processor/Actions/LoadDocumentsActionTest.php\n delete mode 100644 tests/Unit/Component/ES/Processor/Traits/SkipActivityTraitTest.php\n delete mode 100644 tests/Unit/Component/ES/Worker/ActivityWorkerTest.php\n delete mode 100644 tests/Unit/Component/ES/Worker/EntityWorkerTest.php\n delete mode 100644 tests/Unit/Component/ES/Worker/WorkerAmountTest.php\n create mode 100644 tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCreatorTest.php\n create mode 100644 tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.php\n create mode 100644 tests/Unit/Services/Activity/Twilio/S3RecordingCredentialsServiceTest.php\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ git status\nOn branch master\nYour branch is behind 'origin/master' by 114 commits, and can be fast-forwarded.\n (use \"git pull\" to update your local branch)\n\nChanges not staged for commit:\n (use \"git add <file>...\" to update what will be committed)\n (use \"git restore <file>...\" to discard changes in working directory)\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: .env.local\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Component/SCIM/Constants.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Component/SCIM/ScimProvisioning.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Component/Twilio/Conference/ConferenceManager/SoftPhoneManager.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Console/Commands/JiminnyDebugCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/DTO/SCIM/AAD/Request/CoreUserRequest.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/DTO/SCIM/AAD/Response/CoreUser.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: app/Services/Telephony/TextMessagingService.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tmodified: config/logging.php\n\nUntracked files:\n (use \"git add <file>...\" to include in what will be committed)\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\t.env.nikilocal\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\t.env.other\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tWEBHOOK_FILTERING_IMPLEMENTATION.md\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Component/SCIM/Mutators/Attributes/User/RoleAttr.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Console/Commands/Crm/Hubspot/SimulateWebhooksCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Console/Commands/Reports/CreateMockAskJiminnyReportResultCommand.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tapp/Rules/ListenerRoleCannotHaveAdminOrManagerPermissionRule.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tids.txt\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\tpublic/favicon.ico\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\traw_sql_query.sql\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ttests/Unit/Component/SCIM/Mutators/Attributes/User/RoleAttrTest.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ttests/Unit/Policies/CanAccessAiReportsTest.php\n\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ttests/Unit/Rules/ListenerRoleCannotHaveAdminOrManagerPermissionRuleTest.php\n\nno changes added to commit (use \"git add\" and/or \"git commit -a\")\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull\nremote: Enumerating objects: 306, done.\nremote: Counting objects: 100% (299/299), done.\nremote: Compressing objects: 100% (183/183), done.\nremote: Total 306 (delta 213), reused 171 (delta 116), pack-reused 7 (from 1)\nReceiving objects: 100% (306/306), 80.12 KiB | 1000.00 KiB/s, done.\nResolving deltas: 100% (213/213), completed with 53 local objects.\nFrom github.com:jiminny/app\n 90bca4e4b2..5604af40cf master -> origin/master\n 4e7078fd8b..0b8343d179 JY-18091-upgrade-to-php-8-5 -> origin/JY-18091-upgrade-to-php-8-5\n 098eeaa087..d5a447e492 JY-20613-allow-owner-role-on-team-setup -> origin/JY-20613-allow-owner-role-on-team-setup\n c3a76ace91..af65249d0f JY-20749-user-can-view-recorded-meetings -> origin/JY-20749-user-can-view-recorded-meetings\n d94a285ae7..7ce96cb5fe JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue\n * [new branch] JY-20842-remove-partial-updater -> origin/JY-20842-remove-partial-updater\n * [new branch] JY-20920-fix-participant-flip -> origin/JY-20920-fix-participant-flip\n * [new branch] secfix/npm-20260519 -> origin/secfix/npm-20260519\nUpdating cb4ebf0c36..5604af40cf\nFast-forward\n app/Component/ES/ChunkSize.php | 54 +++++++++++++++++++\n app/Component/ES/Processor/DTOs/SelectionList.php | 4 +-\n app/Component/ES/Processor/TargetEntitiesSelector.php | 19 ++++---\n app/Component/MeetingBot/Service/ParticipantMatcher.php | 46 ++++++++++++----\n app/Exceptions/RateLimitException.php | 19 ++++++-\n app/Http/Middleware/McpTierMiddleware.php | 27 ++--------\n app/Jobs/Crm/MatchActivityCrmData.php | 47 ++++++++++++----\n app/Jobs/Middleware/HandleHubspotRateLimit.php | 42 +++++++++++++++\n app/Mcp/Servers/JiminnyServer.php | 2 +\n app/Mcp/Tools/GetMeTool.php | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++\n app/Models/Feature/FeatureEnum.php | 1 +\n app/Services/Activity/HubSpot/ProviderResolver.php | 4 +-\n app/Services/Activity/HubSpot/ProviderResolverInterface.php | 2 +-\n app/Services/Activity/HubSpot/Providers/Provider.php | 2 +-\n app/Services/Activity/HubSpot/Providers/ProviderKixie.php | 2 +-\n app/Services/Activity/HubSpot/Providers/ProviderOrum.php | 2 +-\n app/Services/Activity/HubSpot/Providers/ProviderTwilio.php | 2 +-\n app/Services/Activity/HubSpot/Providers/ProviderTwilioFlex.php | 5 +-\n app/Services/Activity/HubSpot/Service.php | 97 +++++++++++++++++++++++++++------\n app/Services/Crm/Hubspot/Client.php | 132 +++++++++++++++++++++++++++++++++++++++++++++\n app/Services/Crm/Hubspot/HubspotClientInterface.php | 15 ++++++\n app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php | 21 ++++----\n app/Services/Crm/Hubspot/Pagination/PaginationState.php | 2 +-\n database/migrations/2026_05_13_124153_create_mcp_feature_flag.php | 25 +++++++++\n tests/Feature/Mcp/GetMeToolFeatureTest.php | 140 +++++++++++++++++++++++++++++++++++++++++++++++\n tests/Feature/Mcp/ListCallsToolFeatureTest.php | 2 +-\n tests/Feature/Mcp/McpTestHelpersTrait.php | 19 ++++++-\n tests/Unit/Component/ES/ChunkSizeTest.php | 50 +++++++++++++++++\n tests/Unit/Component/ES/Processor/DTOs/SelectionListTest.php | 27 +++++++---\n tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 39 ++++++++------\n tests/Unit/Component/MeetingBot/Service/ParticipantMatcherTest.php | 68 ++++++++++++++++++++++-\n tests/Unit/Exceptions/RateLimitExceptionTest.php | 56 +++++++++++++++++++\n tests/Unit/Jobs/Crm/MatchActivityCrmDataTest.php | 8 +--\n tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++\n tests/Unit/Services/Activity/HubSpot/ServiceTest.php | 109 +++++++++++++++++++++++++++++++++++++\n tests/Unit/Services/Crm/Hubspot/ClientTest.php | 250 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n tests/Unit/Services/Crm/Hubspot/Pagination/HubspotPaginationServiceTest.php | 283 +++++++++++++++++++++---------------------------------------------------------------------------\n 37 files changed, 1587 insertions(+), 344 deletions(-)\n create mode 100644 app/Component/ES/ChunkSize.php\n create mode 100644 app/Jobs/Middleware/HandleHubspotRateLimit.php\n create mode 100644 app/Mcp/Tools/GetMeTool.php\n create mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.php\n create mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.php\n create mode 100644 tests/Unit/Component/ES/ChunkSizeTest.php\n create mode 100644 tests/Unit/Exceptions/RateLimitExceptionTest.php\n create mode 100644 tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull\nAlready up to date.\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20676-delete-report-related-objects\nSwitched to a new branch 'JY-20676-delete-report-related-objects'\nlukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20676-delete-report-related-objects) $ csfix\ndocker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff \nPHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.\nPHP runtime: 8.3.30\nRunning analysis on 7 cores with 10 files per process.\nParallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!\nLoaded config default from \".php-cs-fixer.dist.php\".\n 4781/5690 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░] 84%","is_focused":true},{"role":"AXRadioButton","text":"DOCKER","depth":2,"bounds":{"left":0.27027926,"top":1.0,"width":0.094913565,"height":-0.042298436},"on_screen":true,"role_description":"radio button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close Tab","depth":3,"bounds":{"left":0.27227393,"top":1.0,"width":0.005319149,"height":-0.04549086},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"DEV (docker)","depth":2,"bounds":{"left":0.36519283,"top":1.0,"width":0.094913565,"height":-0.042298436},"on_screen":true,"role_description":"radio button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close Tab","depth":3,"bounds":{"left":0.3671875,"top":1.0,"width":0.005319149,"height":-0.04549086},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"APP (docker)","depth":2,"bounds":{"left":0.46010637,"top":1.0,"width":0.09474734,"height":-0.042298436},"on_screen":true,"role_description":"radio button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close Tab","depth":3,"bounds":{"left":0.46210107,"top":1.0,"width":0.005319149,"height":-0.04549086},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"screenpipe\"","depth":2,"bounds":{"left":0.55485374,"top":1.0,"width":0.09474734,"height":-0.042298436},"on_screen":true,"role_description":"radio button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close Tab","depth":3,"bounds":{"left":0.5568484,"top":1.0,"width":0.005319149,"height":-0.04549086},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"-zsh","depth":2,"bounds":{"left":0.64960104,"top":1.0,"width":0.09474734,"height":-0.042298436},"on_screen":true,"role_description":"radio button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close Tab","depth":3,"bounds":{"left":0.6515958,"top":1.0,"width":0.005319149,"height":-0.04549086},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"⌥⌘1","depth":1,"bounds":{"left":0.7307181,"top":1.0,"width":0.01861702,"height":-0.023144484},"on_screen":true,"automation_id":"_NS:8","role_description":"text"},{"role":"AXStaticText","text":"APP (docker)","depth":1,"bounds":{"left":0.49634308,"top":1.0,"width":0.029920213,"height":-0.02394259},"on_screen":true,"role_description":"text"}]...
|
-1544025323922658412
|
-1358120912881272616
|
idle
|
accessibility
|
NULL
|
Last login: Mon May 18 09:17:28 on ttys007
Poetry Last login: Mon May 18 09:17:28 on ttys007
Poetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parents
Poetry could not find a pyproject.toml file in /Users/lukas/jiminny/app or its parents
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ co master
error: Your local changes to the following files would be overwritten by checkout:
PIPEDRIVE_V2_MIGRATION_TICKETS.md
Please commit your changes or stash them before you switch branches.
Aborting
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ git pull
remote: Enumerating objects: 1047, done.
remote: Counting objects: 100% (832/832), done.
remote: Compressing objects: 100% (298/298), done.
remote: Total 1047 (delta 634), reused 596 (delta 534), pack-reused 215 (from 3)
Receiving objects: 100% (1047/1047), 353.16 KiB | 1.56 MiB/s, done.
Resolving deltas: 100% (687/687), completed with 107 local objects.
From github.com:jiminny/app
907c54896c..34656c53ed pipedrive-sdk-poc -> origin/pipedrive-sdk-poc
03325ec50f..4e7078fd8b JY-18091-upgrade-to-php-8-5 -> origin/JY-18091-upgrade-to-php-8-5
e7d231e163..bc6a3fce6b JY-20725-handle-HS-search-rate-limit -> origin/JY-20725-handle-HS-search-rate-limit
* [new branch] JY-20749-user-can-view-recorded-meetings -> origin/JY-20749-user-can-view-recorded-meetings
98ca281a04..e0351be069 JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue
569abb5149..3906a9238a JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details -> origin/JY-20835-mcp-enable-users-to-get-a-list-of-deals-and-their-details
ad6c2a86e8..50eb6afba9 JY-20846-mcp-enable-the-ai-to-know-details-about-the-user -> origin/JY-20846-mcp-enable-the-ai-to-know-details-about-the-user
* [new branch] JY-20893-chunk-control-per-update-target -> origin/JY-20893-chunk-control-per-update-target
31c62924a5..cb4ebf0c36 master -> origin/master
Updating 907c54896c..34656c53ed
Fast-forward
PIPEDRIVE_V2_MIGRATION_TICKETS.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 52 insertions(+)
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (pipedrive-sdk-poc) $ co master
M .env.local
M config/logging.php
Switched to branch 'master'
Your branch is behind 'origin/master' by 31 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull
Updating 31c62924a5..cb4ebf0c36
Fast-forward
app/Component/ES/Processor/Traits/SelectEntityListTrait.php | 20 ------
app/Services/Calendar/CalendarActivityService.php | 46 +++++++++++++
app/Services/Calendar/Command/MapActivityData.php | 106 +++-------------------------
docs/mcp/explorer/explorer.html | 104 +++++++++++++++++++++++++---
docs/mcp/explorer/explorer.template.html | 102 ++++++++++++++++++++++++---
docs/mcp/tools-list.json | 373 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
docs/mcp/tools.md | 117 +++++++++++++++++++++++--------
tests/Unit/Component/ES/AsyncUpdateElasticSearchTest.php | 16 +----
tests/Unit/Component/ES/Listeners/UpdateMultipleTargetsListenerTest.php | 10 ---
tests/Unit/Component/ES/Listeners/UpdateSingleTargetListenerTest.php | 6 --
tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 9 ---
tests/Unit/Component/ES/Processor/Traits/SelectEntityListTraitTest.php | 15 ++--
tests/Unit/Component/ES/UpdateProcessManagerTest.php | 2 -
tests/Unit/Services/Calendar/CalendarActivityServiceTest.php | 150 ++++++++++++++++++++++++++++++++++++++--
tests/Unit/Services/Calendar/Command/MapActivityDataTest.php | 78 ++-------------------
15 files changed, 832 insertions(+), 322 deletions(-)
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20613-allow-owner-role-on-team-setup
Switched to a new branch 'JY-20613-allow-owner-role-on-team-setup'
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ csfix
docker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff
PHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.
PHP runtime: 8.3.30
Running analysis on 7 cores with 10 files per process.
Parallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!
Loaded config default from ".php-cs-fixer.dist.php".
5682/5682 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
Fixed 0 of 5682 files in 56.978 seconds, 67.00 MB memory used
What's next:
Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1
Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ csfix
docker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff
PHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.
PHP runtime: 8.3.30
Running analysis on 7 cores with 10 files per process.
Parallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!
Loaded config default from ".php-cs-fixer.dist.php".
5682/5682 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
Fixed 0 of 5682 files in 49.910 seconds, 60.00 MB memory used
What's next:
Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug docker_lamp_1
Learn more at [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git pull
remote: Enumerating objects: 248, done.
remote: Counting objects: 100% (128/128), done.
remote: Compressing objects: 100% (23/23), done.
remote: Total 59 (delta 43), reused 44 (delta 33), pack-reused 0 (from 0)
Unpacking objects: 100% (59/59), 10.48 KiB | 228.00 KiB/s, done.
From github.com:jiminny/app
b7df560451..190239dfd4 JY-20613-allow-owner-role-on-team-setup -> origin/JY-20613-allow-owner-role-on-team-setup
e0351be069..d94a285ae7 JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue
* [new branch] JY-20920-fix-participant-matcher -> origin/JY-20920-fix-participant-matcher
cb4ebf0c36..90bca4e4b2 master -> origin/master
Merge made by the 'ort' strategy.
app/Component/ES/ChunkSize.php | 54 +++++++++++++++++++++++++++
app/Component/ES/Processor/DTOs/SelectionList.php | 4 +-
app/Component/ES/Processor/TargetEntitiesSelector.php | 19 ++++++----
app/Http/Middleware/McpTierMiddleware.php | 27 +++-----------
app/Mcp/Servers/JiminnyServer.php | 2 +
app/Mcp/Tools/GetMeTool.php | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
app/Models/Feature/FeatureEnum.php | 1 +
database/migrations/2026_05_13_124153_create_mcp_feature_flag.php | 25 +++++++++++++
front-end/src/components/Settings/Kiosk/modals/EditTeamModal/EditTeamModal.vue | 52 ++++++++++++++++++--------
front-end/src/components/Settings/Kiosk/modals/EditTeamModal/__tests__/EditTeamModal.spec.js | 14 +++++++
tests/Feature/Mcp/GetMeToolFeatureTest.php | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/Feature/Mcp/ListCallsToolFeatureTest.php | 2 +-
tests/Feature/Mcp/McpTestHelpersTrait.php | 19 +++++++++-
tests/Unit/Component/ES/ChunkSizeTest.php | 50 +++++++++++++++++++++++++
tests/Unit/Component/ES/Processor/DTOs/SelectionListTest.php | 27 ++++++++++----
tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 39 +++++++++++---------
16 files changed, 557 insertions(+), 75 deletions(-)
create mode 100644 app/Component/ES/ChunkSize.php
create mode 100644 app/Mcp/Tools/GetMeTool.php
create mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.php
create mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.php
create mode 100644 tests/Unit/Component/ES/ChunkSizeTest.php
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ git push
Enumerating objects: 40, done.
Counting objects: 100% (34/34), done.
Delta compression using up to 8 threads
Compressing objects: 100% (18/18), done.
Writing objects: 100% (18/18), 1.58 KiB | 1.58 MiB/s, done.
Total 18 (delta 15), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (15/15), completed with 13 local objects.
To github.com:jiminny/app.git
190239dfd4..ec1b261264 JY-20613-allow-owner-role-on-team-setup -> JY-20613-allow-owner-role-on-team-setup
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ gbr
* JY-20613-allow-owner-role-on-team-setup
pipedrive-sdk-poc
master
JY-20903-update_activity-stage-on-opportunity-change
JY-20904-fix-update-es-on-activity-command
JY-20891-improve-sms-text-relays
JY-20725-handle-HS-search-rate-limit
JY-20818-move-AJ-reports-to-separated-datadog-metric
JY-20773-fix-automated-reports-user-pilot-tracking
JY-20157-AJ-report-not-send-notification
JY-20508-notify-before-AJ-report-expiration
JY-20372-ai-reports-promotion-pages
JY-20352-sync-opportunities-without-a-local-owner-user-id-is-null
JY-20738-debug-AJ-tracking-UP
a
JY-18909-automated-reports-ask-jiminny
JY-20692-fix-integration-app-[API_KEY]
JY-20553-debug-crm-sync-delays
JY-20698-fix-SF-activity-types-on-new-playbook
JY-20543-AJ-report-tracking
JY-20384-handle-auto-sync-with-no-access-to-event-type
JY-20458-ask-jiminny-user-definitions
JY-19666-fix-import-contacts-account-association
JY-19666-HS-import-contacts-and-accounts-batch-job
JY-20458-Ask-Jiminny-Reports
JY-20200-batch-update-CRM-objects-Salesforce
JY-19666-HS-webhooks-add-contact-and-company
JY-20348-trigger-setup-DI-layout-on-team-creation
JY-20326-refactor-info-message-in-command
JY-20317-fix-auto-log-delay-issue-on-all-channels-disabled
JY-20312-remove-on-update-change-last-synced-at-crm-configurations
JY-20306-SF-skip-auto-sync-for-task-based-playbook
JY-20192-remove-deleted-team-from-saved-search-filters
JY-20197-import-opportunity-batch-job
JY-20293-enable-status-field-for-pipedrive-deals
JY-20191-remove-commands-interactive-prompts
JY-20118-change-default-sync-strategy
JY-20183-add-cache-on-auto-log-delay
JY-20197-add-import-opportunity-batch-job
20118-hs-opportunity-make-webhook-strategy-default
JY-20118-make-default-hs-opportunity-sync-strategy-webhook-based
JY-20196-handle-opportunity-without-note
JY-20118-improve-opportunity-import
JY-20189-handle-activity-search-on-deleted-groups
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20613-allow-owner-role-on-team-setup) $ co JY-20725-handle-HS-search-rate-limit
M .env.local
M config/logging.php
Switched to branch 'JY-20725-handle-HS-search-rate-limit'
Your branch is behind 'origin/JY-20725-handle-HS-search-rate-limit' by 439 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ git pull
Updating 0f3e438941..bc6a3fce6b
Fast-forward
.gitignore | 3 +-
.windsurfrules | 168 ++---
CLAUDE.md | 1 +
app/Component/ActivityAnalytics/Service/CalculateTalkTimeOffsetsFromTranscription.php | 24 +-
app/Component/AiActivityType/Services/AiActivityTypeEligibilityChecker.php | 28 +-
app/Component/AiAutomation/Actions/PrepareUpdateDtoAction.php | 32 +-
app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.php | 47 ++
app/Component/AiAutomation/TestCrmAiPromptService.php | 14 +
app/Component/AiCallScoring/Services/AiCallScoringEligibilityChecker.php | 9 +
app/Component/ES/ElasticSearchDocumentPartialUpdater.php | 13 +-
app/Component/ES/ElasticSearchWorkerManager.php | 86 ---
app/Component/ES/Processor/Actions/LoadDocumentsAction.php | 80 +--
app/Component/ES/Processor/EntityQueryBuilder.php | 12 +-
app/Component/ES/Processor/TargetEntitiesSelector.php | 2 +-
app/Component/ES/Processor/Traits/SkipActivityTrait.php | 25 -
app/Component/ES/Repositories/EsResetActivityRepository.php | 11 +-
app/Component/ES/Worker/ActivityWorker.php | 73 --
app/Component/ES/Worker/EntityWorker.php | 44 --
app/Component/ES/Worker/WorkerAmount.php | 60 --
app/Component/ES/Worker/WorkerInterface.php | 15 -
app/Component/ElasticSearch/Contract/Searchable.php | 4 +
app/Component/Encoding/Job/AnalyzeTrackChannelsJob.php | 20 +-
app/Component/Encoding/Service/GenerateSpeechFromSilenceService.php | 85 ++-
app/Component/FFMpeg/Services/GetSpeechIntervalsService.php | 18 +-
app/Component/LanguageDetection/Services/FindSpeechTimeService.php | 22 +-
app/Component/Nudge/Job/ProcessOrganisationImmediateNudgesJob.php | 218 +++++-
app/Component/ParagraphBreaker/Services/TranscriptionParagraphsService.php | 4 +
app/Component/ParticipantSpeech/Services/ParticipantSpeechesCreator.php | 33 +
app/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleter.php | 15 +
app/Component/ParticipantSpeech/Services/ParticipantSpeechesProvider.php | 51 +-
app/Component/ParticipantSpeech/Services/ParticipantSpeechesUploader.php | 36 +
app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.php | 11 +
app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/NoAssemblyIdException.php | 11 +
app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/SuccessfulResponse.php | 6 +
app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNotCorrectFormatException.php | 11 +
app/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeechesService.php | 23 +-
app/Component/Transcription/Diarization/Source/MeetingBotSource.php | 16 +-
app/Component/Transcription/TranscriptionProcessor/TranscriptionProcessor.php | 3 +
app/Console/Commands/Activities/ActivityHardDeleteCommand.php | 4 +-
app/Console/Commands/Activities/Copy.php | 2 +
app/Console/Commands/Activities/SetupIntegration/TwilioSetS3RecordingCredentialsCommand.php | 119 ++++
app/Console/Commands/Activities/UpdateActivityElasticSearchDocumentCommand.php | 10 +-
app/Console/Commands/Crm/BackfillOpportunityUserFromAccountCommand.php | 126 ++++
app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.php | 19 -
app/Console/Commands/Elasticsearch/AsyncUpdateEsEntities.php | 50 +-
app/Console/Commands/Elasticsearch/ResetAsyncElasticSearchCommand.php | 30 +-
app/Console/Commands/GeckoExport/GeckoExportParticipantSpeechesCommand.php | 14 +-
app/Console/Commands/IssueMcpTokenCommand.php | 84 +++
app/Console/Commands/JiminnyDebugCommand.php | 7 +-
app/Console/Commands/Tracks/CleanupActivityTracksCommand.php | 2 +-
app/Console/Kernel.php | 6 +-
app/Contracts/Services/Calendar/CalendarTrait.php | 80 ++-
app/Events/AutomatedReports/AutomatedReportGenerated.php | 3 +
app/Http/Controllers/API/AiCallScoring/AiScorecardController.php | 7 +-
app/Http/Controllers/API/TeamAiAutomationController.php | 8 +
app/Http/Controllers/CustomerApi/CustomerApiController.php | 4 +-
app/Http/Controllers/Kiosk/ActivityController.php | 58 +-
app/Http/Controllers/Settings/PlaybookController.php | 15 +-
app/Http/Kernel.php | 23 +
app/Http/Middleware/McpAuditMiddleware.php | 156 ++++
app/Http/Middleware/McpTierMiddleware.php | 54 ++
app/Http/Requests/API/V2/ZapierUploadActivityRequest.php | 28 +-
app/Jobs/Activity/Import/ImportTwilioVideoSpeechesJob.php | 25 +-
app/Jobs/Activity/Import/IsActivityReadyForProcessingJob.php | 10 +-
app/Jobs/Calendar/SetupCalendarSync.php | 21 +-
app/Jobs/ImportRemoteTrackJob.php | 96 ++-
app/Jobs/Mailbox/EmailTextRelay.php | 15 +-
app/Mcp/Contracts/McpCallRepositoryInterface.php | 30 +
app/Mcp/DTO/ListCallsFilters.php | 29 +
app/Mcp/Errors/McpError.php | 123 ++++
app/Mcp/Repositories/McpActivityHydrator.php | 145 ++++
app/Mcp/Repositories/McpCallRepository.php | 84 +++
app/Mcp/Repositories/McpElasticCallRepository.php | 171 +++++
app/Mcp/Servers/JiminnyServer.php | 38 +
app/Mcp/Tools/ListCallsTool.php | 205 ++++++
app/Models/Activity.php | 10 +-
app/Models/Activity/Transcription.php | 17 +-
app/Models/ElasticSearch/OpportunityElasticSearchTrait.php | 5 +
app/Models/Participant.php | 1 +
app/Providers/AppServiceProvider.php | 22 +
app/Repositories/Crm/ContactRepository.php | 69 +-
app/Repositories/ParticipantSpeechRepository.php | 13 +-
app/Services/Activity/ParticipantsService.php | 19 +-
app/Services/Activity/Twilio/S3RecordingCredentialsService.php | 82 +++
app/Services/ActivityService.php | 21 +-
app/Services/Calendar/CalendarActivityService.php | 46 ++
app/Services/Calendar/Command/ImportParticipants.php | 1 +
app/Services/Calendar/Command/MapActivityData.php | 106 +--
app/Services/Calendar/GoogleCalendarService.php | 12 +-
app/Services/Crm/Close/Processor/OpportunityProcessor.php | 2 +-
app/Services/Crm/Close/Service.php | 22 +-
app/Services/Crm/Copper/Service.php | 12 +-
app/Services/Crm/Hubspot/Service.php | 154 +++-
app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php | 88 ++-
app/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTrait.php | 22 +-
app/Services/Crm/Pipedrive/Service.php | 17 +-
app/Services/Crm/Salesforce/Service.php | 42 +-
app/Services/Mail/Office/EmailApiClient.php | 129 +---
app/Services/RecallAI/Commands/ScheduleBotCommand.php | 39 +-
app/Services/RecallAI/RecallAIService.php | 22 +-
composer.json | 3 +-
composer.lock | 87 ++-
config/mcp.php | 23 +
database/migrations/2026_04_30_120000_create_mcp_audit_log_table.php | 36 +
docs/mcp/explorer/explorer.html | 697 ++++++++++++++++++
docs/mcp/explorer/explorer.template.html | 697 ++++++++++++++++++
docs/mcp/explorer/generate.js | 215 ++++++
docs/mcp/explorer/tool-explorer-meta.json | 11 +
docs/mcp/tools-list.json | 2536 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
docs/mcp/tools.md | 621 ++++++++++++++++
front-end/package.json | 4 +-
front-end/src/components/Settings/OrgSettings/AiAutomation/CrmFilling/TemplateFieldForm.vue | 28 +-
front-end/src/components/Settings/OrgSettings/Playbooks/AddEditPlaybook.vue | 10 +
front-end/src/components/playback/comments/ActivityComment.less | 10 +-
front-end/src/components/shared/PromptTester/PromptTester.vue | 12 +-
front-end/src/components/shared/__tests__/PromptTester.spec.js | 35 +
front-end/src/components/shared/modals/EntityPickerModal/__tests__/useEntitiesCache.spec.ts | 37 +
front-end/src/components/shared/modals/EntityPickerModal/useEntitiesCache.ts | 9 +
front-end/yarn.lock | 16 +-
phpstan-baseline.neon | 50 --
routes/api.php | 11 +
sonar-project.properties | 91 ++-
tests/Feature/Component/Nudge/ProcessOrganisationImmediateNudgesJobTest.php | 534 ++++++++++++++
tests/Feature/Jobs/ImportRemoteTrackJobTest.php | 283 +++++++-
tests/Feature/Mcp/IssueMcpTokenCommandTest.php | 53 ++
tests/Feature/Mcp/ListCallsToolElasticFeatureTest.php | 155 ++++
tests/Feature/Mcp/ListCallsToolFeatureTest.php | 352 ++++++++++
tests/Feature/Mcp/McpTestHelpersTrait.php | 77 ++
tests/Feature/Services/Team/TeamDeleteHandlers/Retention/RetentionRepositoryHandlerTest.php | 1 +
tests/Stubs/SentryStub.php | 18 +
tests/Unit/Component/ActivityAnalytics/Service/CalculateTalkTimeOffsetFromTranscriptionTest.php | 28 +-
tests/Unit/Component/AiActivityType/Services/AiActivityTypeEligibilityCheckerTest.php | 103 ++-
tests/Unit/Component/AiAutomation/Actions/PrepareUpdateDtoActionTest.php | 91 +++
tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheckerTest.php | 124 ++++
tests/Unit/Component/AiAutomation/TestCrmAiPromptServiceTest.php | 67 +-
tests/Unit/Component/AiCallScoring/Services/AiCallScoringEligibilityCheckerTest.php | 55 ++
tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.php | 135 ----
tests/Unit/Component/ES/Processor/Actions/LoadDocumentsActionTest.php | 220 ++++++
tests/Unit/Component/ES/Processor/EntityQueryBuilderTest.php | 21 +-
tests/Unit/Component/ES/Processor/Traits/SkipActivityTraitTest.php | 51 --
tests/Unit/Component/ES/Worker/ActivityWorkerTest.php | 174 -----
tests/Unit/Component/ES/Worker/EntityWorkerTest.php | 97 ---
tests/Unit/Component/ES/Worker/WorkerAmountTest.php | 116 ---
tests/Unit/Component/Encoding/Job/AnalyzeTrackChannelsJobTest.php | 52 +-
tests/Unit/Component/Encoding/Service/GenerateSpeechFromSilenceServiceTest.php | 171 ++---
tests/Unit/Component/FFMpeg/Services/GetSpeechIntervalsTest.php | 36 +-
tests/Unit/Component/LanguageDetection/Services/FindSpeechTimeServiceTest.php | 20 +-
tests/Unit/Component/MobileSettings/MobileSettingsControllerTest.php | 5 +-
tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCreatorTest.php | 75 ++
tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesDeleterTest.php | 63 ++
tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesProviderTest.php | 134 ++++
tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesUploaderTest.php | 57 ++
tests/Unit/Component/Transcription/Diarization/Services/GetNormalizedParticipantSpeechesServiceTest.php | 51 +-
tests/Unit/Component/Transcription/Diarization/Source/MeetingBotSourceTest.php | 29 +-
tests/Unit/Contracts/Services/Calendar/CalendarTraitTest.php | 58 +-
tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.php | 159 +++++
tests/Unit/Jobs/Activity/Import/ImportTwilioVideoSpeechesJobTest.php | 22 +-
tests/Unit/Jobs/Activity/Import/IsActivityReadyForProcessingJobTest.php | 26 +-
tests/Unit/Jobs/Calendar/SetupCalendarSyncTest.php | 25 -
tests/Unit/Services/Activity/ParticipantsServiceTest.php | 12 +-
tests/Unit/Services/Activity/Twilio/S3RecordingCredentialsServiceTest.php | 180 +++++
tests/Unit/Services/ActivityServiceTest.php | 132 ++++
tests/Unit/Services/Calendar/CalendarActivityServiceTest.php | 150 +++-
tests/Unit/Services/Calendar/Command/ImportParticipantsTest.php | 6 +-
tests/Unit/Services/Calendar/Command/MapActivityDataTest.php | 78 +-
tests/Unit/Services/Calendar/GoogleCalendarServiceTest.php | 116 +++
tests/Unit/Services/Crm/Close/ServiceTest.php | 165 +++++
tests/Unit/Services/Crm/Hubspot/ServiceTest.php | 272 ++++++-
tests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTest.php | 25 +-
tests/Unit/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTraitMatchActivitiesTest.php | 3 +-
tests/Unit/Services/Crm/IntegrationApp/ServiceTraits/SyncCrmEntitiesTraitOpportunitiesTest.php | 40 ++
tests/Unit/Services/Crm/Pipedrive/ImportOpportunityMatchActivitiesTest.php | 2 +
tests/Unit/Services/Crm/Salesforce/ServiceTest.php | 139 ++++
tests/Unit/Services/Mail/Office/EmailApiClientTest.php | 195 ++---
tests/Unit/Services/RecallAI/RecallAIServiceTest.php | 24 +-
175 files changed, 12562 insertions(+), 2162 deletions(-)
create mode 120000 CLAUDE.md
create mode 100644 app/Component/AiAutomation/Services/CrmFillingEligibilityChecker.php
delete mode 100644 app/Component/ES/ElasticSearchWorkerManager.php
delete mode 100644 app/Component/ES/Processor/Traits/SkipActivityTrait.php
delete mode 100644 app/Component/ES/Worker/ActivityWorker.php
delete mode 100644 app/Component/ES/Worker/EntityWorker.php
delete mode 100644 app/Component/ES/Worker/WorkerAmount.php
delete mode 100644 app/Component/ES/Worker/WorkerInterface.php
create mode 100644 app/Component/ProphetAi/Exceptions/InsufficientTranscriptException.php
create mode 100644 app/Component/Transcription/DTO/Http/Transcription/AssemblyAI/AssemblyAI/NoAssemblyIdException.php
create mode 100644 app/Component/Transcription/DTO/Http/Transcription/TranscriptionIsNotCorrectFormatException.php
create mode 100644 app/Console/Commands/Activities/SetupIntegration/TwilioSetS3RecordingCredentialsCommand.php
create mode 100644 app/Console/Commands/Crm/BackfillOpportunityUserFromAccountCommand.php
delete mode 100644 app/Console/Commands/Elasticsearch/AsyncUpdateEsActivities.php
create mode 100644 app/Console/Commands/IssueMcpTokenCommand.php
create mode 100644 app/Http/Middleware/McpAuditMiddleware.php
create mode 100644 app/Http/Middleware/McpTierMiddleware.php
create mode 100644 app/Mcp/Contracts/McpCallRepositoryInterface.php
create mode 100644 app/Mcp/DTO/ListCallsFilters.php
create mode 100644 app/Mcp/Errors/McpError.php
create mode 100644 app/Mcp/Repositories/McpActivityHydrator.php
create mode 100644 app/Mcp/Repositories/McpCallRepository.php
create mode 100644 app/Mcp/Repositories/McpElasticCallRepository.php
create mode 100644 app/Mcp/Servers/JiminnyServer.php
create mode 100644 app/Mcp/Tools/ListCallsTool.php
create mode 100644 app/Services/Activity/Twilio/S3RecordingCredentialsService.php
create mode 100644 config/mcp.php
create mode 100644 database/migrations/2026_04_30_120000_create_mcp_audit_log_table.php
create mode 100644 docs/mcp/explorer/explorer.html
create mode 100644 docs/mcp/explorer/explorer.template.html
create mode 100644 docs/mcp/explorer/generate.js
create mode 100644 docs/mcp/explorer/tool-explorer-meta.json
create mode 100644 docs/mcp/tools-list.json
create mode 100644 docs/mcp/tools.md
create mode 100644 front-end/src/components/shared/modals/EntityPickerModal/__tests__/useEntitiesCache.spec.ts
create mode 100644 tests/Feature/Component/Nudge/ProcessOrganisationImmediateNudgesJobTest.php
create mode 100644 tests/Feature/Mcp/IssueMcpTokenCommandTest.php
create mode 100644 tests/Feature/Mcp/ListCallsToolElasticFeatureTest.php
create mode 100644 tests/Feature/Mcp/ListCallsToolFeatureTest.php
create mode 100644 tests/Feature/Mcp/McpTestHelpersTrait.php
create mode 100644 tests/Stubs/SentryStub.php
create mode 100644 tests/Unit/Component/AiAutomation/Services/CrmFillingEligibilityCheckerTest.php
delete mode 100644 tests/Unit/Component/ES/ElasticSearchWorkerManagerTest.php
create mode 100644 tests/Unit/Component/ES/Processor/Actions/LoadDocumentsActionTest.php
delete mode 100644 tests/Unit/Component/ES/Processor/Traits/SkipActivityTraitTest.php
delete mode 100644 tests/Unit/Component/ES/Worker/ActivityWorkerTest.php
delete mode 100644 tests/Unit/Component/ES/Worker/EntityWorkerTest.php
delete mode 100644 tests/Unit/Component/ES/Worker/WorkerAmountTest.php
create mode 100644 tests/Unit/Component/ParticipantSpeech/Services/ParticipantSpeechesCreatorTest.php
create mode 100644 tests/Unit/Http/Controllers/Kiosk/ActivityControllerTest.php
create mode 100644 tests/Unit/Services/Activity/Twilio/S3RecordingCredentialsServiceTest.php
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20725-handle-HS-search-rate-limit) $ git status
On branch master
Your branch is behind 'origin/master' by 114 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: .env.local
modified: app/Component/SCIM/Constants.php
modified: app/Component/SCIM/ScimProvisioning.php
modified: app/Component/Twilio/Conference/ConferenceManager/SoftPhoneManager.php
modified: app/Console/Commands/JiminnyDebugCommand.php
modified: app/DTO/SCIM/AAD/Request/CoreUserRequest.php
modified: app/DTO/SCIM/AAD/Response/CoreUser.php
modified: app/Services/Telephony/TextMessagingService.php
modified: config/logging.php
Untracked files:
(use "git add <file>..." to include in what will be committed)
.env.nikilocal
.env.other
WEBHOOK_FILTERING_IMPLEMENTATION.md
app/Component/SCIM/Mutators/Attributes/User/RoleAttr.php
app/Console/Commands/Crm/Hubspot/SimulateWebhooksCommand.php
app/Console/Commands/Reports/CreateMockAskJiminnyReportResultCommand.php
app/Rules/ListenerRoleCannotHaveAdminOrManagerPermissionRule.php
ids.txt
public/favicon.ico
raw_sql_query.sql
tests/Unit/Component/SCIM/Mutators/Attributes/User/RoleAttrTest.php
tests/Unit/Policies/CanAccessAiReportsTest.php
tests/Unit/Rules/ListenerRoleCannotHaveAdminOrManagerPermissionRuleTest.php
no changes added to commit (use "git add" and/or "git commit -a")
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull
remote: Enumerating objects: 306, done.
remote: Counting objects: 100% (299/299), done.
remote: Compressing objects: 100% (183/183), done.
remote: Total 306 (delta 213), reused 171 (delta 116), pack-reused 7 (from 1)
Receiving objects: 100% (306/306), 80.12 KiB | 1000.00 KiB/s, done.
Resolving deltas: 100% (213/213), completed with 53 local objects.
From github.com:jiminny/app
90bca4e4b2..5604af40cf master -> origin/master
4e7078fd8b..0b8343d179 JY-18091-upgrade-to-php-8-5 -> origin/JY-18091-upgrade-to-php-8-5
098eeaa087..d5a447e492 JY-20613-allow-owner-role-on-team-setup -> origin/JY-20613-allow-owner-role-on-team-setup
c3a76ace91..af65249d0f JY-20749-user-can-view-recorded-meetings -> origin/JY-20749-user-can-view-recorded-meetings
d94a285ae7..7ce96cb5fe JY-20808-low-priority-indexing-queue -> origin/JY-20808-low-priority-indexing-queue
* [new branch] JY-20842-remove-partial-updater -> origin/JY-20842-remove-partial-updater
* [new branch] JY-20920-fix-participant-flip -> origin/JY-20920-fix-participant-flip
* [new branch] secfix/npm-20260519 -> origin/secfix/npm-20260519
Updating cb4ebf0c36..5604af40cf
Fast-forward
app/Component/ES/ChunkSize.php | 54 +++++++++++++++++++
app/Component/ES/Processor/DTOs/SelectionList.php | 4 +-
app/Component/ES/Processor/TargetEntitiesSelector.php | 19 ++++---
app/Component/MeetingBot/Service/ParticipantMatcher.php | 46 ++++++++++++----
app/Exceptions/RateLimitException.php | 19 ++++++-
app/Http/Middleware/McpTierMiddleware.php | 27 ++--------
app/Jobs/Crm/MatchActivityCrmData.php | 47 ++++++++++++----
app/Jobs/Middleware/HandleHubspotRateLimit.php | 42 +++++++++++++++
app/Mcp/Servers/JiminnyServer.php | 2 +
app/Mcp/Tools/GetMeTool.php | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++
app/Models/Feature/FeatureEnum.php | 1 +
app/Services/Activity/HubSpot/ProviderResolver.php | 4 +-
app/Services/Activity/HubSpot/ProviderResolverInterface.php | 2 +-
app/Services/Activity/HubSpot/Providers/Provider.php | 2 +-
app/Services/Activity/HubSpot/Providers/ProviderKixie.php | 2 +-
app/Services/Activity/HubSpot/Providers/ProviderOrum.php | 2 +-
app/Services/Activity/HubSpot/Providers/ProviderTwilio.php | 2 +-
app/Services/Activity/HubSpot/Providers/ProviderTwilioFlex.php | 5 +-
app/Services/Activity/HubSpot/Service.php | 97 +++++++++++++++++++++++++++------
app/Services/Crm/Hubspot/Client.php | 132 +++++++++++++++++++++++++++++++++++++++++++++
app/Services/Crm/Hubspot/HubspotClientInterface.php | 15 ++++++
app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php | 21 ++++----
app/Services/Crm/Hubspot/Pagination/PaginationState.php | 2 +-
database/migrations/2026_05_13_124153_create_mcp_feature_flag.php | 25 +++++++++
tests/Feature/Mcp/GetMeToolFeatureTest.php | 140 +++++++++++++++++++++++++++++++++++++++++++++++
tests/Feature/Mcp/ListCallsToolFeatureTest.php | 2 +-
tests/Feature/Mcp/McpTestHelpersTrait.php | 19 ++++++-
tests/Unit/Component/ES/ChunkSizeTest.php | 50 +++++++++++++++++
tests/Unit/Component/ES/Processor/DTOs/SelectionListTest.php | 27 +++++++---
tests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.php | 39 ++++++++------
tests/Unit/Component/MeetingBot/Service/ParticipantMatcherTest.php | 68 ++++++++++++++++++++++-
tests/Unit/Exceptions/RateLimitExceptionTest.php | 56 +++++++++++++++++++
tests/Unit/Jobs/Crm/MatchActivityCrmDataTest.php | 8 +--
tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++
tests/Unit/Services/Activity/HubSpot/ServiceTest.php | 109 +++++++++++++++++++++++++++++++++++++
tests/Unit/Services/Crm/Hubspot/ClientTest.php | 250 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/Unit/Services/Crm/Hubspot/Pagination/HubspotPaginationServiceTest.php | 283 +++++++++++++++++++++---------------------------------------------------------------------------
37 files changed, 1587 insertions(+), 344 deletions(-)
create mode 100644 app/Component/ES/ChunkSize.php
create mode 100644 app/Jobs/Middleware/HandleHubspotRateLimit.php
create mode 100644 app/Mcp/Tools/GetMeTool.php
create mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.php
create mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.php
create mode 100644 tests/Unit/Component/ES/ChunkSizeTest.php
create mode 100644 tests/Unit/Exceptions/RateLimitExceptionTest.php
create mode 100644 tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.php
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pull
Already up to date.
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20676-delete-report-related-objects
Switched to a new branch 'JY-20676-delete-report-related-objects'
lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20676-delete-report-related-objects) $ csfix
docker exec -it docker_lamp_1 ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php -v --using-cache=no --diff
PHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminski and contributors.
PHP runtime: 8.3.30
Running analysis on 7 cores with 10 files per process.
Parallel runner is an experimental feature and may be unstable, use it at your own risk. Feedback highly appreciated!
Loaded config default from ".php-cs-fixer.dist.php".
4781/5690 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░] 84%
DOCKER
Close Tab
DEV (docker)
Close Tab
APP (docker)
Close Tab
screenpipe"
Close Tab
-zsh
Close Tab
⌥⌘1
APP (docker)...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
56957
|
NULL
|
0
|
2026-05-19T08:43:21.553988+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779180201553_m1.jpg...
|
Firefox
|
Hotel Bellisimo, Lozenets (updated prices 2026) — Hotel Bellisimo, Lozenets (updated prices 2026) — Personal...
|
1
|
www.booking.com/hotel/bg/hotel-bellisimo.html?aid= www.booking.com/hotel/bg/hotel-bellisimo.html?aid=2311236&label=en-bg-booking-desktop-MtC3OoaoU_ML6gxkUZ2GoAS652796015943%3Apl%3Ata%3Ap1%3Ap2%3Aac%3Aap%3Aneg%3Afi%3Atikwd-65526620%3Alp9217204%3Ali%3Adec%3Adm&sid=ff97aa04f61236b89f3f81a78b301783&age=4&age=6&all_sr_blocks=41168804_355818887_0_0_0&checkin=2026-06-26&checkout=2026-07-05&dest_id=-835933&dest_type=city&dist=0&group_adults=2&group_children=2&hapos=10&highlighted_blocks=41168804_355818887_0_0_0&hpos=10&matching_block_id=41168804_355818887_0_0_0&no_rooms=1&req_adults=2&req_age=4&req_age=6&req_children=2&room1=A%2CA%2C6%2C4&sb_price_type=total&sr_order=popularity&sr_pri_blocks=41168804_355818887_0_0_0__71000&srepoch=1779180188&srpvid=f4603d451eea032b&type=total&ucfs=1&...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
Getting Started DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
Getting Started · AFFiNE
Getting Started · AFFiNE
Screenpipe — Archive
Screenpipe — Archive
Download screenpipe — get started in minutes
Download screenpipe — get started in minutes
Self-Hosted Software and Apps
Self-Hosted Software and Apps
New Tab
New Tab
Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - [EMAIL] - Gmail
Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - [EMAIL] - Gmail
Завеждане на щета онлайн | Euroins
Завеждане на щета онлайн | Euroins
Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii
Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii
Nginx Proxy Manager
Nginx Proxy Manager
Location Logger
Location Logger
Providers - Admin - authentik
Providers - Admin - authentik
Booking.com: Hotels in Lozenets. Book your hotel now!
Booking.com: Hotels in Lozenets. Book your hotel now!
Hotel Bellisimo, Lozenets (updated prices 2026)
Hotel Bellisimo, Lozenets (updated prices 2026)
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Skip to main content
Skip to main content
Booking.com
Prices in Euro
EUR
Language: English (US)
Customer support
List your property
List your property
Register an account
Register
Sign in
Sign in
Stays
Stays
Flights
Flights
Flight + Hotel
Flight + Hotel
Car rental
Car rental
Attractions
Attractions
Airport taxis
Airport taxis
Lozenets
Lozenets
Clear
Fri, Jun 26 — Sun, Jul 5
Fri, Jun 26
—
Sun, Jul 5
Number of travelers and rooms. Currently selected: 2 adults · 2 children · 1 room
2 adults · 2 children · 1 room
Search
Search
Home
Home
Hotels
Hotels
Bulgaria
Bulgaria
Burgas Province
Burgas Province
Lozenets
Lozenets
Hotel Bellisimo (Hotel) (Bulgaria) Deals
Hotel Bellisimo (Hotel) (Bulgaria) Deals
Overview
Overview
Info & prices
Info & prices
Facilities
Facilities
House rules
House rules
Important and legal info
Important and legal info
Guest reviews (139)
Guest reviews (139)
Save this item to a trip list
Share this property
Reserve
Reserve
We Price Match
We Price Match
2 out of 5 stars
Beachfront
Beachfront
Hotel Bellisimo
Hotel Bellisimo
Hotel Bellisimo, Lozenets - Check location
2 Veleka Str, 8277 Lozenets, Bulgaria
2 Veleka Str, 8277 Lozenets, Bulgaria
–
Excellent location – show map
Excellent location – show map
a building on a street with cars parked in front of it at Hotel Bellisimo in Lozenets
a bedroom with a red bed and a large window at Hotel Bellisimo in Lozenets
a bathroom with a sink and a mirror at Hotel Bellisimo in Lozenets
a restaurant with wooden tables and chairs under an umbrella at Hotel Bellisimo in Lozenets
a living room with a couch and a large window at Hotel Bellisimo in Lozenets
a restaurant with wooden tables and a green floor at Hotel Bellisimo in Lozenets
a group of people sitting at tables in a restaurant at Hotel Bellisimo in Lozenets
a bedroom with a orange bed with two nightstands and two towels at Hotel Bellisimo in Lozenets +62 photos
+62 photos
Scored 9.3 Rated wonderful
Scored 9.3
Rated wonderful
Top-rated guest experiences
Top-rated guest experiences
“
The hotel staff and owners were extremely helpful, friendly and went everything possible for us to feel welcome. We were super grateful that they...
”
B
Boryana
Bulgaria
“
i like that the location is good, there is free parking and the people from the hotel were super nice
”
B
Bondzhov
Bulgaria
“
The staff is amazing, very pleasant and professional. The location is perfect, everything was amazing! Thank you!
”
J
Jana
Serbia
“
Perfect location, very comfortable rooms, huge bathroom, very friendly staff that was very helpfull
”
H
Hristo
Germany
“
Everything was perfect, VERY close to beach, very friendly stuff, clean and good family hotel. We will come again next year. Highly recommend for...
”
Hyppenen
Finland
“
Czysty , miły hotel w dobrej lokalizacji. Przemili gospodarze. Generalnie super.
”
Paweł
Poland
“
Vstřícný personál, chutné snídaně, výhodná poloha.
”
Libor
Czech Republic
“
Der mit Abstand angenehmste Aufenthalt meiner Balkan-Motorradreise. Das Bike durfte ich im Hof abstellen (gibt einen Extra-Stern). Das Haus macht...
”...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"DXP4800PLUS-B5F8","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"DXP4800PLUS-B5F8","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Getting Started · AFFiNE","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Getting Started · AFFiNE","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe — Archive","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Screenpipe — Archive","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Download screenpipe — get started in minutes","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Download screenpipe — get started in minutes","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Self-Hosted Software and Apps","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Self-Hosted Software and Apps","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - kovaliklukas@gmail.com - Gmail","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - kovaliklukas@gmail.com - Gmail","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Завеждане на щета онлайн | Euroins","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Завеждане на щета онлайн | Euroins","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Nginx Proxy Manager","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Nginx Proxy Manager","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Location Logger","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Location Logger","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Providers - Admin - authentik","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Providers - Admin - authentik","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Booking.com: Hotels in Lozenets. Book your hotel now!","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Booking.com: Hotels in Lozenets. Book your hotel now!","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Hotel Bellisimo, Lozenets (updated prices 2026)","depth":4,"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Hotel Bellisimo, Lozenets (updated prices 2026)","depth":5,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.48576388,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.5086806,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.53194445,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.5552083,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Bitwarden","depth":6,"bounds":{"left":0.5784722,"top":0.0,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to main content","depth":7,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to main content","depth":9,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Booking.com","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Prices in Euro","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"EUR","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Language: English (US)","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Customer support","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"List your property","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"List your property","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Register an account","depth":9,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Register","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Sign in","depth":10,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sign in","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuItem","text":"Stays","depth":9,"on_screen":true,"help_text":"","role_description":"menu item","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Stays","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuItem","text":"Flights","depth":9,"on_screen":true,"help_text":"","role_description":"menu item","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Flights","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuItem","text":"Flight + Hotel","depth":9,"on_screen":true,"help_text":"","role_description":"menu item","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Flight + Hotel","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuItem","text":"Car rental","depth":9,"on_screen":true,"help_text":"","role_description":"menu item","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Car rental","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuItem","text":"Attractions","depth":9,"on_screen":true,"help_text":"","role_description":"menu item","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Attractions","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuItem","text":"Airport taxis","depth":9,"on_screen":true,"help_text":"","role_description":"menu item","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Airport taxis","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Lozenets","depth":9,"on_screen":true,"value":"Lozenets","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Lozenets","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Clear","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Fri, Jun 26 — Sun, Jul 5","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fri, Jun 26","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sun, Jul 5","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Number of travelers and rooms. Currently selected: 2 adults · 2 children · 1 room","depth":10,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2 adults · 2 children · 1 room","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search","depth":9,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Search","depth":11,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Home","depth":13,"on_screen":true,"help_text":"Booking.com","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Home","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Hotels","depth":13,"on_screen":true,"help_text":"Hotels on Booking.com","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Hotels","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Bulgaria","depth":13,"on_screen":true,"help_text":"Hotels in Bulgaria","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Bulgaria","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Burgas Province","depth":13,"on_screen":true,"help_text":"Hotels in Burgas Province","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Burgas Province","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Lozenets","depth":13,"on_screen":true,"help_text":"Hotels in Lozenets","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Lozenets","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Hotel Bellisimo (Hotel) (Bulgaria) Deals","depth":13,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Hotel Bellisimo (Hotel) (Bulgaria) Deals","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Overview","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Overview","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Info & prices","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Info & prices","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Facilities","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Facilities","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"House rules","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"House rules","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Important and legal info","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Important and legal info","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Guest reviews (139)","depth":14,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Guest reviews (139)","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Save this item to a trip list","depth":17,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Share this property","depth":17,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Reserve","depth":12,"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Reserve","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"We Price Match","depth":15,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"We Price Match","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"2 out of 5 stars","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Beachfront","depth":14,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Beachfront","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Hotel Bellisimo","depth":13,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Hotel Bellisimo","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Hotel Bellisimo, Lozenets - Check location","depth":12,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"2 Veleka Str, 8277 Lozenets, Bulgaria","depth":14,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"2 Veleka Str, 8277 Lozenets, Bulgaria","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"–","depth":13,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Excellent location – show map","depth":13,"on_screen":true,"help_text":"Hotel Bellisimo, Lozenets - Check location","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Excellent location – show map","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"a building on a street with cars parked in front of it at Hotel Bellisimo in Lozenets","depth":16,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"a bedroom with a red bed and a large window at Hotel Bellisimo in Lozenets","depth":16,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"a bathroom with a sink and a mirror at Hotel Bellisimo in Lozenets","depth":16,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"a restaurant with wooden tables and chairs under an umbrella at Hotel Bellisimo in Lozenets","depth":16,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"a living room with a couch and a large window at Hotel Bellisimo in Lozenets","depth":16,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"a restaurant with wooden tables and a green floor at Hotel Bellisimo in Lozenets","depth":16,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"a group of people sitting at tables in a restaurant at Hotel Bellisimo in Lozenets","depth":16,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"a bedroom with a orange bed with two nightstands and two towels at Hotel Bellisimo in Lozenets +62 photos","depth":16,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"+62 photos","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Scored 9.3 Rated wonderful","depth":13,"on_screen":true,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Scored 9.3","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Rated wonderful","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Top-rated guest experiences","depth":13,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Top-rated guest experiences","depth":14,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"“","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The hotel staff and owners were extremely helpful, friendly and went everything possible for us to feel welcome. We were super grateful that they...","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"”","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"B","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Boryana","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Bulgaria","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"“","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"i like that the location is good, there is free parking and the people from the hotel were super nice","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"”","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"B","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Bondzhov","depth":16,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Bulgaria","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"“","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The staff is amazing, very pleasant and professional. The location is perfect, everything was amazing! Thank you!","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"”","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"J","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jana","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Serbia","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"“","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Perfect location, very comfortable rooms, huge bathroom, very friendly staff that was very helpfull","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"”","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"H","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Hristo","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Germany","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"“","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Everything was perfect, VERY close to beach, very friendly stuff, clean and good family hotel. We will come again next year. Highly recommend for...","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"”","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Hyppenen","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Finland","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"“","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Czysty , miły hotel w dobrej lokalizacji. Przemili gospodarze. Generalnie super.","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"”","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Paweł","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Poland","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"“","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Vstřícný personál, chutné snídaně, výhodná poloha.","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"”","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Libor","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Czech Republic","depth":17,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"“","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Der mit Abstand angenehmste Aufenthalt meiner Balkan-Motorradreise. Das Bike durfte ich im Hof abstellen (gibt einen Extra-Stern). Das Haus macht...","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"”","depth":16,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
7445248494130491588
|
2735651089224012320
|
click
|
accessibility
|
NULL
|
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
Getting Started DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
Getting Started · AFFiNE
Getting Started · AFFiNE
Screenpipe — Archive
Screenpipe — Archive
Download screenpipe — get started in minutes
Download screenpipe — get started in minutes
Self-Hosted Software and Apps
Self-Hosted Software and Apps
New Tab
New Tab
Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - [EMAIL] - Gmail
Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - [EMAIL] - Gmail
Завеждане на щета онлайн | Euroins
Завеждане на щета онлайн | Euroins
Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii
Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii
Nginx Proxy Manager
Nginx Proxy Manager
Location Logger
Location Logger
Providers - Admin - authentik
Providers - Admin - authentik
Booking.com: Hotels in Lozenets. Book your hotel now!
Booking.com: Hotels in Lozenets. Book your hotel now!
Hotel Bellisimo, Lozenets (updated prices 2026)
Hotel Bellisimo, Lozenets (updated prices 2026)
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Skip to main content
Skip to main content
Booking.com
Prices in Euro
EUR
Language: English (US)
Customer support
List your property
List your property
Register an account
Register
Sign in
Sign in
Stays
Stays
Flights
Flights
Flight + Hotel
Flight + Hotel
Car rental
Car rental
Attractions
Attractions
Airport taxis
Airport taxis
Lozenets
Lozenets
Clear
Fri, Jun 26 — Sun, Jul 5
Fri, Jun 26
—
Sun, Jul 5
Number of travelers and rooms. Currently selected: 2 adults · 2 children · 1 room
2 adults · 2 children · 1 room
Search
Search
Home
Home
Hotels
Hotels
Bulgaria
Bulgaria
Burgas Province
Burgas Province
Lozenets
Lozenets
Hotel Bellisimo (Hotel) (Bulgaria) Deals
Hotel Bellisimo (Hotel) (Bulgaria) Deals
Overview
Overview
Info & prices
Info & prices
Facilities
Facilities
House rules
House rules
Important and legal info
Important and legal info
Guest reviews (139)
Guest reviews (139)
Save this item to a trip list
Share this property
Reserve
Reserve
We Price Match
We Price Match
2 out of 5 stars
Beachfront
Beachfront
Hotel Bellisimo
Hotel Bellisimo
Hotel Bellisimo, Lozenets - Check location
2 Veleka Str, 8277 Lozenets, Bulgaria
2 Veleka Str, 8277 Lozenets, Bulgaria
–
Excellent location – show map
Excellent location – show map
a building on a street with cars parked in front of it at Hotel Bellisimo in Lozenets
a bedroom with a red bed and a large window at Hotel Bellisimo in Lozenets
a bathroom with a sink and a mirror at Hotel Bellisimo in Lozenets
a restaurant with wooden tables and chairs under an umbrella at Hotel Bellisimo in Lozenets
a living room with a couch and a large window at Hotel Bellisimo in Lozenets
a restaurant with wooden tables and a green floor at Hotel Bellisimo in Lozenets
a group of people sitting at tables in a restaurant at Hotel Bellisimo in Lozenets
a bedroom with a orange bed with two nightstands and two towels at Hotel Bellisimo in Lozenets +62 photos
+62 photos
Scored 9.3 Rated wonderful
Scored 9.3
Rated wonderful
Top-rated guest experiences
Top-rated guest experiences
“
The hotel staff and owners were extremely helpful, friendly and went everything possible for us to feel welcome. We were super grateful that they...
”
B
Boryana
Bulgaria
“
i like that the location is good, there is free parking and the people from the hotel were super nice
”
B
Bondzhov
Bulgaria
“
The staff is amazing, very pleasant and professional. The location is perfect, everything was amazing! Thank you!
”
J
Jana
Serbia
“
Perfect location, very comfortable rooms, huge bathroom, very friendly staff that was very helpfull
”
H
Hristo
Germany
“
Everything was perfect, VERY close to beach, very friendly stuff, clean and good family hotel. We will come again next year. Highly recommend for...
”
Hyppenen
Finland
“
Czysty , miły hotel w dobrej lokalizacji. Przemili gospodarze. Generalnie super.
”
Paweł
Poland
“
Vstřícný personál, chutné snídaně, výhodná poloha.
”
Libor
Czech Republic
“
Der mit Abstand angenehmste Aufenthalt meiner Balkan-Motorradreise. Das Bike durfte ich im Hof abstellen (gibt einen Extra-Stern). Das Haus macht...
”...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
56956
|
NULL
|
0
|
2026-05-19T08:42:59.156110+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779180179156_m2.jpg...
|
Firefox
|
Booking.com: Hotels in Lozenets. Book your hotel n Booking.com: Hotels in Lozenets. Book your hotel now! — Personal...
|
1
|
www.booking.com/searchresults.html?ss=Lozenets%2C+ www.booking.com/searchresults.html?ss=Lozenets%2C+Burgas+Province%2C+Bulgaria&efdco=1&label=en-bg-booking-desktop-MtC3OoaoU_ML6gxkUZ2GoAS652796015943%3Apl%3Ata%3Ap1%3Ap2%3Aac%3Aap%3Aneg%3Afi%3Atikwd-65526620%3Alp9217204%3Ali%3Adec%3Adm&aid=2311236&lang=en-us&sb=1&src_elem=sb&src=index&dest_id=-835933&dest_type=city&ac_position=0&ac_click_type=b&ac_langcode=en&ac_suggestion_list_length=5&search_selected=true&search_pageview_id=d7cd3d314828019c&ac_meta=GhBkN2NkM2QzMTQ4MjgwMTljIAAoATICZW46BExvemU%3D&checkin=2026-06-26&checkout=2026-07-05&group_adults=2&no_rooms=1&group_children=2&age=6&age=4...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
Getting Started DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
Getting Started · AFFiNE
Getting Started · AFFiNE
Screenpipe — Archive
Screenpipe — Archive
Download screenpipe — get started in minutes
Download screenpipe — get started in minutes
Self-Hosted Software and Apps
Self-Hosted Software and Apps
New Tab
New Tab
Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - [EMAIL] - Gmail
Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - [EMAIL] - Gmail
Завеждане на щета онлайн | Euroins
Завеждане на щета онлайн | Euroins
Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii
Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii
Nginx Proxy Manager
Nginx Proxy Manager
Location Logger
Location Logger
Providers - Admin - authentik
Providers - Admin - authentik
Booking.com: Hotels in Lozenets. Book your hotel now!
Booking.com: Hotels in Lozenets. Book your hotel now!
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Skip to main content
Skip to main content
Booking.com
Prices in Euro
EUR
Language: English (US)
Customer support
List your property
List your property
Register an account
Register
Sign in
Sign in
Stays
Stays
Flights
Flights
Flight + Hotel
Flight + Hotel
Car rental
Car rental
Attractions
Attractions
Airport taxis
Airport taxis
Lozenets
Lozenets
Clear
Fri, Jun 26 — Sun, Jul 5
Fri, Jun 26
—
Sun, Jul 5
Number of travelers and rooms. Currently selected: 2 adults · 2 children · 1 room
2 adults · 2 children · 1 room
Search
Search
Home
Home
Bulgaria
Bulgaria
Burgas Province
Burgas Province
Lozenets
Lozenets
Search results
Show on map
Show on map
Filter by:
Filter by:
Your budget (per night)
€ 30 – € 400+
Popular filters
Beachfront: 26 properties
Swimming pool: 34 properties
Breakfast & dinner included: 1 property
Villas: 7 properties
Breakfast included: 14 properties
Free Wifi: 59 properties
Parking: 53 properties
Apartments: 25 properties
Smart filters
What are you looking for?
What are you looking for?
Find properties
Find properties
Meals
Breakfast included: 14 properties
Breakfast & dinner included: 1 property
Kitchen facilities: 40 properties
Property Type
Hotels: 23 properties
Apartments: 25 properties
Vacation Homes: 2 properties
Resorts: 2 properties
Villas: 7 properties
Resort Villages: 1 property
Guesthouses: 9 properties
Family-Friendly Properties: 15 properties
Entire homes & apartments: 44 properties
Bedrooms and bathrooms
Bedrooms
Bathrooms
Facilities
Swimming pool: 34 properties
Parking: 53 properties
Free Wifi: 59 properties
Spa: 6 properties
Hot tub/Jacuzzi: 9 properties
Show all 13
Show all 13
Room facilities
Kitchen/Kitchenette: 40 properties
Air conditioning: 62 properties
Sea view: 26 properties
Washing machine: 24 properties
Balcony: 57 properties
Show all 25
Show all 25
Beach Access
Beachfront: 26 properties
Review score
Wonderful: 9+: 35 properties
Very Good: 8+: 46 properties
Good: 7+: 53 properties
Pleasant: 6+: 55 properties
Property rating
Find high-quality hotels and vacation rentals
1 star: 5 properties
2 stars: 9 properties
3 stars: 23 properties
4 stars: 8 properties
5 stars: 1 property
Reservation policy
Free cancellation: 56 properties
Book without credit card: 1 property
Distance from center of Lozenets
Less than 1 km: 55 properties
Less than 3 km: 65 properties
Less than 5 km: 66 properties
Fun Things To Do
Beach: 39 properties
Tennis equipment: 11 properties
Private beach area: 15 properties
Playground: 19 properties
Windsurfing: 11 properties
Travel group
Pet friendly: 18 properties
Family-Friendly Properties: 15 properties
Bed preference
Cribs: 4 properties
Double bed: 60 properties
Twin beds: 31 properties
Highly rated features
Based on guest reviews
Very good breakfast: 1 property
Online Payment
Accepts online payments: 41 properties
Property Accessibility
Bathroom emergency cord: 1 property
Toilet with grab rails: 1 property
Lowered sink: 1 property
Room Accessibility
Entire unit located on ground floor: 12 properties
Upper floors accessible by elevator: 9 properties
Entire unit wheelchair accessible: 6 properties
Roll-in shower: 1 property
Emergency cord in bathroom: 1 property
Shower chair: 1 property
Walk-in shower: 13 properties
Raised toilet: 2 properties
Search results updated. Lozenets: 66 properties found. Sorted by: Top picks for long stays.
Lozenets: 66 properties found
List
List
Grid
Grid
Sort by: Top picks for long stays
Sort by:
Top picks for long stays
Close banner
Commission paid on bookings, and other factors can affect property rankings. Learn about these ranking parameters and how to select and modify them.
Learn more
Learn more
Browse the results for Lozenets
Save this item to a trip list
Family Hotel Kontesa Opens in new window
Family Hotel Kontesa Opens in new window
Family Hotel Kontesa
Opens in new window
3 out of 5
Lozenets·Show on map
Lozenets
·
Show on map
·
100 m from downtown
·
Beach Nearby
300 m from beach
Scored 9.8 Exceptional 196 reviews
Scored 9.8
Exceptional
196 reviews
Comfort: Scored 9.8
Comfort
9.8
Recommended for your group...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"DXP4800PLUS-B5F8","depth":4,"bounds":{"left":0.5,"top":0.0518755,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"DXP4800PLUS-B5F8","depth":5,"bounds":{"left":0.51329786,"top":0.06304868,"width":0.036901597,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Getting Started · AFFiNE","depth":4,"bounds":{"left":0.5,"top":0.08459697,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Getting Started · AFFiNE","depth":5,"bounds":{"left":0.51329786,"top":0.09577015,"width":0.04255319,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe — Archive","depth":4,"bounds":{"left":0.5,"top":0.11731844,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Screenpipe — Archive","depth":5,"bounds":{"left":0.51329786,"top":0.12849163,"width":0.037898935,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Download screenpipe — get started in minutes","depth":4,"bounds":{"left":0.5,"top":0.15003991,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Download screenpipe — get started in minutes","depth":5,"bounds":{"left":0.51329786,"top":0.16121309,"width":0.0809508,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Self-Hosted Software and Apps","depth":4,"bounds":{"left":0.5,"top":0.18276137,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Self-Hosted Software and Apps","depth":5,"bounds":{"left":0.51329786,"top":0.19393456,"width":0.054853722,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.5,"top":0.21548285,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"bounds":{"left":0.51329786,"top":0.22665602,"width":0.014960106,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - kovaliklukas@gmail.com - Gmail","depth":4,"bounds":{"left":0.5,"top":0.2482043,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - kovaliklukas@gmail.com - Gmail","depth":5,"bounds":{"left":0.51329786,"top":0.25937748,"width":0.18118352,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Завеждане на щета онлайн | Euroins","depth":4,"bounds":{"left":0.5,"top":0.28092578,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Завеждане на щета онлайн | Euroins","depth":5,"bounds":{"left":0.51329786,"top":0.29209897,"width":0.0653258,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii","depth":4,"bounds":{"left":0.5,"top":0.31364724,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii","depth":5,"bounds":{"left":0.51329786,"top":0.32482043,"width":0.091090426,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Nginx Proxy Manager","depth":4,"bounds":{"left":0.5,"top":0.3463687,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Nginx Proxy Manager","depth":5,"bounds":{"left":0.51329786,"top":0.3575419,"width":0.036901597,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Location Logger","depth":4,"bounds":{"left":0.5,"top":0.3790902,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Location Logger","depth":5,"bounds":{"left":0.51329786,"top":0.39026338,"width":0.028091755,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Providers - Admin - authentik","depth":4,"bounds":{"left":0.5,"top":0.41181165,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Providers - Admin - authentik","depth":5,"bounds":{"left":0.51329786,"top":0.42298484,"width":0.05119681,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Booking.com: Hotels in Lozenets. Book your hotel now!","depth":4,"bounds":{"left":0.5,"top":0.4445331,"width":0.06881649,"height":0.032721467},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Booking.com: Hotels in Lozenets. Book your hotel now!","depth":5,"bounds":{"left":0.51329786,"top":0.4557063,"width":0.09541223,"height":0.010774142},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.55651593,"top":0.4517159,"width":0.007978723,"height":0.01915403},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.5028258,"top":0.47885075,"width":0.06333112,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.5028258,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.51379657,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.5249335,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.53607047,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Bitwarden","depth":6,"bounds":{"left":0.5472075,"top":0.97007185,"width":0.010638298,"height":0.025538707},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to main content","depth":7,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to main content","depth":9,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Booking.com","depth":10,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Prices in Euro","depth":10,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"EUR","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Language: English (US)","depth":10,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Customer support","depth":10,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"List your property","depth":9,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"List your property","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Register an account","depth":9,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Register","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Sign in","depth":10,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sign in","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuItem","text":"Stays","depth":9,"on_screen":false,"help_text":"","role_description":"menu item","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Stays","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuItem","text":"Flights","depth":9,"on_screen":false,"help_text":"","role_description":"menu item","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Flights","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuItem","text":"Flight + Hotel","depth":9,"on_screen":false,"help_text":"","role_description":"menu item","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Flight + Hotel","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuItem","text":"Car rental","depth":9,"on_screen":false,"help_text":"","role_description":"menu item","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Car rental","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuItem","text":"Attractions","depth":9,"on_screen":false,"help_text":"","role_description":"menu item","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Attractions","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuItem","text":"Airport taxis","depth":9,"on_screen":false,"help_text":"","role_description":"menu item","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Airport taxis","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Lozenets","depth":11,"on_screen":false,"value":"Lozenets","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Lozenets","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Clear","depth":11,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Fri, Jun 26 — Sun, Jul 5","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fri, Jun 26","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sun, Jul 5","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Number of travelers and rooms. Currently selected: 2 adults · 2 children · 1 room","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2 adults · 2 children · 1 room","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search","depth":11,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Search","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Home","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Home","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Bulgaria","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Bulgaria","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Burgas Province","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Burgas Province","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Lozenets","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Lozenets","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Search results","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Show on map","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Show on map","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Filter by:","depth":10,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Filter by:","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Your budget (per night)","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"€ 30 – € 400+","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Popular filters","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Beachfront: 26 properties","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Swimming pool: 34 properties","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Breakfast & dinner included: 1 property","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Villas: 7 properties","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Breakfast included: 14 properties","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Free Wifi: 59 properties","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Parking: 53 properties","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Apartments: 25 properties","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Smart filters","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"What are you looking for?","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"What are you looking for?","depth":11,"on_screen":false,"help_text":"","placeholder":"Example: I want a place with great reviews and free cancellation","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Find properties","depth":11,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Find properties","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Meals","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Breakfast included: 14 properties","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Breakfast & dinner included: 1 property","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Kitchen facilities: 40 properties","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Property Type","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Hotels: 23 properties","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Apartments: 25 properties","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Vacation Homes: 2 properties","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Resorts: 2 properties","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Villas: 7 properties","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Resort Villages: 1 property","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Guesthouses: 9 properties","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Family-Friendly Properties: 15 properties","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Entire homes & apartments: 44 properties","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Bedrooms and bathrooms","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Bedrooms","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Bathrooms","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Facilities","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Swimming pool: 34 properties","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Parking: 53 properties","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Free Wifi: 59 properties","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Spa: 6 properties","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Hot tub/Jacuzzi: 9 properties","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show all 13","depth":11,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Show all 13","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Room facilities","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Kitchen/Kitchenette: 40 properties","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Air conditioning: 62 properties","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Sea view: 26 properties","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Washing machine: 24 properties","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Balcony: 57 properties","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show all 25","depth":11,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Show all 25","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Beach Access","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Beachfront: 26 properties","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review score","depth":13,"bounds":{"left":0.6072141,"top":0.0,"width":0.03025266,"height":0.013567438},"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Wonderful: 9+: 35 properties","depth":12,"bounds":{"left":0.6072141,"top":0.0,"width":0.0003324468,"height":0.0007980846},"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Very Good: 8+: 46 properties","depth":12,"bounds":{"left":0.6072141,"top":0.0,"width":0.0003324468,"height":0.0007980846},"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Good: 7+: 53 properties","depth":12,"bounds":{"left":0.6072141,"top":0.0,"width":0.0003324468,"height":0.0007980846},"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Pleasant: 6+: 55 properties","depth":12,"bounds":{"left":0.6072141,"top":0.0207502,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Property rating","depth":13,"bounds":{"left":0.6072141,"top":0.06264964,"width":0.034906916,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Find high-quality hotels and vacation rentals","depth":13,"bounds":{"left":0.6072141,"top":0.07861133,"width":0.06948138,"height":0.026336791},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"1 star: 5 properties","depth":12,"bounds":{"left":0.6072141,"top":0.10933759,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"2 stars: 9 properties","depth":12,"bounds":{"left":0.6072141,"top":0.13328013,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"3 stars: 23 properties","depth":12,"bounds":{"left":0.6072141,"top":0.15722266,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"4 stars: 8 properties","depth":12,"bounds":{"left":0.6072141,"top":0.1811652,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"5 stars: 1 property","depth":12,"bounds":{"left":0.6072141,"top":0.19074222,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Reservation policy","depth":13,"bounds":{"left":0.6072141,"top":0.23264167,"width":0.042386968,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Free cancellation: 56 properties","depth":12,"bounds":{"left":0.6072141,"top":0.25059855,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Book without credit card: 1 property","depth":12,"bounds":{"left":0.6072141,"top":0.2745411,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Distance from center of Lozenets","depth":13,"bounds":{"left":0.6072141,"top":0.31644055,"width":0.076130316,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Less than 1 km: 55 properties","depth":12,"bounds":{"left":0.6072141,"top":0.33439744,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Less than 3 km: 65 properties","depth":12,"bounds":{"left":0.6072141,"top":0.35834,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Less than 5 km: 66 properties","depth":12,"bounds":{"left":0.6072141,"top":0.38228253,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fun Things To Do","depth":13,"bounds":{"left":0.6072141,"top":0.42418197,"width":0.03939495,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Beach: 39 properties","depth":12,"bounds":{"left":0.6072141,"top":0.44213888,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tennis equipment: 11 properties","depth":12,"bounds":{"left":0.6072141,"top":0.4660814,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Private beach area: 15 properties","depth":12,"bounds":{"left":0.6072141,"top":0.49002394,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Playground: 19 properties","depth":12,"bounds":{"left":0.6072141,"top":0.5139665,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Windsurfing: 11 properties","depth":12,"bounds":{"left":0.6072141,"top":0.53790903,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Travel group","depth":13,"bounds":{"left":0.6072141,"top":0.5798085,"width":0.028756648,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Pet friendly: 18 properties","depth":12,"bounds":{"left":0.6072141,"top":0.5977654,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Family-Friendly Properties: 15 properties","depth":12,"bounds":{"left":0.6072141,"top":0.60814047,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Bed preference","depth":13,"bounds":{"left":0.6072141,"top":0.6500399,"width":0.03523936,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Cribs: 4 properties","depth":12,"bounds":{"left":0.6072141,"top":0.6679968,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Double bed: 60 properties","depth":12,"bounds":{"left":0.6072141,"top":0.69193935,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Twin beds: 31 properties","depth":12,"bounds":{"left":0.6072141,"top":0.7158819,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Highly rated features","depth":13,"bounds":{"left":0.6072141,"top":0.7577813,"width":0.048537236,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Based on guest reviews","depth":13,"bounds":{"left":0.6072141,"top":0.77374303,"width":0.04454787,"height":0.011971269},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Very good breakfast: 1 property","depth":12,"bounds":{"left":0.6072141,"top":0.79010373,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Online Payment","depth":13,"bounds":{"left":0.6072141,"top":0.8320032,"width":0.036070477,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Accepts online payments: 41 properties","depth":12,"bounds":{"left":0.6072141,"top":0.8499601,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Property Accessibility","depth":13,"bounds":{"left":0.6072141,"top":0.89185953,"width":0.05069814,"height":0.013567438},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Bathroom emergency cord: 1 property","depth":12,"bounds":{"left":0.6072141,"top":0.90981644,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Toilet with grab rails: 1 property","depth":12,"bounds":{"left":0.6072141,"top":0.933759,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Lowered sink: 1 property","depth":12,"bounds":{"left":0.6072141,"top":0.94493216,"width":0.0003324468,"height":0.0007980846},"on_screen":true,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Room Accessibility","depth":13,"bounds":{"left":0.6072141,"top":0.9868316,"width":0.043550532,"height":0.013168395},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Entire unit located on ground floor: 12 properties","depth":12,"bounds":{"left":0.6072141,"top":1.0,"width":0.0003324468,"height":-0.004788518},"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Upper floors accessible by elevator: 9 properties","depth":12,"bounds":{"left":0.6072141,"top":1.0,"width":0.0003324468,"height":-0.044692755},"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Entire unit wheelchair accessible: 6 properties","depth":12,"bounds":{"left":0.6072141,"top":1.0,"width":0.0003324468,"height":-0.08459699},"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Roll-in shower: 1 property","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Emergency cord in bathroom: 1 property","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Shower chair: 1 property","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Walk-in shower: 13 properties","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Raised toilet: 2 properties","depth":12,"on_screen":false,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Search results updated. Lozenets: 66 properties found. Sorted by: Top picks for long stays.","depth":9,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Lozenets: 66 properties found","depth":10,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"List","depth":10,"on_screen":false,"help_text":"","role_description":"radio button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"List","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Grid","depth":10,"on_screen":false,"help_text":"","role_description":"radio button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Grid","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sort by: Top picks for long stays","depth":11,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Sort by:","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Top picks for long stays","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close banner","depth":12,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Commission paid on bookings, and other factors can affect property rankings. Learn about these ranking parameters and how to select and modify them.","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn more","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn more","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Browse the results for Lozenets","depth":11,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Save this item to a trip list","depth":14,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Family Hotel Kontesa Opens in new window","depth":12,"on_screen":false,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"Family Hotel Kontesa Opens in new window","depth":13,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Family Hotel Kontesa","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Opens in new window","depth":15,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"3 out of 5","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Lozenets·Show on map","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Lozenets","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"·","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Show on map","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"·","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"100 m from downtown","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"·","depth":12,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Beach Nearby","depth":13,"on_screen":false,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"300 m from beach","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Scored 9.8 Exceptional 196 reviews","depth":11,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Scored 9.8","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Exceptional","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"196 reviews","depth":14,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Comfort: Scored 9.8","depth":12,"on_screen":false,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Comfort","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"9.8","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Recommended for your group","depth":13,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
9082921408005096728
|
4436132614917977110
|
visual_change
|
accessibility
|
NULL
|
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
Getting Started DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
Getting Started · AFFiNE
Getting Started · AFFiNE
Screenpipe — Archive
Screenpipe — Archive
Download screenpipe — get started in minutes
Download screenpipe — get started in minutes
Self-Hosted Software and Apps
Self-Hosted Software and Apps
New Tab
New Tab
Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - [EMAIL] - Gmail
Помогнете ни да развиваме My Vivacom – Вашето мнение е важно - [EMAIL] - Gmail
Завеждане на щета онлайн | Euroins
Завеждане на щета онлайн | Euroins
Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii
Kontakt | Veľvyslanectvo Slovenskej republiky v Sofii
Nginx Proxy Manager
Nginx Proxy Manager
Location Logger
Location Logger
Providers - Admin - authentik
Providers - Admin - authentik
Booking.com: Hotels in Lozenets. Book your hotel now!
Booking.com: Hotels in Lozenets. Book your hotel now!
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Skip to main content
Skip to main content
Booking.com
Prices in Euro
EUR
Language: English (US)
Customer support
List your property
List your property
Register an account
Register
Sign in
Sign in
Stays
Stays
Flights
Flights
Flight + Hotel
Flight + Hotel
Car rental
Car rental
Attractions
Attractions
Airport taxis
Airport taxis
Lozenets
Lozenets
Clear
Fri, Jun 26 — Sun, Jul 5
Fri, Jun 26
—
Sun, Jul 5
Number of travelers and rooms. Currently selected: 2 adults · 2 children · 1 room
2 adults · 2 children · 1 room
Search
Search
Home
Home
Bulgaria
Bulgaria
Burgas Province
Burgas Province
Lozenets
Lozenets
Search results
Show on map
Show on map
Filter by:
Filter by:
Your budget (per night)
€ 30 – € 400+
Popular filters
Beachfront: 26 properties
Swimming pool: 34 properties
Breakfast & dinner included: 1 property
Villas: 7 properties
Breakfast included: 14 properties
Free Wifi: 59 properties
Parking: 53 properties
Apartments: 25 properties
Smart filters
What are you looking for?
What are you looking for?
Find properties
Find properties
Meals
Breakfast included: 14 properties
Breakfast & dinner included: 1 property
Kitchen facilities: 40 properties
Property Type
Hotels: 23 properties
Apartments: 25 properties
Vacation Homes: 2 properties
Resorts: 2 properties
Villas: 7 properties
Resort Villages: 1 property
Guesthouses: 9 properties
Family-Friendly Properties: 15 properties
Entire homes & apartments: 44 properties
Bedrooms and bathrooms
Bedrooms
Bathrooms
Facilities
Swimming pool: 34 properties
Parking: 53 properties
Free Wifi: 59 properties
Spa: 6 properties
Hot tub/Jacuzzi: 9 properties
Show all 13
Show all 13
Room facilities
Kitchen/Kitchenette: 40 properties
Air conditioning: 62 properties
Sea view: 26 properties
Washing machine: 24 properties
Balcony: 57 properties
Show all 25
Show all 25
Beach Access
Beachfront: 26 properties
Review score
Wonderful: 9+: 35 properties
Very Good: 8+: 46 properties
Good: 7+: 53 properties
Pleasant: 6+: 55 properties
Property rating
Find high-quality hotels and vacation rentals
1 star: 5 properties
2 stars: 9 properties
3 stars: 23 properties
4 stars: 8 properties
5 stars: 1 property
Reservation policy
Free cancellation: 56 properties
Book without credit card: 1 property
Distance from center of Lozenets
Less than 1 km: 55 properties
Less than 3 km: 65 properties
Less than 5 km: 66 properties
Fun Things To Do
Beach: 39 properties
Tennis equipment: 11 properties
Private beach area: 15 properties
Playground: 19 properties
Windsurfing: 11 properties
Travel group
Pet friendly: 18 properties
Family-Friendly Properties: 15 properties
Bed preference
Cribs: 4 properties
Double bed: 60 properties
Twin beds: 31 properties
Highly rated features
Based on guest reviews
Very good breakfast: 1 property
Online Payment
Accepts online payments: 41 properties
Property Accessibility
Bathroom emergency cord: 1 property
Toilet with grab rails: 1 property
Lowered sink: 1 property
Room Accessibility
Entire unit located on ground floor: 12 properties
Upper floors accessible by elevator: 9 properties
Entire unit wheelchair accessible: 6 properties
Roll-in shower: 1 property
Emergency cord in bathroom: 1 property
Shower chair: 1 property
Walk-in shower: 13 properties
Raised toilet: 2 properties
Search results updated. Lozenets: 66 properties found. Sorted by: Top picks for long stays.
Lozenets: 66 properties found
List
List
Grid
Grid
Sort by: Top picks for long stays
Sort by:
Top picks for long stays
Close banner
Commission paid on bookings, and other factors can affect property rankings. Learn about these ranking parameters and how to select and modify them.
Learn more
Learn more
Browse the results for Lozenets
Save this item to a trip list
Family Hotel Kontesa Opens in new window
Family Hotel Kontesa Opens in new window
Family Hotel Kontesa
Opens in new window
3 out of 5
Lozenets·Show on map
Lozenets
·
Show on map
·
100 m from downtown
·
Beach Nearby
300 m from beach
Scored 9.8 Exceptional 196 reviews
Scored 9.8
Exceptional
196 reviews
Comfort: Scored 9.8
Comfort
9.8
Recommended for your group...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
56912
|
NULL
|
0
|
2026-05-19T08:38:31.836823+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779179911836_m2.jpg...
|
PhpStorm
|
faVsco.js – AskAnythingPromptService.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhostormViewINavicarecodeTOOISWindowmelpFV faVsco. PhostormViewINavicarecodeTOOISWindowmelpFV faVsco.js°9 JY-20676-delete-rProiectC ActivityController.ongphp api.php© AskAnythingController.phpD AskAnything© AskAnythingPromptService.php X© AskAnythingPrompt.phpphp api_v2.phpvm Dtosc) Automateakeport.pnp© AutomatedReportsService.php© AskAnythingPromptDto.phpD eventsC) AskAnythingPro) search.phpAsKAnytningPromptservice.ong<?phpchistorvservice.ono0 AskJiminnyAiD AWSw cachew country1 Dataoase→ DatadogN DateTtimeN DealinsiahtsN DealRisksIM SlacticSearchM SloquentEncodingD EncryptionM Saken1 FeaturerlagsWrrMpegD FileSystemC Gong- GuzzleHttp0 KeyPointsW KIOSKDLoCKS2 MediaPioeline/ MobileSettinasn NudaeM Paragranh BreakerM PartitionedCookieM PlavbackPadeM PlavlistPropheti DronhotAfM DrosnorWorkeMAuoncdeclare(strict types=1):namesoace Jaminnv comoonent Askanvthino?› use ...class AskAnythingPromptServicepublic function __construct(private readonly AskAnythingRepository $askAnythingRepository.private readonly UserRepository $userRepository,private readonly GroupRepositoryInterface $groupRepository.4...}* @return array<AskAnythingPromptDto>public function get(User Suser. AskAnythingPromptTarget Starqet): array$prompts = Sthis->askAnythingRepository->findPromptsByUserAndTarget(stargetsoromotitos =foreach (Sprompts as Spromot) {if (soromot->aetOwnero == nulb <SownerUuid = Soromot->aetowner@->cetluido:SshareGrouns = nwu.Provide usens and arouns onlv if ownen of the nromnt is current usenif ($prompt->getOwnerId() === $user->getId()) {Scharelisens. SchareGrounsi= Sthis->aetReceiverlluids/Snromnt)*$promptDtos[] = new AskAnythingPromptDto(Snnomnt-Sao+lluid?$prompt->qetTitleO.Snnomn+-sao+Contont^)starget.sowneruuidAccept File &+X Reject File 4%€+ 2 of 3 files →es. (today 10:00)# Support Daily - in 3 h 22 m100% 5• Tue 19 May 11:38:3*AskJiminnyReportActivityServiceTest -= custom.log= laravel.log4 SF jiminny@localhost]4 HS_local [jiminny@localhost]& console [PROD]# console [euyCascadeA console [STAGING]© CoachingFeedbackCoachUserln.php XAsk Jiminny Report M+0 ..stoheAskAnythingPromptService.phpdeclare(scrict_cypes=l)nInought tor osReadAskAnvthinaPromotServicelest.0no # 44-223namespace Jiminny Component Activ1tySearch Filterder1n1t1on:Thought for 1s› use ...AskAnythingPromptServiceTest.php+24 -2final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterfaceSummarv of Revisions1usadeorivate const int No GROUP 10 = 999orivate UserRenository SuserRenository:public function__construct(UserRepository $userRepository)1...h29 Ф >public function shouldApplyQueries: boolf...}34 0 >public function getQueries: FilterDefinitionQueryCollection{...h45 đ >public function toArray: array{...hprivate function getOptions(): array{...}public function getValue: array{...}private function getDefaultValue: array{...}135136 ct ›public function aetValidationRules(2strina Sorefix = null): arrav{...?l146 đt ›public function aetSortOrder@: intf...}151 G>public function shouldBeIncluded(Team $team): bool{...}1. Searchtiranstormer now emits has renortslSearchTransformer.nhn. 42-50_Searchtranstormer.php:42-50public tunction transtorm(search Ssearch): arrayreturn П"Tilters = Sthis->getrilters(Ssearch),'has reports' => Ssearch->automatedReportso->exists.You reverted the Sappends laccessor on the Search model ((correctlv — addina it would have caused unnecessary querieseverywhere the model is serialized). The flag now lives only in the transformer used by listActivitySearch.2. Rethought the prompt DTOYou're riaht - newlv-created and edited oromots will never have related reports, and most existina oromots won't have anv• Made AskAnythingPromptDto::ShasReports nullable ?bool ShasReports = null)• Onlv included it in toArravo when it is not null — same conditional pattern as ownerid / sharellsers / shareGrouos |• Removed it from create() and edit( ) DTO construction in AskAnythingPromptService - they always pass nothingnow. so create/undate responses won't include has renorts•In get(), it stays — calls $prompt->getHasReports() (your renamed accessor) so the list endpoint emits the flag.This way the per-row exists() auery is oniv run when the list endooint is hit. never on createledit.3. Test uodateUpdated testGetAskAnythingPrompts in AskAnythingPromptServiceTest.php to mock getHasReports() on everyoromot mock and reflect the values (one true, three false ) in the expected DTOs. The existina testCreateAskAnvthinaPromptWithTwoUsers. testEditAskAnythingPrompt. etc. don't need changes - they already construct expected DTOswithout an 8th araument. which now matches the nuli default.G..l..3 files +30 -4>Accent alliAsk anvthina (884-L)<> Code Claude Qnus 4.7 MediumWN Windsurf Teams50-26UTF.8io 4 spaces...
|
NULL
|
-3531246519512689421
|
NULL
|
click
|
ocr
|
NULL
|
PhostormViewINavicarecodeTOOISWindowmelpFV faVsco. PhostormViewINavicarecodeTOOISWindowmelpFV faVsco.js°9 JY-20676-delete-rProiectC ActivityController.ongphp api.php© AskAnythingController.phpD AskAnything© AskAnythingPromptService.php X© AskAnythingPrompt.phpphp api_v2.phpvm Dtosc) Automateakeport.pnp© AutomatedReportsService.php© AskAnythingPromptDto.phpD eventsC) AskAnythingPro) search.phpAsKAnytningPromptservice.ong<?phpchistorvservice.ono0 AskJiminnyAiD AWSw cachew country1 Dataoase→ DatadogN DateTtimeN DealinsiahtsN DealRisksIM SlacticSearchM SloquentEncodingD EncryptionM Saken1 FeaturerlagsWrrMpegD FileSystemC Gong- GuzzleHttp0 KeyPointsW KIOSKDLoCKS2 MediaPioeline/ MobileSettinasn NudaeM Paragranh BreakerM PartitionedCookieM PlavbackPadeM PlavlistPropheti DronhotAfM DrosnorWorkeMAuoncdeclare(strict types=1):namesoace Jaminnv comoonent Askanvthino?› use ...class AskAnythingPromptServicepublic function __construct(private readonly AskAnythingRepository $askAnythingRepository.private readonly UserRepository $userRepository,private readonly GroupRepositoryInterface $groupRepository.4...}* @return array<AskAnythingPromptDto>public function get(User Suser. AskAnythingPromptTarget Starqet): array$prompts = Sthis->askAnythingRepository->findPromptsByUserAndTarget(stargetsoromotitos =foreach (Sprompts as Spromot) {if (soromot->aetOwnero == nulb <SownerUuid = Soromot->aetowner@->cetluido:SshareGrouns = nwu.Provide usens and arouns onlv if ownen of the nromnt is current usenif ($prompt->getOwnerId() === $user->getId()) {Scharelisens. SchareGrounsi= Sthis->aetReceiverlluids/Snromnt)*$promptDtos[] = new AskAnythingPromptDto(Snnomnt-Sao+lluid?$prompt->qetTitleO.Snnomn+-sao+Contont^)starget.sowneruuidAccept File &+X Reject File 4%€+ 2 of 3 files →es. (today 10:00)# Support Daily - in 3 h 22 m100% 5• Tue 19 May 11:38:3*AskJiminnyReportActivityServiceTest -= custom.log= laravel.log4 SF jiminny@localhost]4 HS_local [jiminny@localhost]& console [PROD]# console [euyCascadeA console [STAGING]© CoachingFeedbackCoachUserln.php XAsk Jiminny Report M+0 ..stoheAskAnythingPromptService.phpdeclare(scrict_cypes=l)nInought tor osReadAskAnvthinaPromotServicelest.0no # 44-223namespace Jiminny Component Activ1tySearch Filterder1n1t1on:Thought for 1s› use ...AskAnythingPromptServiceTest.php+24 -2final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterfaceSummarv of Revisions1usadeorivate const int No GROUP 10 = 999orivate UserRenository SuserRenository:public function__construct(UserRepository $userRepository)1...h29 Ф >public function shouldApplyQueries: boolf...}34 0 >public function getQueries: FilterDefinitionQueryCollection{...h45 đ >public function toArray: array{...hprivate function getOptions(): array{...}public function getValue: array{...}private function getDefaultValue: array{...}135136 ct ›public function aetValidationRules(2strina Sorefix = null): arrav{...?l146 đt ›public function aetSortOrder@: intf...}151 G>public function shouldBeIncluded(Team $team): bool{...}1. Searchtiranstormer now emits has renortslSearchTransformer.nhn. 42-50_Searchtranstormer.php:42-50public tunction transtorm(search Ssearch): arrayreturn П"Tilters = Sthis->getrilters(Ssearch),'has reports' => Ssearch->automatedReportso->exists.You reverted the Sappends laccessor on the Search model ((correctlv — addina it would have caused unnecessary querieseverywhere the model is serialized). The flag now lives only in the transformer used by listActivitySearch.2. Rethought the prompt DTOYou're riaht - newlv-created and edited oromots will never have related reports, and most existina oromots won't have anv• Made AskAnythingPromptDto::ShasReports nullable ?bool ShasReports = null)• Onlv included it in toArravo when it is not null — same conditional pattern as ownerid / sharellsers / shareGrouos |• Removed it from create() and edit( ) DTO construction in AskAnythingPromptService - they always pass nothingnow. so create/undate responses won't include has renorts•In get(), it stays — calls $prompt->getHasReports() (your renamed accessor) so the list endpoint emits the flag.This way the per-row exists() auery is oniv run when the list endooint is hit. never on createledit.3. Test uodateUpdated testGetAskAnythingPrompts in AskAnythingPromptServiceTest.php to mock getHasReports() on everyoromot mock and reflect the values (one true, three false ) in the expected DTOs. The existina testCreateAskAnvthinaPromptWithTwoUsers. testEditAskAnythingPrompt. etc. don't need changes - they already construct expected DTOswithout an 8th araument. which now matches the nuli default.G..l..3 files +30 -4>Accent alliAsk anvthina (884-L)<> Code Claude Qnus 4.7 MediumWN Windsurf Teams50-26UTF.8io 4 spaces...
|
56910
|
NULL
|
NULL
|
NULL
|
|
56911
|
NULL
|
0
|
2026-05-19T08:38:31.865690+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779179911865_m1.jpg...
|
PhpStorm
|
faVsco.js – AskAnythingPromptService.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpAPPDOCKER• ₴1D SlackFileEditViewGoHistoryWindowHelpAPPDOCKER• ₴1DEV (-zsh)₴82app/Jobs/Crm/MatchActivityCrmData.phpapp/Jobs/Middleware/HandleHubspotRateLimit.phpAPP (-zst47++++++p42++++++*app/Mcp/Servers/JiminnyServer.phpapp/Mcp/Tools/GetMeTool.php157++++++•app/Models/Feature/FeatureEnum.phpapp/Services/Activity/HubSpot/ProviderResolver.php+-app/Services/Activity/HubSpot/ProviderResolverInterface.phpapp/Services/Activity/HubSpot/Providers/Provider.phpapp/Services/Activity/HubSpot/Providers/ProviderKixie.php+-app/Services/Activity/HubSpot/Providers/Provider0rum.phpapp/Services/Activity/HubSpot/Providers/ProviderTwilio.phpapp/Services/Activity/HubSpot/Providers/ProviderTwilioFlex.phpapp/Services/Activity/HubSpot/Service.phpapp/Services/Crm/Hubspot/Client.phpapp/Services/Crm/Hubspot/HubspotClientInterface.phpapp/Services/Crm/Hubspot/Pagination/HubspotPaginationService.phpapp/Services/Crm/Hubspot/Pagination/PaginationState.phpdatabase/migrations/2026_05_13_124153_create_mcp_feature_flag.phptests/Feature/Mcp/GetMeToolFeatureTest.phptests/Feature/Mcp/ListCallsToolFeatureTest.phptests/Feature/Mcp/McpTestHelpersTrait.phptests/Unit/Component/ES/ChunkSizeTest.phptests/Unit/Component/ES/Processor/DT0s/SelectionListTest.phptests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.phptests/Unit/Component/MeetingBot/Service/ParticipantMatcherTest.phptests/Unit/Exceptions/RateLimitExceptionTest.phptests/Unit/Jobs/Crm/MatchActivityCrmDataTest.phptests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.phptests/Unit/Services/Activity/HubSpot/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ClientTest.phptests/Unit/Services/Crm/Hubspot/Pagination/HubspotPaginationServiceTest.php97++++++-132++++++•15++++++21++++--2+-25++++++.140++++++•2+-19++++++50++++++-27++++++-39++++++-6856++++++-+-151++++++-109++++++-250++++++-283++++++=37 files changed, 1587 insertions(+), 344 deletions(-)create mode 100644 app/Component/ES/ChunkSize.phpcreate mode 100644 app/Jobs/Middleware/HandleHubspotRateLimit.phpcreate mode 100644 app/Mcp/Tools/GetMeTool.phpcreate mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.phpcreate mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.phpcreate mode 100644 tests/Unit/Component/ES/ChunkSizeTest.phpcreate mode 100644 tests/Unit/Exceptions/RateLimitExceptionTest.phpcreate mode 100644 tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.phplukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pullAlready up to date.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20676-delete-reSwitched to a new branch 'JY-20676-delete-report-related-objects'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20676-delete-report-related-obHomeDMsActivityFilesLaterMore> 0EDJiminny ...# Jiminny-Dg# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi...• Direct messages€. Vasil Vasilev8. Nikolay Yankov®. Galya Dimitrova. Aneliya Angelovaão Stefka Stoyanova. Stoyan Tomovd Todor Stamatov "Kd. Mario GeorgievNikolay Ivanovdo James Graham2 Stoyan TanevRo Steliyan GeorgievLukas Kovalik y... OAppsJira CloudToastSupport Daily • in 3 h 22 m100% <73• Tue 19 May 11:38:31Describe what you are looking forNikolay Yankov6 0MessagesAdd canvasO Files+Nikolay YankovYesterday ~имаше ли нещь . y-..-Lukas Kovalik 2:28 PMтрябва да си вързан към SF да работиNikolay Yankov 2:28 PMaxaaaNikolay Yankov 2:41 PMимаме approve на PRда го даваме за QA?Lukas Kovalik 2:42 PMдаNikolay Yankov 3:02 PMтестове фейлватрьннах го 2 пътиToday ~Nikolay Yankov 10:05 AM/api/v2/user/ask-anything-prompts?target=on_demandhas_reports/api/v2/user/ask-anything-prompts/3381a35f-f1a3-431d-9510-bd079cd80ed6DELETE/api/vl/activity/saved-searchMessage Nikolay Yankov...
|
NULL
|
-1194862087907702114
|
NULL
|
click
|
ocr
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpAPPDOCKER• ₴1D SlackFileEditViewGoHistoryWindowHelpAPPDOCKER• ₴1DEV (-zsh)₴82app/Jobs/Crm/MatchActivityCrmData.phpapp/Jobs/Middleware/HandleHubspotRateLimit.phpAPP (-zst47++++++p42++++++*app/Mcp/Servers/JiminnyServer.phpapp/Mcp/Tools/GetMeTool.php157++++++•app/Models/Feature/FeatureEnum.phpapp/Services/Activity/HubSpot/ProviderResolver.php+-app/Services/Activity/HubSpot/ProviderResolverInterface.phpapp/Services/Activity/HubSpot/Providers/Provider.phpapp/Services/Activity/HubSpot/Providers/ProviderKixie.php+-app/Services/Activity/HubSpot/Providers/Provider0rum.phpapp/Services/Activity/HubSpot/Providers/ProviderTwilio.phpapp/Services/Activity/HubSpot/Providers/ProviderTwilioFlex.phpapp/Services/Activity/HubSpot/Service.phpapp/Services/Crm/Hubspot/Client.phpapp/Services/Crm/Hubspot/HubspotClientInterface.phpapp/Services/Crm/Hubspot/Pagination/HubspotPaginationService.phpapp/Services/Crm/Hubspot/Pagination/PaginationState.phpdatabase/migrations/2026_05_13_124153_create_mcp_feature_flag.phptests/Feature/Mcp/GetMeToolFeatureTest.phptests/Feature/Mcp/ListCallsToolFeatureTest.phptests/Feature/Mcp/McpTestHelpersTrait.phptests/Unit/Component/ES/ChunkSizeTest.phptests/Unit/Component/ES/Processor/DT0s/SelectionListTest.phptests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.phptests/Unit/Component/MeetingBot/Service/ParticipantMatcherTest.phptests/Unit/Exceptions/RateLimitExceptionTest.phptests/Unit/Jobs/Crm/MatchActivityCrmDataTest.phptests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.phptests/Unit/Services/Activity/HubSpot/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ClientTest.phptests/Unit/Services/Crm/Hubspot/Pagination/HubspotPaginationServiceTest.php97++++++-132++++++•15++++++21++++--2+-25++++++.140++++++•2+-19++++++50++++++-27++++++-39++++++-6856++++++-+-151++++++-109++++++-250++++++-283++++++=37 files changed, 1587 insertions(+), 344 deletions(-)create mode 100644 app/Component/ES/ChunkSize.phpcreate mode 100644 app/Jobs/Middleware/HandleHubspotRateLimit.phpcreate mode 100644 app/Mcp/Tools/GetMeTool.phpcreate mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.phpcreate mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.phpcreate mode 100644 tests/Unit/Component/ES/ChunkSizeTest.phpcreate mode 100644 tests/Unit/Exceptions/RateLimitExceptionTest.phpcreate mode 100644 tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.phplukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pullAlready up to date.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20676-delete-reSwitched to a new branch 'JY-20676-delete-report-related-objects'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20676-delete-report-related-obHomeDMsActivityFilesLaterMore> 0EDJiminny ...# Jiminny-Dg# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi...• Direct messages€. Vasil Vasilev8. Nikolay Yankov®. Galya Dimitrova. Aneliya Angelovaão Stefka Stoyanova. Stoyan Tomovd Todor Stamatov "Kd. Mario GeorgievNikolay Ivanovdo James Graham2 Stoyan TanevRo Steliyan GeorgievLukas Kovalik y... OAppsJira CloudToastSupport Daily • in 3 h 22 m100% <73• Tue 19 May 11:38:31Describe what you are looking forNikolay Yankov6 0MessagesAdd canvasO Files+Nikolay YankovYesterday ~имаше ли нещь . y-..-Lukas Kovalik 2:28 PMтрябва да си вързан към SF да работиNikolay Yankov 2:28 PMaxaaaNikolay Yankov 2:41 PMимаме approve на PRда го даваме за QA?Lukas Kovalik 2:42 PMдаNikolay Yankov 3:02 PMтестове фейлватрьннах го 2 пътиToday ~Nikolay Yankov 10:05 AM/api/v2/user/ask-anything-prompts?target=on_demandhas_reports/api/v2/user/ask-anything-prompts/3381a35f-f1a3-431d-9510-bd079cd80ed6DELETE/api/vl/activity/saved-searchMessage Nikolay Yankov...
|
56908
|
NULL
|
NULL
|
NULL
|
|
56850
|
NULL
|
0
|
2026-05-19T08:33:17.074008+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779179597074_m1.jpg...
|
PhpStorm
|
faVsco.js – AskAnythingPromptServiceTest.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20676-delete-report-re Project: faVsco.js, menu
JY-20676-delete-report-related-objects, 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
6
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Component\AskAnything;
use Illuminate\Database\Eloquent\Collection;
use Jiminny\Component\AskAnything\AskAnythingPromptService;
use Jiminny\Component\AskAnything\Dtos\AskAnythingPromptDto;
use Jiminny\Contracts\Repositories\GroupRepositoryInterface;
use Jiminny\Models\AskAnything\AskAnythingPrompt;
use Jiminny\Models\AskAnything\AskAnythingPromptTarget;
use Jiminny\Models\AskAnything\UserAskAnythingPrompt;
use Jiminny\Models\Group;
use Jiminny\Models\User;
use Jiminny\Repositories\AskAnythingRepository;
use Jiminny\Repositories\UserRepository;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
use Tests\Unit\Traits\TestPrivateMethod;
class AskAnythingPromptServiceTest extends TestCase
{
use TestPrivateMethod;
private AskAnythingPromptService $askAnythingPromptService;
private AskAnythingRepository&MockObject $askAnythingRepository;
private UserRepository&MockObject $userRepository;
private GroupRepositoryInterface&MockObject $groupRepository;
protected function setUp(): void
{
$this->askAnythingRepository = $this->createMock(AskAnythingRepository::class);
$this->userRepository = $this->createMock(UserRepository::class);
$this->groupRepository = $this->createMock(GroupRepositoryInterface::class);
$this->askAnythingPromptService = new AskAnythingPromptService(
$this->askAnythingRepository,
$this->userRepository,
$this->groupRepository
);
}
public function testGetAskAnythingPrompts(): void
{
$user = $this->createMock(User::class);
$user->expects($this->any())
->method('getId')
->willReturn(1);
$user->expects($this->any())
->method('getUuid')
->willReturn('1');
$defaultPrompt = $this->createMock(AskAnythingPrompt::class);
$defaultPrompt->expects($this->once())
->method('getOwner')
->willReturn(null);
$defaultPrompt->expects($this->once())
->method('getUuid')
->willReturn('default-uuid');
$defaultPrompt->expects($this->once())
->method('getTitle')
->willReturn('Sentiment');
$defaultPrompt->expects($this->once())
->method('getContent')
->willReturn('What was the overall sentiment of the customer during the call?');
$defaultPrompt->expects($this->once())
->method('getHasReports')
->willReturn(false);
$promptOwnedByUser = $this->createMock(AskAnythingPrompt::class);
$promptOwnedByUser->expects($this->exactly(2))
->method('getOwner')
->willReturn($user);
$promptOwnedByUser->expects($this->once())
->method('getUuid')
->willReturn('uuid-1st-prompt');
$promptOwnedByUser->expects($this->once())
->method('getTitle')
->willReturn('First users prompt');
$promptOwnedByUser->expects($this->once())
->method('getContent')
->willReturn('Test prompt');
$promptOwnedByUser->expects($this->once())
->method('getId')
->willReturn(99);
$promptOwnedByUser->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$promptOwnedByUser->expects($this->once())
->method('getHasReports')
->willReturn(true);
$defaultPromptOrderedByUser = $this->createMock(AskAnythingPrompt::class);
$defaultPromptOrderedByUser->expects($this->once())
->method('getOwner')
->willReturn(null);
$defaultPromptOrderedByUser->expects($this->once())
->method('getUuid')
->willReturn('default-uuid');
$defaultPromptOrderedByUser->expects($this->once())
->method('getTitle')
->willReturn('Sentiment');
$defaultPromptOrderedByUser->expects($this->once())
->method('getContent')
->willReturn('What was the overall sentiment of the customer during the call?');
$defaultPromptOrderedByUser->expects($this->once())
->method('getHasReports')
->willReturn(false);
$promptOwnedByUserAndSharedWithGroup = $this->createMock(AskAnythingPrompt::class);
$promptOwnedByUserAndSharedWithGroup->expects($this->exactly(2))
->method('getOwner')
->willReturn($user);
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getUuid')
->willReturn('uuid-2nd-prompt');
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getTitle')
->willReturn('Prompt shared with group');
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getContent')
->willReturn('Test prompt that is shared with group');
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getId')
->willReturn(109);
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getHasReports')
->willReturn(false);
$group = $this->createMock(Group::class);
$group->expects($this->once())
->method('getUuid')
->willReturn('uuid-of-the-group');
$sharedWithGroup = $this->createMock(UserAskAnythingPrompt::class);
$sharedWithGroup->expects($this->once())
->method('getUser')
->willReturn(null);
$sharedWithGroup->expects($this->once())
->method('getGroup')
->willReturn($group);
$this->askAnythingRepository->expects($this->exactly(2))
->method('findSharedUsersAndGroupsByPromptId')
->willReturnMap([
[99, new Collection([])],
[109, new Collection([$sharedWithGroup])],
]);
$prompts = [$defaultPrompt, $promptOwnedByUser, $defaultPromptOrderedByUser, $promptOwnedByUserAndSharedWithGroup];
$this->askAnythingRepository->expects($this->once())
->method('findPromptsByUserAndTarget')
->willReturn(new Collection($prompts));
$expectedDto1 = new AskAnythingPromptDto(
'default-uuid',
'Sentiment',
'What was the overall sentiment of the customer during the call?',
AskAnythingPromptTarget::call,
null,
null,
null,
false,
);
$expectedDto2 = new AskAnythingPromptDto(
'uuid-1st-prompt',
'First users prompt',
'Test prompt',
AskAnythingPromptTarget::call,
'1',
[],
[],
true,
);
$expectedDto3 = new AskAnythingPromptDto(
'default-uuid',
'Sentiment',
'What was the overall sentiment of the customer during the call?',
AskAnythingPromptTarget::call,
null,
null,
null,
false,
);
$expectedDto4 = new AskAnythingPromptDto(
'uuid-2nd-prompt',
'Prompt shared with group',
'Test prompt that is shared with group',
AskAnythingPromptTarget::call,
'1',
[],
['uuid-of-the-group'],
false,
);
$dtos = $this->askAnythingPromptService->get($user, AskAnythingPromptTarget::call);
$this->assertEquals([$expectedDto1, $expectedDto2, $expectedDto3, $expectedDto4], $dtos);
}
public function testEditAskAnythingPrompt(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(123);
$prompt->expects($this->never())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(123);
$user->expects($this->once())
->method('getUuid')
->willReturn('owner-uuid');
$title = 'new title';
$content = 'new content';
$shareUsers = ['us-1'];
$shareGroups = ['gr-1', 'gr-2'];
$shareUser = $this->createMock(User::class);
$this->userRepository->expects($this->once())
->method('findByUuid')
->with('us-1')
->willReturn($shareUser);
$shareGroup1 = $this->createMock(Group::class);
$shareGroup2 = $this->createMock(Group::class);
$this->groupRepository->expects($this->exactly(2))
->method('findByUuid')
->willReturnMap([
['gr-1', $shareGroup1],
['gr-2', $shareGroup2],
]);
$editPrompt = $this->createMock(AskAnythingPrompt::class);
$editPrompt->expects($this->once())
->method('getTitle')
->willReturn($title);
$editPrompt->expects($this->once())
->method('getContent')
->willReturn($content);
$editPrompt->expects($this->once())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$editPrompt->expects($this->once())
->method('getUuid')
->willReturn('uuid-1st-prompt');
$this->askAnythingRepository->expects($this->once())
->method('editPrompt')
->with($prompt, $title, $content, [$shareUser], [$shareGroup1, $shareGroup2])
->willReturn($editPrompt);
$expectedDto = new AskAnythingPromptDto(
'uuid-1st-prompt',
$title,
$content,
AskAnythingPromptTarget::call,
'owner-uuid',
$shareUsers,
$shareGroups
);
$editDto = $this->askAnythingPromptService->edit($prompt, $user, $title, $content, $shareUsers, $shareGroups);
$this->assertEquals($expectedDto, $editDto);
}
public function testHideDefaultAndCreateAskAnythingPrompt(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(true);
$prompt->expects($this->once())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getUuid')
->willReturn('new-owner-uuid');
$title = 'title';
$content = 'content';
$shareUsers = ['us-1'];
$shareGroups = [];
$shareUser = $this->createMock(User::class);
$this->userRepository->expects($this->once())
->method('findByUuid')
->with('us-1')
->willReturn($shareUser);
$this->groupRepository->expects($this->never())
->method('findByUuid');
$newPrompt = $this->createMock(AskAnythingPrompt::class);
$newPrompt->expects($this->once())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$newPrompt->expects($this->once())
->method('getUuid')
->willReturn('uuid-1st-prompt');
$newPrompt->expects($this->once())
->method('getTitle')
->willReturn($title);
$newPrompt->expects($this->once())
->method('getContent')
->willReturn($content);
$this->askAnythingRepository->expects($this->once())
->method('hidePromptForUser');
$this->askAnythingRepository->expects($this->once())
->method('createPrompt')
->willReturn($newPrompt);
$expectedDto = new AskAnythingPromptDto(
'uuid-1st-prompt',
$title,
$content,
AskAnythingPromptTarget::call,
'new-owner-uuid',
$shareUsers,
$shareGroups
);
$actualDto = $this->askAnythingPromptService->edit($prompt, $user, $title, $content, $shareUsers, $shareGroups);
$this->assertEquals($expectedDto, $actualDto);
}
public function testDeleteAskAnythingPrompt(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->any())
->method('getId')
->willReturn(1);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
// Use Mockery for the relationship mock (more flexible)
$relationMock = \Mockery::mock(\Illuminate\Database\Eloquent\Relations\HasMany::class);
$relationMock->shouldReceive('withTrashed')
->once()
->andReturnSelf();
$relationMock->shouldReceive('update')
->once()
->with(['ask_anything_prompt_id' => null, 'status' => false]);
$prompt->expects($this->once())
->method('automatedReports')
->willReturn($relationMock);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(1);
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(1, $user)
->willReturn($userPrompt);
$userPrompt->expects($this->once())
->method('delete');
$this->askAnythingRepository->expects($this->any())
->method('findSharedUsersAndGroupsByPromptId')
->with(1)
->willReturn(new Collection([]));
$this->askAnythingRepository->expects($this->once())
->method('deletePrompt');
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testDeleteAskAnythingPromptWithRelations(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->any())
->method('getId')
->willReturn(1);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$user = $this->createMock(User::class);
$user->expects($this->any())
->method('getId')
->willReturn(1);
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(1, $user)
->willReturn($userPrompt);
$userPrompt->expects($this->once())
->method('delete');
$this->askAnythingRepository->expects($this->exactly(3))
->method('findSharedUsersAndGroupsByPromptId')
->willReturnMap([
[1, new Collection([$userPrompt])],
[1, new Collection([])],
]);
$this->askAnythingRepository->expects($this->never())
->method('deletePrompt');
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testHideDefaultAskAnythingPrompt(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(true);
$user = $this->createMock(User::class);
$this->askAnythingRepository->expects($this->once())
->method('hidePromptForUser');
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testHideSharedWithUserAskAnythingPrompt(): void
{
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$prompt->expects($this->exactly(3))
->method('getId')
->willReturn(33);
$relationMock = \Mockery::mock(\Illuminate\Database\Eloquent\Relations\HasMany::class);
$relationMock->shouldReceive('withTrashed')
->once()
->andReturnSelf();
$relationMock->shouldReceive('update')
->once()
->with(['ask_anything_prompt_id' => null, 'status' => false]);
$prompt->expects($this->once())
->method('automatedReports')
->willReturn($relationMock);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(2);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(33, $user)
->willReturn($userPrompt);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUserGroup')
->with(33, $user)
->willReturn(null);
$userPrompt->expects($this->once())
->method('delete');
$this->askAnythingRepository->expects($this->once())
->method('findSharedUsersAndGroupsByPromptId')
->with(33)
->willReturn(new Collection([]));
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testHideSharedWithUserAndGroupAskAnythingPrompt(): void
{
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$prompt->expects($this->exactly(2))
->method('getId')
->willReturn(33);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(2);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(33, $user)
->willReturn($userPrompt);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUserGroup')
->with(33, $user)
->willReturn($userPrompt);
$userPrompt->expects($this->never())
->method('delete');
$this->askAnythingRepository->expects($this->once())
->method('hidePromptForUser')
->with($prompt, $user);
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testHideSharedWithGroupAskAnythingPrompt(): void
{
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$prompt->expects($this->exactly(2))
->method('getId')
->willReturn(33);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(2);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(33, $user)
->willReturn(null);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUserGroup')
->with(33, $user)
->willReturn($userPrompt);
$userPrompt->expects($this->never())
->method('delete');
$this->askAnythingRepository->expects($this->once())
->method('hidePromptForUser')
->with($prompt, $user);
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testDeleteWithNoSharesAndNotOwner(): void
{
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$prompt->expects($this->exactly(2))
->method('getId')
->willReturn(33);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(2);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(33, $user)
->willReturn(null);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUserGroup')
->with(33, $user)
->willReturn(null);
$userPrompt->expects($this->never())
->method('delete');
$this->askAnythingRepository->expects($this->never())
->method('hidePromptForUser');
$this->expectException(\InvalidArgumentException::class);
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testReorderAskAnythingPrompts(): void
{
$prompts = ['id1', 'id2', 'id3'];
$prompt1 = $this->createMock(AskAnythingPrompt::class);
$prompt2 = $this->createMock(AskAnythingPrompt::class);
$prompt3 = $this->createMock(AskAnythingPrompt::class);
$user = $this->createMock(User::class);
$this->askAnythingRepository->expects($this->exactly(3))
->method('getPromptByUuid')
->willReturnMap([
['id1', $prompt1],
['id2', $prompt2],
['id3', $prompt3],
]);
$this->askAnythingRepository->expects($this->exactly(3))
->method('orderPromptForUser')
->willReturnMap([
[[$prompt1, $user, 1]],
[[$prompt2, $user, 2]],
[[$prompt3, $user, 3]],
]);
$this->askAnythingPromptService->reorder($user, $prompts);
}
public function testCreateAskAnythingPromptWithTwoUsers(): void
{
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getUuid')
->willReturn('uuid-of-the-user');
$shareUser1 = $this->createMock(User::class);
$shareUser2 = $this->createMock(User::class);
$title = 'Test title';
$content = 'Test content';
$target = AskAnythingPromptTarget::call;
$shareUsers = ['us-1', 'us-2'];
$shareGroups = [];
$this->userRepository->expects($this->exactly(2))
->method('findByUuid')
->willReturnMap([
['us-1', $shareUser1],
['us-2', $shareUser2],
]);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('getUuid')
->willReturn('prompt-1-uuid');
$prompt->expects($this->once())
->method('getTitle')
->willReturn($title);
$prompt->expects($this->once())
->method('getContent')
->willReturn($content);
$this->askAnythingRepository->expects($this->once())
->method('createPrompt')
->with(
$user,
$target,
$title,
$content,
[$shareUser1, $shareUser2],
[],
)
->willReturn($prompt);
$expectedPromptDto = new AskAnythingPromptDto(
'prompt-1-uuid',
$title,
$content,
$target,
'uuid-of-the-user',
$shareUsers,
$shareGroups,
);
$actualPromptDto = $this->askAnythingPromptService->create(
$user,
$title,
$content,
$target,
$shareUsers,
$shareGroups
);
$this->assertEquals($expectedPromptDto, $actualPromptDto);
}
public function testRecreatePromptsForUserRelations(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('getId')
->willReturn(1);
$prompt->expects($this->once())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$prompt->expects($this->once())
->method('getTitle')
->willReturn('Test title');
$prompt->expects($this->once())
->method('getContent')
->willReturn('Test content');
$sharedPrompt = $this->createMock(UserAskAnythingPrompt::class);
$sharedUser = $this->createMock(User::class);
$sharedUser->expects($this->once())
->method('isStatusActive')
->willReturn(true);
$sharedUser->expects($this->once())
->method('getId')
->willReturn(1);
$sharedPrompt->expects($this->once())
->method('getUser')
->willReturn($sharedUser);
$sharedPrompt->expects($this->exactly(2))
->method('isRemoved')
->willReturn(false);
$sharedPrompt->expects($this->once())
->method('delete');
$this->askAnythingRepository->expects($this->once())
->method('findSharedUsersAndGroupsByPromptId')
->with(1)
->willReturn(new Collection([$sharedPrompt]));
$this->askAnythingRepository->expects($this->once())
->method('createPrompt');
$data = $this->invokePrivateMethod('recreatePromptsForUserRelations', $this->askAnythingPromptService, [$prompt]);
$this->assertEquals([[1], []], $data);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20676-delete-report-related-objects, menu","depth":5,"on_screen":true,"help_text":"Git Branch: JY-20676-delete-report-related-objects","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":"6","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.016666668,"height":0.02111111},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.02111111},"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.025555555},"on_screen":false,"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.0,"top":0.0,"width":0.014583333,"height":0.025555555},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Component\\AskAnything;\n\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Jiminny\\Component\\AskAnything\\AskAnythingPromptService;\nuse Jiminny\\Component\\AskAnything\\Dtos\\AskAnythingPromptDto;\nuse Jiminny\\Contracts\\Repositories\\GroupRepositoryInterface;\nuse Jiminny\\Models\\AskAnything\\AskAnythingPrompt;\nuse Jiminny\\Models\\AskAnything\\AskAnythingPromptTarget;\nuse Jiminny\\Models\\AskAnything\\UserAskAnythingPrompt;\nuse Jiminny\\Models\\Group;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AskAnythingRepository;\nuse Jiminny\\Repositories\\UserRepository;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Tests\\TestCase;\nuse Tests\\Unit\\Traits\\TestPrivateMethod;\n\nclass AskAnythingPromptServiceTest extends TestCase\n{\n use TestPrivateMethod;\n\n private AskAnythingPromptService $askAnythingPromptService;\n private AskAnythingRepository&MockObject $askAnythingRepository;\n private UserRepository&MockObject $userRepository;\n private GroupRepositoryInterface&MockObject $groupRepository;\n\n protected function setUp(): void\n {\n $this->askAnythingRepository = $this->createMock(AskAnythingRepository::class);\n $this->userRepository = $this->createMock(UserRepository::class);\n $this->groupRepository = $this->createMock(GroupRepositoryInterface::class);\n\n $this->askAnythingPromptService = new AskAnythingPromptService(\n $this->askAnythingRepository,\n $this->userRepository,\n $this->groupRepository\n );\n }\n\n public function testGetAskAnythingPrompts(): void\n {\n $user = $this->createMock(User::class);\n $user->expects($this->any())\n ->method('getId')\n ->willReturn(1);\n $user->expects($this->any())\n ->method('getUuid')\n ->willReturn('1');\n $defaultPrompt = $this->createMock(AskAnythingPrompt::class);\n $defaultPrompt->expects($this->once())\n ->method('getOwner')\n ->willReturn(null);\n $defaultPrompt->expects($this->once())\n ->method('getUuid')\n ->willReturn('default-uuid');\n $defaultPrompt->expects($this->once())\n ->method('getTitle')\n ->willReturn('Sentiment');\n $defaultPrompt->expects($this->once())\n ->method('getContent')\n ->willReturn('What was the overall sentiment of the customer during the call?');\n $defaultPrompt->expects($this->once())\n ->method('getHasReports')\n ->willReturn(false);\n $promptOwnedByUser = $this->createMock(AskAnythingPrompt::class);\n $promptOwnedByUser->expects($this->exactly(2))\n ->method('getOwner')\n ->willReturn($user);\n $promptOwnedByUser->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-1st-prompt');\n $promptOwnedByUser->expects($this->once())\n ->method('getTitle')\n ->willReturn('First users prompt');\n $promptOwnedByUser->expects($this->once())\n ->method('getContent')\n ->willReturn('Test prompt');\n $promptOwnedByUser->expects($this->once())\n ->method('getId')\n ->willReturn(99);\n $promptOwnedByUser->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $promptOwnedByUser->expects($this->once())\n ->method('getHasReports')\n ->willReturn(true);\n $defaultPromptOrderedByUser = $this->createMock(AskAnythingPrompt::class);\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getOwner')\n ->willReturn(null);\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getUuid')\n ->willReturn('default-uuid');\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getTitle')\n ->willReturn('Sentiment');\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getContent')\n ->willReturn('What was the overall sentiment of the customer during the call?');\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getHasReports')\n ->willReturn(false);\n $promptOwnedByUserAndSharedWithGroup = $this->createMock(AskAnythingPrompt::class);\n $promptOwnedByUserAndSharedWithGroup->expects($this->exactly(2))\n ->method('getOwner')\n ->willReturn($user);\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-2nd-prompt');\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getTitle')\n ->willReturn('Prompt shared with group');\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getContent')\n ->willReturn('Test prompt that is shared with group');\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getId')\n ->willReturn(109);\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getHasReports')\n ->willReturn(false);\n\n $group = $this->createMock(Group::class);\n $group->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-of-the-group');\n $sharedWithGroup = $this->createMock(UserAskAnythingPrompt::class);\n $sharedWithGroup->expects($this->once())\n ->method('getUser')\n ->willReturn(null);\n $sharedWithGroup->expects($this->once())\n ->method('getGroup')\n ->willReturn($group);\n\n $this->askAnythingRepository->expects($this->exactly(2))\n ->method('findSharedUsersAndGroupsByPromptId')\n ->willReturnMap([\n [99, new Collection([])],\n [109, new Collection([$sharedWithGroup])],\n ]);\n\n $prompts = [$defaultPrompt, $promptOwnedByUser, $defaultPromptOrderedByUser, $promptOwnedByUserAndSharedWithGroup];\n $this->askAnythingRepository->expects($this->once())\n ->method('findPromptsByUserAndTarget')\n ->willReturn(new Collection($prompts));\n\n $expectedDto1 = new AskAnythingPromptDto(\n 'default-uuid',\n 'Sentiment',\n 'What was the overall sentiment of the customer during the call?',\n AskAnythingPromptTarget::call,\n null,\n null,\n null,\n false,\n );\n $expectedDto2 = new AskAnythingPromptDto(\n 'uuid-1st-prompt',\n 'First users prompt',\n 'Test prompt',\n AskAnythingPromptTarget::call,\n '1',\n [],\n [],\n true,\n );\n $expectedDto3 = new AskAnythingPromptDto(\n 'default-uuid',\n 'Sentiment',\n 'What was the overall sentiment of the customer during the call?',\n AskAnythingPromptTarget::call,\n null,\n null,\n null,\n false,\n );\n $expectedDto4 = new AskAnythingPromptDto(\n 'uuid-2nd-prompt',\n 'Prompt shared with group',\n 'Test prompt that is shared with group',\n AskAnythingPromptTarget::call,\n '1',\n [],\n ['uuid-of-the-group'],\n false,\n );\n $dtos = $this->askAnythingPromptService->get($user, AskAnythingPromptTarget::call);\n\n $this->assertEquals([$expectedDto1, $expectedDto2, $expectedDto3, $expectedDto4], $dtos);\n }\n\n public function testEditAskAnythingPrompt(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(123);\n $prompt->expects($this->never())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(123);\n $user->expects($this->once())\n ->method('getUuid')\n ->willReturn('owner-uuid');\n\n $title = 'new title';\n $content = 'new content';\n $shareUsers = ['us-1'];\n $shareGroups = ['gr-1', 'gr-2'];\n\n $shareUser = $this->createMock(User::class);\n $this->userRepository->expects($this->once())\n ->method('findByUuid')\n ->with('us-1')\n ->willReturn($shareUser);\n $shareGroup1 = $this->createMock(Group::class);\n $shareGroup2 = $this->createMock(Group::class);\n $this->groupRepository->expects($this->exactly(2))\n ->method('findByUuid')\n ->willReturnMap([\n ['gr-1', $shareGroup1],\n ['gr-2', $shareGroup2],\n ]);\n\n $editPrompt = $this->createMock(AskAnythingPrompt::class);\n $editPrompt->expects($this->once())\n ->method('getTitle')\n ->willReturn($title);\n $editPrompt->expects($this->once())\n ->method('getContent')\n ->willReturn($content);\n $editPrompt->expects($this->once())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $editPrompt->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-1st-prompt');\n $this->askAnythingRepository->expects($this->once())\n ->method('editPrompt')\n ->with($prompt, $title, $content, [$shareUser], [$shareGroup1, $shareGroup2])\n ->willReturn($editPrompt);\n\n $expectedDto = new AskAnythingPromptDto(\n 'uuid-1st-prompt',\n $title,\n $content,\n AskAnythingPromptTarget::call,\n 'owner-uuid',\n $shareUsers,\n $shareGroups\n );\n $editDto = $this->askAnythingPromptService->edit($prompt, $user, $title, $content, $shareUsers, $shareGroups);\n\n $this->assertEquals($expectedDto, $editDto);\n }\n\n public function testHideDefaultAndCreateAskAnythingPrompt(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(true);\n $prompt->expects($this->once())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getUuid')\n ->willReturn('new-owner-uuid');\n $title = 'title';\n $content = 'content';\n $shareUsers = ['us-1'];\n $shareGroups = [];\n $shareUser = $this->createMock(User::class);\n $this->userRepository->expects($this->once())\n ->method('findByUuid')\n ->with('us-1')\n ->willReturn($shareUser);\n $this->groupRepository->expects($this->never())\n ->method('findByUuid');\n\n $newPrompt = $this->createMock(AskAnythingPrompt::class);\n $newPrompt->expects($this->once())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $newPrompt->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-1st-prompt');\n $newPrompt->expects($this->once())\n ->method('getTitle')\n ->willReturn($title);\n $newPrompt->expects($this->once())\n ->method('getContent')\n ->willReturn($content);\n\n $this->askAnythingRepository->expects($this->once())\n ->method('hidePromptForUser');\n $this->askAnythingRepository->expects($this->once())\n ->method('createPrompt')\n ->willReturn($newPrompt);\n\n $expectedDto = new AskAnythingPromptDto(\n 'uuid-1st-prompt',\n $title,\n $content,\n AskAnythingPromptTarget::call,\n 'new-owner-uuid',\n $shareUsers,\n $shareGroups\n );\n\n $actualDto = $this->askAnythingPromptService->edit($prompt, $user, $title, $content, $shareUsers, $shareGroups);\n\n $this->assertEquals($expectedDto, $actualDto);\n }\n\n public function testDeleteAskAnythingPrompt(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->any())\n ->method('getId')\n ->willReturn(1);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n\n // Use Mockery for the relationship mock (more flexible)\n $relationMock = \\Mockery::mock(\\Illuminate\\Database\\Eloquent\\Relations\\HasMany::class);\n $relationMock->shouldReceive('withTrashed')\n ->once()\n ->andReturnSelf();\n $relationMock->shouldReceive('update')\n ->once()\n ->with(['ask_anything_prompt_id' => null, 'status' => false]);\n\n $prompt->expects($this->once())\n ->method('automatedReports')\n ->willReturn($relationMock);\n\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(1);\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(1, $user)\n ->willReturn($userPrompt);\n $userPrompt->expects($this->once())\n ->method('delete');\n $this->askAnythingRepository->expects($this->any())\n ->method('findSharedUsersAndGroupsByPromptId')\n ->with(1)\n ->willReturn(new Collection([]));\n $this->askAnythingRepository->expects($this->once())\n ->method('deletePrompt');\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testDeleteAskAnythingPromptWithRelations(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->any())\n ->method('getId')\n ->willReturn(1);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $user = $this->createMock(User::class);\n $user->expects($this->any())\n ->method('getId')\n ->willReturn(1);\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(1, $user)\n ->willReturn($userPrompt);\n $userPrompt->expects($this->once())\n ->method('delete');\n $this->askAnythingRepository->expects($this->exactly(3))\n ->method('findSharedUsersAndGroupsByPromptId')\n ->willReturnMap([\n [1, new Collection([$userPrompt])],\n [1, new Collection([])],\n ]);\n $this->askAnythingRepository->expects($this->never())\n ->method('deletePrompt');\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testHideDefaultAskAnythingPrompt(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(true);\n $user = $this->createMock(User::class);\n $this->askAnythingRepository->expects($this->once())\n ->method('hidePromptForUser');\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testHideSharedWithUserAskAnythingPrompt(): void\n {\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $prompt->expects($this->exactly(3))\n ->method('getId')\n ->willReturn(33);\n\n $relationMock = \\Mockery::mock(\\Illuminate\\Database\\Eloquent\\Relations\\HasMany::class);\n $relationMock->shouldReceive('withTrashed')\n ->once()\n ->andReturnSelf();\n $relationMock->shouldReceive('update')\n ->once()\n ->with(['ask_anything_prompt_id' => null, 'status' => false]);\n $prompt->expects($this->once())\n ->method('automatedReports')\n ->willReturn($relationMock);\n\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(2);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(33, $user)\n ->willReturn($userPrompt);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUserGroup')\n ->with(33, $user)\n ->willReturn(null);\n $userPrompt->expects($this->once())\n ->method('delete');\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedUsersAndGroupsByPromptId')\n ->with(33)\n ->willReturn(new Collection([]));\n\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testHideSharedWithUserAndGroupAskAnythingPrompt(): void\n {\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $prompt->expects($this->exactly(2))\n ->method('getId')\n ->willReturn(33);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(2);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(33, $user)\n ->willReturn($userPrompt);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUserGroup')\n ->with(33, $user)\n ->willReturn($userPrompt);\n $userPrompt->expects($this->never())\n ->method('delete');\n $this->askAnythingRepository->expects($this->once())\n ->method('hidePromptForUser')\n ->with($prompt, $user);\n\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testHideSharedWithGroupAskAnythingPrompt(): void\n {\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $prompt->expects($this->exactly(2))\n ->method('getId')\n ->willReturn(33);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(2);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(33, $user)\n ->willReturn(null);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUserGroup')\n ->with(33, $user)\n ->willReturn($userPrompt);\n $userPrompt->expects($this->never())\n ->method('delete');\n $this->askAnythingRepository->expects($this->once())\n ->method('hidePromptForUser')\n ->with($prompt, $user);\n\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testDeleteWithNoSharesAndNotOwner(): void\n {\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $prompt->expects($this->exactly(2))\n ->method('getId')\n ->willReturn(33);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(2);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(33, $user)\n ->willReturn(null);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUserGroup')\n ->with(33, $user)\n ->willReturn(null);\n $userPrompt->expects($this->never())\n ->method('delete');\n $this->askAnythingRepository->expects($this->never())\n ->method('hidePromptForUser');\n\n $this->expectException(\\InvalidArgumentException::class);\n\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testReorderAskAnythingPrompts(): void\n {\n $prompts = ['id1', 'id2', 'id3'];\n $prompt1 = $this->createMock(AskAnythingPrompt::class);\n $prompt2 = $this->createMock(AskAnythingPrompt::class);\n $prompt3 = $this->createMock(AskAnythingPrompt::class);\n $user = $this->createMock(User::class);\n $this->askAnythingRepository->expects($this->exactly(3))\n ->method('getPromptByUuid')\n ->willReturnMap([\n ['id1', $prompt1],\n ['id2', $prompt2],\n ['id3', $prompt3],\n ]);\n $this->askAnythingRepository->expects($this->exactly(3))\n ->method('orderPromptForUser')\n ->willReturnMap([\n [[$prompt1, $user, 1]],\n [[$prompt2, $user, 2]],\n [[$prompt3, $user, 3]],\n ]);\n $this->askAnythingPromptService->reorder($user, $prompts);\n }\n\n public function testCreateAskAnythingPromptWithTwoUsers(): void\n {\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-of-the-user');\n $shareUser1 = $this->createMock(User::class);\n $shareUser2 = $this->createMock(User::class);\n $title = 'Test title';\n $content = 'Test content';\n $target = AskAnythingPromptTarget::call;\n $shareUsers = ['us-1', 'us-2'];\n $shareGroups = [];\n\n $this->userRepository->expects($this->exactly(2))\n ->method('findByUuid')\n ->willReturnMap([\n ['us-1', $shareUser1],\n ['us-2', $shareUser2],\n ]);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('getUuid')\n ->willReturn('prompt-1-uuid');\n $prompt->expects($this->once())\n ->method('getTitle')\n ->willReturn($title);\n $prompt->expects($this->once())\n ->method('getContent')\n ->willReturn($content);\n $this->askAnythingRepository->expects($this->once())\n ->method('createPrompt')\n ->with(\n $user,\n $target,\n $title,\n $content,\n [$shareUser1, $shareUser2],\n [],\n )\n ->willReturn($prompt);\n\n $expectedPromptDto = new AskAnythingPromptDto(\n 'prompt-1-uuid',\n $title,\n $content,\n $target,\n 'uuid-of-the-user',\n $shareUsers,\n $shareGroups,\n );\n\n $actualPromptDto = $this->askAnythingPromptService->create(\n $user,\n $title,\n $content,\n $target,\n $shareUsers,\n $shareGroups\n );\n\n $this->assertEquals($expectedPromptDto, $actualPromptDto);\n }\n\n public function testRecreatePromptsForUserRelations(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('getId')\n ->willReturn(1);\n $prompt->expects($this->once())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $prompt->expects($this->once())\n ->method('getTitle')\n ->willReturn('Test title');\n $prompt->expects($this->once())\n ->method('getContent')\n ->willReturn('Test content');\n\n $sharedPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $sharedUser = $this->createMock(User::class);\n $sharedUser->expects($this->once())\n ->method('isStatusActive')\n ->willReturn(true);\n $sharedUser->expects($this->once())\n ->method('getId')\n ->willReturn(1);\n\n $sharedPrompt->expects($this->once())\n ->method('getUser')\n ->willReturn($sharedUser);\n $sharedPrompt->expects($this->exactly(2))\n ->method('isRemoved')\n ->willReturn(false);\n $sharedPrompt->expects($this->once())\n ->method('delete');\n\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedUsersAndGroupsByPromptId')\n ->with(1)\n ->willReturn(new Collection([$sharedPrompt]));\n\n $this->askAnythingRepository->expects($this->once())\n ->method('createPrompt');\n\n $data = $this->invokePrivateMethod('recreatePromptsForUserRelations', $this->askAnythingPromptService, [$prompt]);\n\n $this->assertEquals([[1], []], $data);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Component\\AskAnything;\n\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Jiminny\\Component\\AskAnything\\AskAnythingPromptService;\nuse Jiminny\\Component\\AskAnything\\Dtos\\AskAnythingPromptDto;\nuse Jiminny\\Contracts\\Repositories\\GroupRepositoryInterface;\nuse Jiminny\\Models\\AskAnything\\AskAnythingPrompt;\nuse Jiminny\\Models\\AskAnything\\AskAnythingPromptTarget;\nuse Jiminny\\Models\\AskAnything\\UserAskAnythingPrompt;\nuse Jiminny\\Models\\Group;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AskAnythingRepository;\nuse Jiminny\\Repositories\\UserRepository;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Tests\\TestCase;\nuse Tests\\Unit\\Traits\\TestPrivateMethod;\n\nclass AskAnythingPromptServiceTest extends TestCase\n{\n use TestPrivateMethod;\n\n private AskAnythingPromptService $askAnythingPromptService;\n private AskAnythingRepository&MockObject $askAnythingRepository;\n private UserRepository&MockObject $userRepository;\n private GroupRepositoryInterface&MockObject $groupRepository;\n\n protected function setUp(): void\n {\n $this->askAnythingRepository = $this->createMock(AskAnythingRepository::class);\n $this->userRepository = $this->createMock(UserRepository::class);\n $this->groupRepository = $this->createMock(GroupRepositoryInterface::class);\n\n $this->askAnythingPromptService = new AskAnythingPromptService(\n $this->askAnythingRepository,\n $this->userRepository,\n $this->groupRepository\n );\n }\n\n public function testGetAskAnythingPrompts(): void\n {\n $user = $this->createMock(User::class);\n $user->expects($this->any())\n ->method('getId')\n ->willReturn(1);\n $user->expects($this->any())\n ->method('getUuid')\n ->willReturn('1');\n $defaultPrompt = $this->createMock(AskAnythingPrompt::class);\n $defaultPrompt->expects($this->once())\n ->method('getOwner')\n ->willReturn(null);\n $defaultPrompt->expects($this->once())\n ->method('getUuid')\n ->willReturn('default-uuid');\n $defaultPrompt->expects($this->once())\n ->method('getTitle')\n ->willReturn('Sentiment');\n $defaultPrompt->expects($this->once())\n ->method('getContent')\n ->willReturn('What was the overall sentiment of the customer during the call?');\n $defaultPrompt->expects($this->once())\n ->method('getHasReports')\n ->willReturn(false);\n $promptOwnedByUser = $this->createMock(AskAnythingPrompt::class);\n $promptOwnedByUser->expects($this->exactly(2))\n ->method('getOwner')\n ->willReturn($user);\n $promptOwnedByUser->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-1st-prompt');\n $promptOwnedByUser->expects($this->once())\n ->method('getTitle')\n ->willReturn('First users prompt');\n $promptOwnedByUser->expects($this->once())\n ->method('getContent')\n ->willReturn('Test prompt');\n $promptOwnedByUser->expects($this->once())\n ->method('getId')\n ->willReturn(99);\n $promptOwnedByUser->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $promptOwnedByUser->expects($this->once())\n ->method('getHasReports')\n ->willReturn(true);\n $defaultPromptOrderedByUser = $this->createMock(AskAnythingPrompt::class);\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getOwner')\n ->willReturn(null);\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getUuid')\n ->willReturn('default-uuid');\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getTitle')\n ->willReturn('Sentiment');\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getContent')\n ->willReturn('What was the overall sentiment of the customer during the call?');\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getHasReports')\n ->willReturn(false);\n $promptOwnedByUserAndSharedWithGroup = $this->createMock(AskAnythingPrompt::class);\n $promptOwnedByUserAndSharedWithGroup->expects($this->exactly(2))\n ->method('getOwner')\n ->willReturn($user);\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-2nd-prompt');\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getTitle')\n ->willReturn('Prompt shared with group');\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getContent')\n ->willReturn('Test prompt that is shared with group');\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getId')\n ->willReturn(109);\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getHasReports')\n ->willReturn(false);\n\n $group = $this->createMock(Group::class);\n $group->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-of-the-group');\n $sharedWithGroup = $this->createMock(UserAskAnythingPrompt::class);\n $sharedWithGroup->expects($this->once())\n ->method('getUser')\n ->willReturn(null);\n $sharedWithGroup->expects($this->once())\n ->method('getGroup')\n ->willReturn($group);\n\n $this->askAnythingRepository->expects($this->exactly(2))\n ->method('findSharedUsersAndGroupsByPromptId')\n ->willReturnMap([\n [99, new Collection([])],\n [109, new Collection([$sharedWithGroup])],\n ]);\n\n $prompts = [$defaultPrompt, $promptOwnedByUser, $defaultPromptOrderedByUser, $promptOwnedByUserAndSharedWithGroup];\n $this->askAnythingRepository->expects($this->once())\n ->method('findPromptsByUserAndTarget')\n ->willReturn(new Collection($prompts));\n\n $expectedDto1 = new AskAnythingPromptDto(\n 'default-uuid',\n 'Sentiment',\n 'What was the overall sentiment of the customer during the call?',\n AskAnythingPromptTarget::call,\n null,\n null,\n null,\n false,\n );\n $expectedDto2 = new AskAnythingPromptDto(\n 'uuid-1st-prompt',\n 'First users prompt',\n 'Test prompt',\n AskAnythingPromptTarget::call,\n '1',\n [],\n [],\n true,\n );\n $expectedDto3 = new AskAnythingPromptDto(\n 'default-uuid',\n 'Sentiment',\n 'What was the overall sentiment of the customer during the call?',\n AskAnythingPromptTarget::call,\n null,\n null,\n null,\n false,\n );\n $expectedDto4 = new AskAnythingPromptDto(\n 'uuid-2nd-prompt',\n 'Prompt shared with group',\n 'Test prompt that is shared with group',\n AskAnythingPromptTarget::call,\n '1',\n [],\n ['uuid-of-the-group'],\n false,\n );\n $dtos = $this->askAnythingPromptService->get($user, AskAnythingPromptTarget::call);\n\n $this->assertEquals([$expectedDto1, $expectedDto2, $expectedDto3, $expectedDto4], $dtos);\n }\n\n public function testEditAskAnythingPrompt(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(123);\n $prompt->expects($this->never())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(123);\n $user->expects($this->once())\n ->method('getUuid')\n ->willReturn('owner-uuid');\n\n $title = 'new title';\n $content = 'new content';\n $shareUsers = ['us-1'];\n $shareGroups = ['gr-1', 'gr-2'];\n\n $shareUser = $this->createMock(User::class);\n $this->userRepository->expects($this->once())\n ->method('findByUuid')\n ->with('us-1')\n ->willReturn($shareUser);\n $shareGroup1 = $this->createMock(Group::class);\n $shareGroup2 = $this->createMock(Group::class);\n $this->groupRepository->expects($this->exactly(2))\n ->method('findByUuid')\n ->willReturnMap([\n ['gr-1', $shareGroup1],\n ['gr-2', $shareGroup2],\n ]);\n\n $editPrompt = $this->createMock(AskAnythingPrompt::class);\n $editPrompt->expects($this->once())\n ->method('getTitle')\n ->willReturn($title);\n $editPrompt->expects($this->once())\n ->method('getContent')\n ->willReturn($content);\n $editPrompt->expects($this->once())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $editPrompt->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-1st-prompt');\n $this->askAnythingRepository->expects($this->once())\n ->method('editPrompt')\n ->with($prompt, $title, $content, [$shareUser], [$shareGroup1, $shareGroup2])\n ->willReturn($editPrompt);\n\n $expectedDto = new AskAnythingPromptDto(\n 'uuid-1st-prompt',\n $title,\n $content,\n AskAnythingPromptTarget::call,\n 'owner-uuid',\n $shareUsers,\n $shareGroups\n );\n $editDto = $this->askAnythingPromptService->edit($prompt, $user, $title, $content, $shareUsers, $shareGroups);\n\n $this->assertEquals($expectedDto, $editDto);\n }\n\n public function testHideDefaultAndCreateAskAnythingPrompt(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(true);\n $prompt->expects($this->once())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getUuid')\n ->willReturn('new-owner-uuid');\n $title = 'title';\n $content = 'content';\n $shareUsers = ['us-1'];\n $shareGroups = [];\n $shareUser = $this->createMock(User::class);\n $this->userRepository->expects($this->once())\n ->method('findByUuid')\n ->with('us-1')\n ->willReturn($shareUser);\n $this->groupRepository->expects($this->never())\n ->method('findByUuid');\n\n $newPrompt = $this->createMock(AskAnythingPrompt::class);\n $newPrompt->expects($this->once())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $newPrompt->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-1st-prompt');\n $newPrompt->expects($this->once())\n ->method('getTitle')\n ->willReturn($title);\n $newPrompt->expects($this->once())\n ->method('getContent')\n ->willReturn($content);\n\n $this->askAnythingRepository->expects($this->once())\n ->method('hidePromptForUser');\n $this->askAnythingRepository->expects($this->once())\n ->method('createPrompt')\n ->willReturn($newPrompt);\n\n $expectedDto = new AskAnythingPromptDto(\n 'uuid-1st-prompt',\n $title,\n $content,\n AskAnythingPromptTarget::call,\n 'new-owner-uuid',\n $shareUsers,\n $shareGroups\n );\n\n $actualDto = $this->askAnythingPromptService->edit($prompt, $user, $title, $content, $shareUsers, $shareGroups);\n\n $this->assertEquals($expectedDto, $actualDto);\n }\n\n public function testDeleteAskAnythingPrompt(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->any())\n ->method('getId')\n ->willReturn(1);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n\n // Use Mockery for the relationship mock (more flexible)\n $relationMock = \\Mockery::mock(\\Illuminate\\Database\\Eloquent\\Relations\\HasMany::class);\n $relationMock->shouldReceive('withTrashed')\n ->once()\n ->andReturnSelf();\n $relationMock->shouldReceive('update')\n ->once()\n ->with(['ask_anything_prompt_id' => null, 'status' => false]);\n\n $prompt->expects($this->once())\n ->method('automatedReports')\n ->willReturn($relationMock);\n\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(1);\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(1, $user)\n ->willReturn($userPrompt);\n $userPrompt->expects($this->once())\n ->method('delete');\n $this->askAnythingRepository->expects($this->any())\n ->method('findSharedUsersAndGroupsByPromptId')\n ->with(1)\n ->willReturn(new Collection([]));\n $this->askAnythingRepository->expects($this->once())\n ->method('deletePrompt');\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testDeleteAskAnythingPromptWithRelations(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->any())\n ->method('getId')\n ->willReturn(1);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $user = $this->createMock(User::class);\n $user->expects($this->any())\n ->method('getId')\n ->willReturn(1);\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(1, $user)\n ->willReturn($userPrompt);\n $userPrompt->expects($this->once())\n ->method('delete');\n $this->askAnythingRepository->expects($this->exactly(3))\n ->method('findSharedUsersAndGroupsByPromptId')\n ->willReturnMap([\n [1, new Collection([$userPrompt])],\n [1, new Collection([])],\n ]);\n $this->askAnythingRepository->expects($this->never())\n ->method('deletePrompt');\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testHideDefaultAskAnythingPrompt(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(true);\n $user = $this->createMock(User::class);\n $this->askAnythingRepository->expects($this->once())\n ->method('hidePromptForUser');\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testHideSharedWithUserAskAnythingPrompt(): void\n {\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $prompt->expects($this->exactly(3))\n ->method('getId')\n ->willReturn(33);\n\n $relationMock = \\Mockery::mock(\\Illuminate\\Database\\Eloquent\\Relations\\HasMany::class);\n $relationMock->shouldReceive('withTrashed')\n ->once()\n ->andReturnSelf();\n $relationMock->shouldReceive('update')\n ->once()\n ->with(['ask_anything_prompt_id' => null, 'status' => false]);\n $prompt->expects($this->once())\n ->method('automatedReports')\n ->willReturn($relationMock);\n\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(2);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(33, $user)\n ->willReturn($userPrompt);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUserGroup')\n ->with(33, $user)\n ->willReturn(null);\n $userPrompt->expects($this->once())\n ->method('delete');\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedUsersAndGroupsByPromptId')\n ->with(33)\n ->willReturn(new Collection([]));\n\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testHideSharedWithUserAndGroupAskAnythingPrompt(): void\n {\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $prompt->expects($this->exactly(2))\n ->method('getId')\n ->willReturn(33);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(2);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(33, $user)\n ->willReturn($userPrompt);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUserGroup')\n ->with(33, $user)\n ->willReturn($userPrompt);\n $userPrompt->expects($this->never())\n ->method('delete');\n $this->askAnythingRepository->expects($this->once())\n ->method('hidePromptForUser')\n ->with($prompt, $user);\n\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testHideSharedWithGroupAskAnythingPrompt(): void\n {\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $prompt->expects($this->exactly(2))\n ->method('getId')\n ->willReturn(33);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(2);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(33, $user)\n ->willReturn(null);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUserGroup')\n ->with(33, $user)\n ->willReturn($userPrompt);\n $userPrompt->expects($this->never())\n ->method('delete');\n $this->askAnythingRepository->expects($this->once())\n ->method('hidePromptForUser')\n ->with($prompt, $user);\n\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testDeleteWithNoSharesAndNotOwner(): void\n {\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $prompt->expects($this->exactly(2))\n ->method('getId')\n ->willReturn(33);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(2);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(33, $user)\n ->willReturn(null);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUserGroup')\n ->with(33, $user)\n ->willReturn(null);\n $userPrompt->expects($this->never())\n ->method('delete');\n $this->askAnythingRepository->expects($this->never())\n ->method('hidePromptForUser');\n\n $this->expectException(\\InvalidArgumentException::class);\n\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testReorderAskAnythingPrompts(): void\n {\n $prompts = ['id1', 'id2', 'id3'];\n $prompt1 = $this->createMock(AskAnythingPrompt::class);\n $prompt2 = $this->createMock(AskAnythingPrompt::class);\n $prompt3 = $this->createMock(AskAnythingPrompt::class);\n $user = $this->createMock(User::class);\n $this->askAnythingRepository->expects($this->exactly(3))\n ->method('getPromptByUuid')\n ->willReturnMap([\n ['id1', $prompt1],\n ['id2', $prompt2],\n ['id3', $prompt3],\n ]);\n $this->askAnythingRepository->expects($this->exactly(3))\n ->method('orderPromptForUser')\n ->willReturnMap([\n [[$prompt1, $user, 1]],\n [[$prompt2, $user, 2]],\n [[$prompt3, $user, 3]],\n ]);\n $this->askAnythingPromptService->reorder($user, $prompts);\n }\n\n public function testCreateAskAnythingPromptWithTwoUsers(): void\n {\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-of-the-user');\n $shareUser1 = $this->createMock(User::class);\n $shareUser2 = $this->createMock(User::class);\n $title = 'Test title';\n $content = 'Test content';\n $target = AskAnythingPromptTarget::call;\n $shareUsers = ['us-1', 'us-2'];\n $shareGroups = [];\n\n $this->userRepository->expects($this->exactly(2))\n ->method('findByUuid')\n ->willReturnMap([\n ['us-1', $shareUser1],\n ['us-2', $shareUser2],\n ]);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('getUuid')\n ->willReturn('prompt-1-uuid');\n $prompt->expects($this->once())\n ->method('getTitle')\n ->willReturn($title);\n $prompt->expects($this->once())\n ->method('getContent')\n ->willReturn($content);\n $this->askAnythingRepository->expects($this->once())\n ->method('createPrompt')\n ->with(\n $user,\n $target,\n $title,\n $content,\n [$shareUser1, $shareUser2],\n [],\n )\n ->willReturn($prompt);\n\n $expectedPromptDto = new AskAnythingPromptDto(\n 'prompt-1-uuid',\n $title,\n $content,\n $target,\n 'uuid-of-the-user',\n $shareUsers,\n $shareGroups,\n );\n\n $actualPromptDto = $this->askAnythingPromptService->create(\n $user,\n $title,\n $content,\n $target,\n $shareUsers,\n $shareGroups\n );\n\n $this->assertEquals($expectedPromptDto, $actualPromptDto);\n }\n\n public function testRecreatePromptsForUserRelations(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('getId')\n ->willReturn(1);\n $prompt->expects($this->once())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $prompt->expects($this->once())\n ->method('getTitle')\n ->willReturn('Test title');\n $prompt->expects($this->once())\n ->method('getContent')\n ->willReturn('Test content');\n\n $sharedPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $sharedUser = $this->createMock(User::class);\n $sharedUser->expects($this->once())\n ->method('isStatusActive')\n ->willReturn(true);\n $sharedUser->expects($this->once())\n ->method('getId')\n ->willReturn(1);\n\n $sharedPrompt->expects($this->once())\n ->method('getUser')\n ->willReturn($sharedUser);\n $sharedPrompt->expects($this->exactly(2))\n ->method('isRemoved')\n ->willReturn(false);\n $sharedPrompt->expects($this->once())\n ->method('delete');\n\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedUsersAndGroupsByPromptId')\n ->with(1)\n ->willReturn(new Collection([$sharedPrompt]));\n\n $this->askAnythingRepository->expects($this->once())\n ->method('createPrompt');\n\n $data = $this->invokePrivateMethod('recreatePromptsForUserRelations', $this->askAnythingPromptService, [$prompt]);\n\n $this->assertEquals([[1], []], $data);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
1140439531069478179
|
-8755961741003010129
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20676-delete-report-re Project: faVsco.js, menu
JY-20676-delete-report-related-objects, 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
6
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Component\AskAnything;
use Illuminate\Database\Eloquent\Collection;
use Jiminny\Component\AskAnything\AskAnythingPromptService;
use Jiminny\Component\AskAnything\Dtos\AskAnythingPromptDto;
use Jiminny\Contracts\Repositories\GroupRepositoryInterface;
use Jiminny\Models\AskAnything\AskAnythingPrompt;
use Jiminny\Models\AskAnything\AskAnythingPromptTarget;
use Jiminny\Models\AskAnything\UserAskAnythingPrompt;
use Jiminny\Models\Group;
use Jiminny\Models\User;
use Jiminny\Repositories\AskAnythingRepository;
use Jiminny\Repositories\UserRepository;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
use Tests\Unit\Traits\TestPrivateMethod;
class AskAnythingPromptServiceTest extends TestCase
{
use TestPrivateMethod;
private AskAnythingPromptService $askAnythingPromptService;
private AskAnythingRepository&MockObject $askAnythingRepository;
private UserRepository&MockObject $userRepository;
private GroupRepositoryInterface&MockObject $groupRepository;
protected function setUp(): void
{
$this->askAnythingRepository = $this->createMock(AskAnythingRepository::class);
$this->userRepository = $this->createMock(UserRepository::class);
$this->groupRepository = $this->createMock(GroupRepositoryInterface::class);
$this->askAnythingPromptService = new AskAnythingPromptService(
$this->askAnythingRepository,
$this->userRepository,
$this->groupRepository
);
}
public function testGetAskAnythingPrompts(): void
{
$user = $this->createMock(User::class);
$user->expects($this->any())
->method('getId')
->willReturn(1);
$user->expects($this->any())
->method('getUuid')
->willReturn('1');
$defaultPrompt = $this->createMock(AskAnythingPrompt::class);
$defaultPrompt->expects($this->once())
->method('getOwner')
->willReturn(null);
$defaultPrompt->expects($this->once())
->method('getUuid')
->willReturn('default-uuid');
$defaultPrompt->expects($this->once())
->method('getTitle')
->willReturn('Sentiment');
$defaultPrompt->expects($this->once())
->method('getContent')
->willReturn('What was the overall sentiment of the customer during the call?');
$defaultPrompt->expects($this->once())
->method('getHasReports')
->willReturn(false);
$promptOwnedByUser = $this->createMock(AskAnythingPrompt::class);
$promptOwnedByUser->expects($this->exactly(2))
->method('getOwner')
->willReturn($user);
$promptOwnedByUser->expects($this->once())
->method('getUuid')
->willReturn('uuid-1st-prompt');
$promptOwnedByUser->expects($this->once())
->method('getTitle')
->willReturn('First users prompt');
$promptOwnedByUser->expects($this->once())
->method('getContent')
->willReturn('Test prompt');
$promptOwnedByUser->expects($this->once())
->method('getId')
->willReturn(99);
$promptOwnedByUser->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$promptOwnedByUser->expects($this->once())
->method('getHasReports')
->willReturn(true);
$defaultPromptOrderedByUser = $this->createMock(AskAnythingPrompt::class);
$defaultPromptOrderedByUser->expects($this->once())
->method('getOwner')
->willReturn(null);
$defaultPromptOrderedByUser->expects($this->once())
->method('getUuid')
->willReturn('default-uuid');
$defaultPromptOrderedByUser->expects($this->once())
->method('getTitle')
->willReturn('Sentiment');
$defaultPromptOrderedByUser->expects($this->once())
->method('getContent')
->willReturn('What was the overall sentiment of the customer during the call?');
$defaultPromptOrderedByUser->expects($this->once())
->method('getHasReports')
->willReturn(false);
$promptOwnedByUserAndSharedWithGroup = $this->createMock(AskAnythingPrompt::class);
$promptOwnedByUserAndSharedWithGroup->expects($this->exactly(2))
->method('getOwner')
->willReturn($user);
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getUuid')
->willReturn('uuid-2nd-prompt');
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getTitle')
->willReturn('Prompt shared with group');
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getContent')
->willReturn('Test prompt that is shared with group');
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getId')
->willReturn(109);
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getHasReports')
->willReturn(false);
$group = $this->createMock(Group::class);
$group->expects($this->once())
->method('getUuid')
->willReturn('uuid-of-the-group');
$sharedWithGroup = $this->createMock(UserAskAnythingPrompt::class);
$sharedWithGroup->expects($this->once())
->method('getUser')
->willReturn(null);
$sharedWithGroup->expects($this->once())
->method('getGroup')
->willReturn($group);
$this->askAnythingRepository->expects($this->exactly(2))
->method('findSharedUsersAndGroupsByPromptId')
->willReturnMap([
[99, new Collection([])],
[109, new Collection([$sharedWithGroup])],
]);
$prompts = [$defaultPrompt, $promptOwnedByUser, $defaultPromptOrderedByUser, $promptOwnedByUserAndSharedWithGroup];
$this->askAnythingRepository->expects($this->once())
->method('findPromptsByUserAndTarget')
->willReturn(new Collection($prompts));
$expectedDto1 = new AskAnythingPromptDto(
'default-uuid',
'Sentiment',
'What was the overall sentiment of the customer during the call?',
AskAnythingPromptTarget::call,
null,
null,
null,
false,
);
$expectedDto2 = new AskAnythingPromptDto(
'uuid-1st-prompt',
'First users prompt',
'Test prompt',
AskAnythingPromptTarget::call,
'1',
[],
[],
true,
);
$expectedDto3 = new AskAnythingPromptDto(
'default-uuid',
'Sentiment',
'What was the overall sentiment of the customer during the call?',
AskAnythingPromptTarget::call,
null,
null,
null,
false,
);
$expectedDto4 = new AskAnythingPromptDto(
'uuid-2nd-prompt',
'Prompt shared with group',
'Test prompt that is shared with group',
AskAnythingPromptTarget::call,
'1',
[],
['uuid-of-the-group'],
false,
);
$dtos = $this->askAnythingPromptService->get($user, AskAnythingPromptTarget::call);
$this->assertEquals([$expectedDto1, $expectedDto2, $expectedDto3, $expectedDto4], $dtos);
}
public function testEditAskAnythingPrompt(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(123);
$prompt->expects($this->never())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(123);
$user->expects($this->once())
->method('getUuid')
->willReturn('owner-uuid');
$title = 'new title';
$content = 'new content';
$shareUsers = ['us-1'];
$shareGroups = ['gr-1', 'gr-2'];
$shareUser = $this->createMock(User::class);
$this->userRepository->expects($this->once())
->method('findByUuid')
->with('us-1')
->willReturn($shareUser);
$shareGroup1 = $this->createMock(Group::class);
$shareGroup2 = $this->createMock(Group::class);
$this->groupRepository->expects($this->exactly(2))
->method('findByUuid')
->willReturnMap([
['gr-1', $shareGroup1],
['gr-2', $shareGroup2],
]);
$editPrompt = $this->createMock(AskAnythingPrompt::class);
$editPrompt->expects($this->once())
->method('getTitle')
->willReturn($title);
$editPrompt->expects($this->once())
->method('getContent')
->willReturn($content);
$editPrompt->expects($this->once())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$editPrompt->expects($this->once())
->method('getUuid')
->willReturn('uuid-1st-prompt');
$this->askAnythingRepository->expects($this->once())
->method('editPrompt')
->with($prompt, $title, $content, [$shareUser], [$shareGroup1, $shareGroup2])
->willReturn($editPrompt);
$expectedDto = new AskAnythingPromptDto(
'uuid-1st-prompt',
$title,
$content,
AskAnythingPromptTarget::call,
'owner-uuid',
$shareUsers,
$shareGroups
);
$editDto = $this->askAnythingPromptService->edit($prompt, $user, $title, $content, $shareUsers, $shareGroups);
$this->assertEquals($expectedDto, $editDto);
}
public function testHideDefaultAndCreateAskAnythingPrompt(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(true);
$prompt->expects($this->once())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getUuid')
->willReturn('new-owner-uuid');
$title = 'title';
$content = 'content';
$shareUsers = ['us-1'];
$shareGroups = [];
$shareUser = $this->createMock(User::class);
$this->userRepository->expects($this->once())
->method('findByUuid')
->with('us-1')
->willReturn($shareUser);
$this->groupRepository->expects($this->never())
->method('findByUuid');
$newPrompt = $this->createMock(AskAnythingPrompt::class);
$newPrompt->expects($this->once())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$newPrompt->expects($this->once())
->method('getUuid')
->willReturn('uuid-1st-prompt');
$newPrompt->expects($this->once())
->method('getTitle')
->willReturn($title);
$newPrompt->expects($this->once())
->method('getContent')
->willReturn($content);
$this->askAnythingRepository->expects($this->once())
->method('hidePromptForUser');
$this->askAnythingRepository->expects($this->once())
->method('createPrompt')
->willReturn($newPrompt);
$expectedDto = new AskAnythingPromptDto(
'uuid-1st-prompt',
$title,
$content,
AskAnythingPromptTarget::call,
'new-owner-uuid',
$shareUsers,
$shareGroups
);
$actualDto = $this->askAnythingPromptService->edit($prompt, $user, $title, $content, $shareUsers, $shareGroups);
$this->assertEquals($expectedDto, $actualDto);
}
public function testDeleteAskAnythingPrompt(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->any())
->method('getId')
->willReturn(1);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
// Use Mockery for the relationship mock (more flexible)
$relationMock = \Mockery::mock(\Illuminate\Database\Eloquent\Relations\HasMany::class);
$relationMock->shouldReceive('withTrashed')
->once()
->andReturnSelf();
$relationMock->shouldReceive('update')
->once()
->with(['ask_anything_prompt_id' => null, 'status' => false]);
$prompt->expects($this->once())
->method('automatedReports')
->willReturn($relationMock);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(1);
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(1, $user)
->willReturn($userPrompt);
$userPrompt->expects($this->once())
->method('delete');
$this->askAnythingRepository->expects($this->any())
->method('findSharedUsersAndGroupsByPromptId')
->with(1)
->willReturn(new Collection([]));
$this->askAnythingRepository->expects($this->once())
->method('deletePrompt');
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testDeleteAskAnythingPromptWithRelations(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->any())
->method('getId')
->willReturn(1);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$user = $this->createMock(User::class);
$user->expects($this->any())
->method('getId')
->willReturn(1);
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(1, $user)
->willReturn($userPrompt);
$userPrompt->expects($this->once())
->method('delete');
$this->askAnythingRepository->expects($this->exactly(3))
->method('findSharedUsersAndGroupsByPromptId')
->willReturnMap([
[1, new Collection([$userPrompt])],
[1, new Collection([])],
]);
$this->askAnythingRepository->expects($this->never())
->method('deletePrompt');
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testHideDefaultAskAnythingPrompt(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(true);
$user = $this->createMock(User::class);
$this->askAnythingRepository->expects($this->once())
->method('hidePromptForUser');
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testHideSharedWithUserAskAnythingPrompt(): void
{
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$prompt->expects($this->exactly(3))
->method('getId')
->willReturn(33);
$relationMock = \Mockery::mock(\Illuminate\Database\Eloquent\Relations\HasMany::class);
$relationMock->shouldReceive('withTrashed')
->once()
->andReturnSelf();
$relationMock->shouldReceive('update')
->once()
->with(['ask_anything_prompt_id' => null, 'status' => false]);
$prompt->expects($this->once())
->method('automatedReports')
->willReturn($relationMock);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(2);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(33, $user)
->willReturn($userPrompt);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUserGroup')
->with(33, $user)
->willReturn(null);
$userPrompt->expects($this->once())
->method('delete');
$this->askAnythingRepository->expects($this->once())
->method('findSharedUsersAndGroupsByPromptId')
->with(33)
->willReturn(new Collection([]));
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testHideSharedWithUserAndGroupAskAnythingPrompt(): void
{
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$prompt->expects($this->exactly(2))
->method('getId')
->willReturn(33);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(2);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(33, $user)
->willReturn($userPrompt);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUserGroup')
->with(33, $user)
->willReturn($userPrompt);
$userPrompt->expects($this->never())
->method('delete');
$this->askAnythingRepository->expects($this->once())
->method('hidePromptForUser')
->with($prompt, $user);
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testHideSharedWithGroupAskAnythingPrompt(): void
{
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$prompt->expects($this->exactly(2))
->method('getId')
->willReturn(33);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(2);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(33, $user)
->willReturn(null);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUserGroup')
->with(33, $user)
->willReturn($userPrompt);
$userPrompt->expects($this->never())
->method('delete');
$this->askAnythingRepository->expects($this->once())
->method('hidePromptForUser')
->with($prompt, $user);
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testDeleteWithNoSharesAndNotOwner(): void
{
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$prompt->expects($this->exactly(2))
->method('getId')
->willReturn(33);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(2);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(33, $user)
->willReturn(null);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUserGroup')
->with(33, $user)
->willReturn(null);
$userPrompt->expects($this->never())
->method('delete');
$this->askAnythingRepository->expects($this->never())
->method('hidePromptForUser');
$this->expectException(\InvalidArgumentException::class);
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testReorderAskAnythingPrompts(): void
{
$prompts = ['id1', 'id2', 'id3'];
$prompt1 = $this->createMock(AskAnythingPrompt::class);
$prompt2 = $this->createMock(AskAnythingPrompt::class);
$prompt3 = $this->createMock(AskAnythingPrompt::class);
$user = $this->createMock(User::class);
$this->askAnythingRepository->expects($this->exactly(3))
->method('getPromptByUuid')
->willReturnMap([
['id1', $prompt1],
['id2', $prompt2],
['id3', $prompt3],
]);
$this->askAnythingRepository->expects($this->exactly(3))
->method('orderPromptForUser')
->willReturnMap([
[[$prompt1, $user, 1]],
[[$prompt2, $user, 2]],
[[$prompt3, $user, 3]],
]);
$this->askAnythingPromptService->reorder($user, $prompts);
}
public function testCreateAskAnythingPromptWithTwoUsers(): void
{
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getUuid')
->willReturn('uuid-of-the-user');
$shareUser1 = $this->createMock(User::class);
$shareUser2 = $this->createMock(User::class);
$title = 'Test title';
$content = 'Test content';
$target = AskAnythingPromptTarget::call;
$shareUsers = ['us-1', 'us-2'];
$shareGroups = [];
$this->userRepository->expects($this->exactly(2))
->method('findByUuid')
->willReturnMap([
['us-1', $shareUser1],
['us-2', $shareUser2],
]);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('getUuid')
->willReturn('prompt-1-uuid');
$prompt->expects($this->once())
->method('getTitle')
->willReturn($title);
$prompt->expects($this->once())
->method('getContent')
->willReturn($content);
$this->askAnythingRepository->expects($this->once())
->method('createPrompt')
->with(
$user,
$target,
$title,
$content,
[$shareUser1, $shareUser2],
[],
)
->willReturn($prompt);
$expectedPromptDto = new AskAnythingPromptDto(
'prompt-1-uuid',
$title,
$content,
$target,
'uuid-of-the-user',
$shareUsers,
$shareGroups,
);
$actualPromptDto = $this->askAnythingPromptService->create(
$user,
$title,
$content,
$target,
$shareUsers,
$shareGroups
);
$this->assertEquals($expectedPromptDto, $actualPromptDto);
}
public function testRecreatePromptsForUserRelations(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('getId')
->willReturn(1);
$prompt->expects($this->once())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$prompt->expects($this->once())
->method('getTitle')
->willReturn('Test title');
$prompt->expects($this->once())
->method('getContent')
->willReturn('Test content');
$sharedPrompt = $this->createMock(UserAskAnythingPrompt::class);
$sharedUser = $this->createMock(User::class);
$sharedUser->expects($this->once())
->method('isStatusActive')
->willReturn(true);
$sharedUser->expects($this->once())
->method('getId')
->willReturn(1);
$sharedPrompt->expects($this->once())
->method('getUser')
->willReturn($sharedUser);
$sharedPrompt->expects($this->exactly(2))
->method('isRemoved')
->willReturn(false);
$sharedPrompt->expects($this->once())
->method('delete');
$this->askAnythingRepository->expects($this->once())
->method('findSharedUsersAndGroupsByPromptId')
->with(1)
->willReturn(new Collection([$sharedPrompt]));
$this->askAnythingRepository->expects($this->once())
->method('createPrompt');
$data = $this->invokePrivateMethod('recreatePromptsForUserRelations', $this->askAnythingPromptService, [$prompt]);
$this->assertEquals([[1], []], $data);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
56840
|
NULL
|
NULL
|
NULL
|
|
56849
|
NULL
|
0
|
2026-05-19T08:33:10.107253+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779179590107_m2.jpg...
|
PhpStorm
|
faVsco.js – AskAnythingPromptServiceTest.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20676-delete-report-re Project: faVsco.js, menu
JY-20676-delete-report-related-objects, 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
6
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Component\AskAnything;
use Illuminate\Database\Eloquent\Collection;
use Jiminny\Component\AskAnything\AskAnythingPromptService;
use Jiminny\Component\AskAnything\Dtos\AskAnythingPromptDto;
use Jiminny\Contracts\Repositories\GroupRepositoryInterface;
use Jiminny\Models\AskAnything\AskAnythingPrompt;
use Jiminny\Models\AskAnything\AskAnythingPromptTarget;
use Jiminny\Models\AskAnything\UserAskAnythingPrompt;
use Jiminny\Models\Group;
use Jiminny\Models\User;
use Jiminny\Repositories\AskAnythingRepository;
use Jiminny\Repositories\UserRepository;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
use Tests\Unit\Traits\TestPrivateMethod;
class AskAnythingPromptServiceTest extends TestCase
{
use TestPrivateMethod;
private AskAnythingPromptService $askAnythingPromptService;
private AskAnythingRepository&MockObject $askAnythingRepository;
private UserRepository&MockObject $userRepository;
private GroupRepositoryInterface&MockObject $groupRepository;
protected function setUp(): void
{
$this->askAnythingRepository = $this->createMock(AskAnythingRepository::class);
$this->userRepository = $this->createMock(UserRepository::class);
$this->groupRepository = $this->createMock(GroupRepositoryInterface::class);
$this->askAnythingPromptService = new AskAnythingPromptService(
$this->askAnythingRepository,
$this->userRepository,
$this->groupRepository
);
}
public function testGetAskAnythingPrompts(): void
{
$user = $this->createMock(User::class);
$user->expects($this->any())
->method('getId')
->willReturn(1);
$user->expects($this->any())
->method('getUuid')
->willReturn('1');
$defaultPrompt = $this->createMock(AskAnythingPrompt::class);
$defaultPrompt->expects($this->once())
->method('getOwner')
->willReturn(null);
$defaultPrompt->expects($this->once())
->method('getUuid')
->willReturn('default-uuid');
$defaultPrompt->expects($this->once())
->method('getTitle')
->willReturn('Sentiment');
$defaultPrompt->expects($this->once())
->method('getContent')
->willReturn('What was the overall sentiment of the customer during the call?');
$defaultPrompt->expects($this->once())
->method('getHasReports')
->willReturn(false);
$promptOwnedByUser = $this->createMock(AskAnythingPrompt::class);
$promptOwnedByUser->expects($this->exactly(2))
->method('getOwner')
->willReturn($user);
$promptOwnedByUser->expects($this->once())
->method('getUuid')
->willReturn('uuid-1st-prompt');
$promptOwnedByUser->expects($this->once())
->method('getTitle')
->willReturn('First users prompt');
$promptOwnedByUser->expects($this->once())
->method('getContent')
->willReturn('Test prompt');
$promptOwnedByUser->expects($this->once())
->method('getId')
->willReturn(99);
$promptOwnedByUser->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$promptOwnedByUser->expects($this->once())
->method('getHasReports')
->willReturn(true);
$defaultPromptOrderedByUser = $this->createMock(AskAnythingPrompt::class);
$defaultPromptOrderedByUser->expects($this->once())
->method('getOwner')
->willReturn(null);
$defaultPromptOrderedByUser->expects($this->once())
->method('getUuid')
->willReturn('default-uuid');
$defaultPromptOrderedByUser->expects($this->once())
->method('getTitle')
->willReturn('Sentiment');
$defaultPromptOrderedByUser->expects($this->once())
->method('getContent')
->willReturn('What was the overall sentiment of the customer during the call?');
$defaultPromptOrderedByUser->expects($this->once())
->method('getHasReports')
->willReturn(false);
$promptOwnedByUserAndSharedWithGroup = $this->createMock(AskAnythingPrompt::class);
$promptOwnedByUserAndSharedWithGroup->expects($this->exactly(2))
->method('getOwner')
->willReturn($user);
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getUuid')
->willReturn('uuid-2nd-prompt');
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getTitle')
->willReturn('Prompt shared with group');
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getContent')
->willReturn('Test prompt that is shared with group');
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getId')
->willReturn(109);
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getHasReports')
->willReturn(false);
$group = $this->createMock(Group::class);
$group->expects($this->once())
->method('getUuid')
->willReturn('uuid-of-the-group');
$sharedWithGroup = $this->createMock(UserAskAnythingPrompt::class);
$sharedWithGroup->expects($this->once())
->method('getUser')
->willReturn(null);
$sharedWithGroup->expects($this->once())
->method('getGroup')
->willReturn($group);
$this->askAnythingRepository->expects($this->exactly(2))
->method('findSharedUsersAndGroupsByPromptId')
->willReturnMap([
[99, new Collection([])],
[109, new Collection([$sharedWithGroup])],
]);
$prompts = [$defaultPrompt, $promptOwnedByUser, $defaultPromptOrderedByUser, $promptOwnedByUserAndSharedWithGroup];
$this->askAnythingRepository->expects($this->once())
->method('findPromptsByUserAndTarget')
->willReturn(new Collection($prompts));
$expectedDto1 = new AskAnythingPromptDto(
'default-uuid',
'Sentiment',
'What was the overall sentiment of the customer during the call?',
AskAnythingPromptTarget::call,
null,
null,
null,
false,
);
$expectedDto2 = new AskAnythingPromptDto(
'uuid-1st-prompt',
'First users prompt',
'Test prompt',
AskAnythingPromptTarget::call,
'1',
[],
[],
true,
);
$expectedDto3 = new AskAnythingPromptDto(
'default-uuid',
'Sentiment',
'What was the overall sentiment of the customer during the call?',
AskAnythingPromptTarget::call,
null,
null,
null,
false,
);
$expectedDto4 = new AskAnythingPromptDto(
'uuid-2nd-prompt',
'Prompt shared with group',
'Test prompt that is shared with group',
AskAnythingPromptTarget::call,
'1',
[],
['uuid-of-the-group'],
false,
);
$dtos = $this->askAnythingPromptService->get($user, AskAnythingPromptTarget::call);
$this->assertEquals([$expectedDto1, $expectedDto2, $expectedDto3, $expectedDto4], $dtos);
}
public function testEditAskAnythingPrompt(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(123);
$prompt->expects($this->never())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(123);
$user->expects($this->once())
->method('getUuid')
->willReturn('owner-uuid');
$title = 'new title';
$content = 'new content';
$shareUsers = ['us-1'];
$shareGroups = ['gr-1', 'gr-2'];
$shareUser = $this->createMock(User::class);
$this->userRepository->expects($this->once())
->method('findByUuid')
->with('us-1')
->willReturn($shareUser);
$shareGroup1 = $this->createMock(Group::class);
$shareGroup2 = $this->createMock(Group::class);
$this->groupRepository->expects($this->exactly(2))
->method('findByUuid')
->willReturnMap([
['gr-1', $shareGroup1],
['gr-2', $shareGroup2],
]);
$editPrompt = $this->createMock(AskAnythingPrompt::class);
$editPrompt->expects($this->once())
->method('getTitle')
->willReturn($title);
$editPrompt->expects($this->once())
->method('getContent')
->willReturn($content);
$editPrompt->expects($this->once())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$editPrompt->expects($this->once())
->method('getUuid')
->willReturn('uuid-1st-prompt');
$this->askAnythingRepository->expects($this->once())
->method('editPrompt')
->with($prompt, $title, $content, [$shareUser], [$shareGroup1, $shareGroup2])
->willReturn($editPrompt);
$expectedDto = new AskAnythingPromptDto(
'uuid-1st-prompt',
$title,
$content,
AskAnythingPromptTarget::call,
'owner-uuid',
$shareUsers,
$shareGroups
);
$editDto = $this->askAnythingPromptService->edit($prompt, $user, $title, $content, $shareUsers, $shareGroups);
$this->assertEquals($expectedDto, $editDto);
}
public function testHideDefaultAndCreateAskAnythingPrompt(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(true);
$prompt->expects($this->once())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getUuid')
->willReturn('new-owner-uuid');
$title = 'title';
$content = 'content';
$shareUsers = ['us-1'];
$shareGroups = [];
$shareUser = $this->createMock(User::class);
$this->userRepository->expects($this->once())
->method('findByUuid')
->with('us-1')
->willReturn($shareUser);
$this->groupRepository->expects($this->never())
->method('findByUuid');
$newPrompt = $this->createMock(AskAnythingPrompt::class);
$newPrompt->expects($this->once())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$newPrompt->expects($this->once())
->method('getUuid')
->willReturn('uuid-1st-prompt');
$newPrompt->expects($this->once())
->method('getTitle')
->willReturn($title);
$newPrompt->expects($this->once())
->method('getContent')
->willReturn($content);
$this->askAnythingRepository->expects($this->once())
->method('hidePromptForUser');
$this->askAnythingRepository->expects($this->once())
->method('createPrompt')
->willReturn($newPrompt);
$expectedDto = new AskAnythingPromptDto(
'uuid-1st-prompt',
$title,
$content,
AskAnythingPromptTarget::call,
'new-owner-uuid',
$shareUsers,
$shareGroups
);
$actualDto = $this->askAnythingPromptService->edit($prompt, $user, $title, $content, $shareUsers, $shareGroups);
$this->assertEquals($expectedDto, $actualDto);
}
public function testDeleteAskAnythingPrompt(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->any())
->method('getId')
->willReturn(1);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
// Use Mockery for the relationship mock (more flexible)
$relationMock = \Mockery::mock(\Illuminate\Database\Eloquent\Relations\HasMany::class);
$relationMock->shouldReceive('withTrashed')
->once()
->andReturnSelf();
$relationMock->shouldReceive('update')
->once()
->with(['ask_anything_prompt_id' => null, 'status' => false]);
$prompt->expects($this->once())
->method('automatedReports')
->willReturn($relationMock);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(1);
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(1, $user)
->willReturn($userPrompt);
$userPrompt->expects($this->once())
->method('delete');
$this->askAnythingRepository->expects($this->any())
->method('findSharedUsersAndGroupsByPromptId')
->with(1)
->willReturn(new Collection([]));
$this->askAnythingRepository->expects($this->once())
->method('deletePrompt');
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testDeleteAskAnythingPromptWithRelations(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->any())
->method('getId')
->willReturn(1);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$user = $this->createMock(User::class);
$user->expects($this->any())
->method('getId')
->willReturn(1);
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(1, $user)
->willReturn($userPrompt);
$userPrompt->expects($this->once())
->method('delete');
$this->askAnythingRepository->expects($this->exactly(3))
->method('findSharedUsersAndGroupsByPromptId')
->willReturnMap([
[1, new Collection([$userPrompt])],
[1, new Collection([])],
]);
$this->askAnythingRepository->expects($this->never())
->method('deletePrompt');
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testHideDefaultAskAnythingPrompt(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(true);
$user = $this->createMock(User::class);
$this->askAnythingRepository->expects($this->once())
->method('hidePromptForUser');
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testHideSharedWithUserAskAnythingPrompt(): void
{
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$prompt->expects($this->exactly(3))
->method('getId')
->willReturn(33);
$relationMock = \Mockery::mock(\Illuminate\Database\Eloquent\Relations\HasMany::class);
$relationMock->shouldReceive('withTrashed')
->once()
->andReturnSelf();
$relationMock->shouldReceive('update')
->once()
->with(['ask_anything_prompt_id' => null, 'status' => false]);
$prompt->expects($this->once())
->method('automatedReports')
->willReturn($relationMock);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(2);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(33, $user)
->willReturn($userPrompt);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUserGroup')
->with(33, $user)
->willReturn(null);
$userPrompt->expects($this->once())
->method('delete');
$this->askAnythingRepository->expects($this->once())
->method('findSharedUsersAndGroupsByPromptId')
->with(33)
->willReturn(new Collection([]));
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testHideSharedWithUserAndGroupAskAnythingPrompt(): void
{
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$prompt->expects($this->exactly(2))
->method('getId')
->willReturn(33);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(2);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(33, $user)
->willReturn($userPrompt);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUserGroup')
->with(33, $user)
->willReturn($userPrompt);
$userPrompt->expects($this->never())
->method('delete');
$this->askAnythingRepository->expects($this->once())
->method('hidePromptForUser')
->with($prompt, $user);
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testHideSharedWithGroupAskAnythingPrompt(): void
{
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$prompt->expects($this->exactly(2))
->method('getId')
->willReturn(33);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(2);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(33, $user)
->willReturn(null);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUserGroup')
->with(33, $user)
->willReturn($userPrompt);
$userPrompt->expects($this->never())
->method('delete');
$this->askAnythingRepository->expects($this->once())
->method('hidePromptForUser')
->with($prompt, $user);
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testDeleteWithNoSharesAndNotOwner(): void
{
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$prompt->expects($this->exactly(2))
->method('getId')
->willReturn(33);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(2);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(33, $user)
->willReturn(null);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUserGroup')
->with(33, $user)
->willReturn(null);
$userPrompt->expects($this->never())
->method('delete');
$this->askAnythingRepository->expects($this->never())
->method('hidePromptForUser');
$this->expectException(\InvalidArgumentException::class);
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testReorderAskAnythingPrompts(): void
{
$prompts = ['id1', 'id2', 'id3'];
$prompt1 = $this->createMock(AskAnythingPrompt::class);
$prompt2 = $this->createMock(AskAnythingPrompt::class);
$prompt3 = $this->createMock(AskAnythingPrompt::class);
$user = $this->createMock(User::class);
$this->askAnythingRepository->expects($this->exactly(3))
->method('getPromptByUuid')
->willReturnMap([
['id1', $prompt1],
['id2', $prompt2],
['id3', $prompt3],
]);
$this->askAnythingRepository->expects($this->exactly(3))
->method('orderPromptForUser')
->willReturnMap([
[[$prompt1, $user, 1]],
[[$prompt2, $user, 2]],
[[$prompt3, $user, 3]],
]);
$this->askAnythingPromptService->reorder($user, $prompts);
}
public function testCreateAskAnythingPromptWithTwoUsers(): void
{
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getUuid')
->willReturn('uuid-of-the-user');
$shareUser1 = $this->createMock(User::class);
$shareUser2 = $this->createMock(User::class);
$title = 'Test title';
$content = 'Test content';
$target = AskAnythingPromptTarget::call;
$shareUsers = ['us-1', 'us-2'];
$shareGroups = [];
$this->userRepository->expects($this->exactly(2))
->method('findByUuid')
->willReturnMap([
['us-1', $shareUser1],
['us-2', $shareUser2],
]);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('getUuid')
->willReturn('prompt-1-uuid');
$prompt->expects($this->once())
->method('getTitle')
->willReturn($title);
$prompt->expects($this->once())
->method('getContent')
->willReturn($content);
$this->askAnythingRepository->expects($this->once())
->method('createPrompt')
->with(
$user,
$target,
$title,
$content,
[$shareUser1, $shareUser2],
[],
)
->willReturn($prompt);
$expectedPromptDto = new AskAnythingPromptDto(
'prompt-1-uuid',
$title,
$content,
$target,
'uuid-of-the-user',
$shareUsers,
$shareGroups,
);
$actualPromptDto = $this->askAnythingPromptService->create(
$user,
$title,
$content,
$target,
$shareUsers,
$shareGroups
);
$this->assertEquals($expectedPromptDto, $actualPromptDto);
}
public function testRecreatePromptsForUserRelations(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('getId')
->willReturn(1);
$prompt->expects($this->once())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$prompt->expects($this->once())
->method('getTitle')
->willReturn('Test title');
$prompt->expects($this->once())
->method('getContent')
->willReturn('Test content');
$sharedPrompt = $this->createMock(UserAskAnythingPrompt::class);
$sharedUser = $this->createMock(User::class);
$sharedUser->expects($this->once())
->method('isStatusActive')
->willReturn(true);
$sharedUser->expects($this->once())
->method('getId')
->willReturn(1);
$sharedPrompt->expects($this->once())
->method('getUser')
->willReturn($sharedUser);
$sharedPrompt->expects($this->exactly(2))
->method('isRemoved')
->willReturn(false);
$sharedPrompt->expects($this->once())
->method('delete');
$this->askAnythingRepository->expects($this->once())
->method('findSharedUsersAndGroupsByPromptId')
->with(1)
->willReturn(new Collection([$sharedPrompt]));
$this->askAnythingRepository->expects($this->once())
->method('createPrompt');
$data = $this->invokePrivateMethod('recreatePromptsForUserRelations', $this->askAnythingPromptService, [$prompt]);
$this->assertEquals([[1], []], $data);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20676-delete-report-related-objects, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.098071806,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20676-delete-report-related-objects","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":"6","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.007978723,"height":0.0},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.00731383,"height":0.0},"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.00731383,"height":0.0},"on_screen":false,"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.27027926,"top":1.0,"width":0.006981383,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Component\\AskAnything;\n\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Jiminny\\Component\\AskAnything\\AskAnythingPromptService;\nuse Jiminny\\Component\\AskAnything\\Dtos\\AskAnythingPromptDto;\nuse Jiminny\\Contracts\\Repositories\\GroupRepositoryInterface;\nuse Jiminny\\Models\\AskAnything\\AskAnythingPrompt;\nuse Jiminny\\Models\\AskAnything\\AskAnythingPromptTarget;\nuse Jiminny\\Models\\AskAnything\\UserAskAnythingPrompt;\nuse Jiminny\\Models\\Group;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AskAnythingRepository;\nuse Jiminny\\Repositories\\UserRepository;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Tests\\TestCase;\nuse Tests\\Unit\\Traits\\TestPrivateMethod;\n\nclass AskAnythingPromptServiceTest extends TestCase\n{\n use TestPrivateMethod;\n\n private AskAnythingPromptService $askAnythingPromptService;\n private AskAnythingRepository&MockObject $askAnythingRepository;\n private UserRepository&MockObject $userRepository;\n private GroupRepositoryInterface&MockObject $groupRepository;\n\n protected function setUp(): void\n {\n $this->askAnythingRepository = $this->createMock(AskAnythingRepository::class);\n $this->userRepository = $this->createMock(UserRepository::class);\n $this->groupRepository = $this->createMock(GroupRepositoryInterface::class);\n\n $this->askAnythingPromptService = new AskAnythingPromptService(\n $this->askAnythingRepository,\n $this->userRepository,\n $this->groupRepository\n );\n }\n\n public function testGetAskAnythingPrompts(): void\n {\n $user = $this->createMock(User::class);\n $user->expects($this->any())\n ->method('getId')\n ->willReturn(1);\n $user->expects($this->any())\n ->method('getUuid')\n ->willReturn('1');\n $defaultPrompt = $this->createMock(AskAnythingPrompt::class);\n $defaultPrompt->expects($this->once())\n ->method('getOwner')\n ->willReturn(null);\n $defaultPrompt->expects($this->once())\n ->method('getUuid')\n ->willReturn('default-uuid');\n $defaultPrompt->expects($this->once())\n ->method('getTitle')\n ->willReturn('Sentiment');\n $defaultPrompt->expects($this->once())\n ->method('getContent')\n ->willReturn('What was the overall sentiment of the customer during the call?');\n $defaultPrompt->expects($this->once())\n ->method('getHasReports')\n ->willReturn(false);\n $promptOwnedByUser = $this->createMock(AskAnythingPrompt::class);\n $promptOwnedByUser->expects($this->exactly(2))\n ->method('getOwner')\n ->willReturn($user);\n $promptOwnedByUser->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-1st-prompt');\n $promptOwnedByUser->expects($this->once())\n ->method('getTitle')\n ->willReturn('First users prompt');\n $promptOwnedByUser->expects($this->once())\n ->method('getContent')\n ->willReturn('Test prompt');\n $promptOwnedByUser->expects($this->once())\n ->method('getId')\n ->willReturn(99);\n $promptOwnedByUser->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $promptOwnedByUser->expects($this->once())\n ->method('getHasReports')\n ->willReturn(true);\n $defaultPromptOrderedByUser = $this->createMock(AskAnythingPrompt::class);\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getOwner')\n ->willReturn(null);\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getUuid')\n ->willReturn('default-uuid');\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getTitle')\n ->willReturn('Sentiment');\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getContent')\n ->willReturn('What was the overall sentiment of the customer during the call?');\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getHasReports')\n ->willReturn(false);\n $promptOwnedByUserAndSharedWithGroup = $this->createMock(AskAnythingPrompt::class);\n $promptOwnedByUserAndSharedWithGroup->expects($this->exactly(2))\n ->method('getOwner')\n ->willReturn($user);\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-2nd-prompt');\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getTitle')\n ->willReturn('Prompt shared with group');\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getContent')\n ->willReturn('Test prompt that is shared with group');\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getId')\n ->willReturn(109);\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getHasReports')\n ->willReturn(false);\n\n $group = $this->createMock(Group::class);\n $group->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-of-the-group');\n $sharedWithGroup = $this->createMock(UserAskAnythingPrompt::class);\n $sharedWithGroup->expects($this->once())\n ->method('getUser')\n ->willReturn(null);\n $sharedWithGroup->expects($this->once())\n ->method('getGroup')\n ->willReturn($group);\n\n $this->askAnythingRepository->expects($this->exactly(2))\n ->method('findSharedUsersAndGroupsByPromptId')\n ->willReturnMap([\n [99, new Collection([])],\n [109, new Collection([$sharedWithGroup])],\n ]);\n\n $prompts = [$defaultPrompt, $promptOwnedByUser, $defaultPromptOrderedByUser, $promptOwnedByUserAndSharedWithGroup];\n $this->askAnythingRepository->expects($this->once())\n ->method('findPromptsByUserAndTarget')\n ->willReturn(new Collection($prompts));\n\n $expectedDto1 = new AskAnythingPromptDto(\n 'default-uuid',\n 'Sentiment',\n 'What was the overall sentiment of the customer during the call?',\n AskAnythingPromptTarget::call,\n null,\n null,\n null,\n false,\n );\n $expectedDto2 = new AskAnythingPromptDto(\n 'uuid-1st-prompt',\n 'First users prompt',\n 'Test prompt',\n AskAnythingPromptTarget::call,\n '1',\n [],\n [],\n true,\n );\n $expectedDto3 = new AskAnythingPromptDto(\n 'default-uuid',\n 'Sentiment',\n 'What was the overall sentiment of the customer during the call?',\n AskAnythingPromptTarget::call,\n null,\n null,\n null,\n false,\n );\n $expectedDto4 = new AskAnythingPromptDto(\n 'uuid-2nd-prompt',\n 'Prompt shared with group',\n 'Test prompt that is shared with group',\n AskAnythingPromptTarget::call,\n '1',\n [],\n ['uuid-of-the-group'],\n false,\n );\n $dtos = $this->askAnythingPromptService->get($user, AskAnythingPromptTarget::call);\n\n $this->assertEquals([$expectedDto1, $expectedDto2, $expectedDto3, $expectedDto4], $dtos);\n }\n\n public function testEditAskAnythingPrompt(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(123);\n $prompt->expects($this->never())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(123);\n $user->expects($this->once())\n ->method('getUuid')\n ->willReturn('owner-uuid');\n\n $title = 'new title';\n $content = 'new content';\n $shareUsers = ['us-1'];\n $shareGroups = ['gr-1', 'gr-2'];\n\n $shareUser = $this->createMock(User::class);\n $this->userRepository->expects($this->once())\n ->method('findByUuid')\n ->with('us-1')\n ->willReturn($shareUser);\n $shareGroup1 = $this->createMock(Group::class);\n $shareGroup2 = $this->createMock(Group::class);\n $this->groupRepository->expects($this->exactly(2))\n ->method('findByUuid')\n ->willReturnMap([\n ['gr-1', $shareGroup1],\n ['gr-2', $shareGroup2],\n ]);\n\n $editPrompt = $this->createMock(AskAnythingPrompt::class);\n $editPrompt->expects($this->once())\n ->method('getTitle')\n ->willReturn($title);\n $editPrompt->expects($this->once())\n ->method('getContent')\n ->willReturn($content);\n $editPrompt->expects($this->once())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $editPrompt->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-1st-prompt');\n $this->askAnythingRepository->expects($this->once())\n ->method('editPrompt')\n ->with($prompt, $title, $content, [$shareUser], [$shareGroup1, $shareGroup2])\n ->willReturn($editPrompt);\n\n $expectedDto = new AskAnythingPromptDto(\n 'uuid-1st-prompt',\n $title,\n $content,\n AskAnythingPromptTarget::call,\n 'owner-uuid',\n $shareUsers,\n $shareGroups\n );\n $editDto = $this->askAnythingPromptService->edit($prompt, $user, $title, $content, $shareUsers, $shareGroups);\n\n $this->assertEquals($expectedDto, $editDto);\n }\n\n public function testHideDefaultAndCreateAskAnythingPrompt(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(true);\n $prompt->expects($this->once())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getUuid')\n ->willReturn('new-owner-uuid');\n $title = 'title';\n $content = 'content';\n $shareUsers = ['us-1'];\n $shareGroups = [];\n $shareUser = $this->createMock(User::class);\n $this->userRepository->expects($this->once())\n ->method('findByUuid')\n ->with('us-1')\n ->willReturn($shareUser);\n $this->groupRepository->expects($this->never())\n ->method('findByUuid');\n\n $newPrompt = $this->createMock(AskAnythingPrompt::class);\n $newPrompt->expects($this->once())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $newPrompt->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-1st-prompt');\n $newPrompt->expects($this->once())\n ->method('getTitle')\n ->willReturn($title);\n $newPrompt->expects($this->once())\n ->method('getContent')\n ->willReturn($content);\n\n $this->askAnythingRepository->expects($this->once())\n ->method('hidePromptForUser');\n $this->askAnythingRepository->expects($this->once())\n ->method('createPrompt')\n ->willReturn($newPrompt);\n\n $expectedDto = new AskAnythingPromptDto(\n 'uuid-1st-prompt',\n $title,\n $content,\n AskAnythingPromptTarget::call,\n 'new-owner-uuid',\n $shareUsers,\n $shareGroups\n );\n\n $actualDto = $this->askAnythingPromptService->edit($prompt, $user, $title, $content, $shareUsers, $shareGroups);\n\n $this->assertEquals($expectedDto, $actualDto);\n }\n\n public function testDeleteAskAnythingPrompt(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->any())\n ->method('getId')\n ->willReturn(1);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n\n // Use Mockery for the relationship mock (more flexible)\n $relationMock = \\Mockery::mock(\\Illuminate\\Database\\Eloquent\\Relations\\HasMany::class);\n $relationMock->shouldReceive('withTrashed')\n ->once()\n ->andReturnSelf();\n $relationMock->shouldReceive('update')\n ->once()\n ->with(['ask_anything_prompt_id' => null, 'status' => false]);\n\n $prompt->expects($this->once())\n ->method('automatedReports')\n ->willReturn($relationMock);\n\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(1);\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(1, $user)\n ->willReturn($userPrompt);\n $userPrompt->expects($this->once())\n ->method('delete');\n $this->askAnythingRepository->expects($this->any())\n ->method('findSharedUsersAndGroupsByPromptId')\n ->with(1)\n ->willReturn(new Collection([]));\n $this->askAnythingRepository->expects($this->once())\n ->method('deletePrompt');\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testDeleteAskAnythingPromptWithRelations(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->any())\n ->method('getId')\n ->willReturn(1);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $user = $this->createMock(User::class);\n $user->expects($this->any())\n ->method('getId')\n ->willReturn(1);\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(1, $user)\n ->willReturn($userPrompt);\n $userPrompt->expects($this->once())\n ->method('delete');\n $this->askAnythingRepository->expects($this->exactly(3))\n ->method('findSharedUsersAndGroupsByPromptId')\n ->willReturnMap([\n [1, new Collection([$userPrompt])],\n [1, new Collection([])],\n ]);\n $this->askAnythingRepository->expects($this->never())\n ->method('deletePrompt');\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testHideDefaultAskAnythingPrompt(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(true);\n $user = $this->createMock(User::class);\n $this->askAnythingRepository->expects($this->once())\n ->method('hidePromptForUser');\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testHideSharedWithUserAskAnythingPrompt(): void\n {\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $prompt->expects($this->exactly(3))\n ->method('getId')\n ->willReturn(33);\n\n $relationMock = \\Mockery::mock(\\Illuminate\\Database\\Eloquent\\Relations\\HasMany::class);\n $relationMock->shouldReceive('withTrashed')\n ->once()\n ->andReturnSelf();\n $relationMock->shouldReceive('update')\n ->once()\n ->with(['ask_anything_prompt_id' => null, 'status' => false]);\n $prompt->expects($this->once())\n ->method('automatedReports')\n ->willReturn($relationMock);\n\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(2);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(33, $user)\n ->willReturn($userPrompt);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUserGroup')\n ->with(33, $user)\n ->willReturn(null);\n $userPrompt->expects($this->once())\n ->method('delete');\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedUsersAndGroupsByPromptId')\n ->with(33)\n ->willReturn(new Collection([]));\n\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testHideSharedWithUserAndGroupAskAnythingPrompt(): void\n {\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $prompt->expects($this->exactly(2))\n ->method('getId')\n ->willReturn(33);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(2);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(33, $user)\n ->willReturn($userPrompt);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUserGroup')\n ->with(33, $user)\n ->willReturn($userPrompt);\n $userPrompt->expects($this->never())\n ->method('delete');\n $this->askAnythingRepository->expects($this->once())\n ->method('hidePromptForUser')\n ->with($prompt, $user);\n\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testHideSharedWithGroupAskAnythingPrompt(): void\n {\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $prompt->expects($this->exactly(2))\n ->method('getId')\n ->willReturn(33);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(2);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(33, $user)\n ->willReturn(null);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUserGroup')\n ->with(33, $user)\n ->willReturn($userPrompt);\n $userPrompt->expects($this->never())\n ->method('delete');\n $this->askAnythingRepository->expects($this->once())\n ->method('hidePromptForUser')\n ->with($prompt, $user);\n\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testDeleteWithNoSharesAndNotOwner(): void\n {\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $prompt->expects($this->exactly(2))\n ->method('getId')\n ->willReturn(33);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(2);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(33, $user)\n ->willReturn(null);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUserGroup')\n ->with(33, $user)\n ->willReturn(null);\n $userPrompt->expects($this->never())\n ->method('delete');\n $this->askAnythingRepository->expects($this->never())\n ->method('hidePromptForUser');\n\n $this->expectException(\\InvalidArgumentException::class);\n\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testReorderAskAnythingPrompts(): void\n {\n $prompts = ['id1', 'id2', 'id3'];\n $prompt1 = $this->createMock(AskAnythingPrompt::class);\n $prompt2 = $this->createMock(AskAnythingPrompt::class);\n $prompt3 = $this->createMock(AskAnythingPrompt::class);\n $user = $this->createMock(User::class);\n $this->askAnythingRepository->expects($this->exactly(3))\n ->method('getPromptByUuid')\n ->willReturnMap([\n ['id1', $prompt1],\n ['id2', $prompt2],\n ['id3', $prompt3],\n ]);\n $this->askAnythingRepository->expects($this->exactly(3))\n ->method('orderPromptForUser')\n ->willReturnMap([\n [[$prompt1, $user, 1]],\n [[$prompt2, $user, 2]],\n [[$prompt3, $user, 3]],\n ]);\n $this->askAnythingPromptService->reorder($user, $prompts);\n }\n\n public function testCreateAskAnythingPromptWithTwoUsers(): void\n {\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-of-the-user');\n $shareUser1 = $this->createMock(User::class);\n $shareUser2 = $this->createMock(User::class);\n $title = 'Test title';\n $content = 'Test content';\n $target = AskAnythingPromptTarget::call;\n $shareUsers = ['us-1', 'us-2'];\n $shareGroups = [];\n\n $this->userRepository->expects($this->exactly(2))\n ->method('findByUuid')\n ->willReturnMap([\n ['us-1', $shareUser1],\n ['us-2', $shareUser2],\n ]);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('getUuid')\n ->willReturn('prompt-1-uuid');\n $prompt->expects($this->once())\n ->method('getTitle')\n ->willReturn($title);\n $prompt->expects($this->once())\n ->method('getContent')\n ->willReturn($content);\n $this->askAnythingRepository->expects($this->once())\n ->method('createPrompt')\n ->with(\n $user,\n $target,\n $title,\n $content,\n [$shareUser1, $shareUser2],\n [],\n )\n ->willReturn($prompt);\n\n $expectedPromptDto = new AskAnythingPromptDto(\n 'prompt-1-uuid',\n $title,\n $content,\n $target,\n 'uuid-of-the-user',\n $shareUsers,\n $shareGroups,\n );\n\n $actualPromptDto = $this->askAnythingPromptService->create(\n $user,\n $title,\n $content,\n $target,\n $shareUsers,\n $shareGroups\n );\n\n $this->assertEquals($expectedPromptDto, $actualPromptDto);\n }\n\n public function testRecreatePromptsForUserRelations(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('getId')\n ->willReturn(1);\n $prompt->expects($this->once())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $prompt->expects($this->once())\n ->method('getTitle')\n ->willReturn('Test title');\n $prompt->expects($this->once())\n ->method('getContent')\n ->willReturn('Test content');\n\n $sharedPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $sharedUser = $this->createMock(User::class);\n $sharedUser->expects($this->once())\n ->method('isStatusActive')\n ->willReturn(true);\n $sharedUser->expects($this->once())\n ->method('getId')\n ->willReturn(1);\n\n $sharedPrompt->expects($this->once())\n ->method('getUser')\n ->willReturn($sharedUser);\n $sharedPrompt->expects($this->exactly(2))\n ->method('isRemoved')\n ->willReturn(false);\n $sharedPrompt->expects($this->once())\n ->method('delete');\n\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedUsersAndGroupsByPromptId')\n ->with(1)\n ->willReturn(new Collection([$sharedPrompt]));\n\n $this->askAnythingRepository->expects($this->once())\n ->method('createPrompt');\n\n $data = $this->invokePrivateMethod('recreatePromptsForUserRelations', $this->askAnythingPromptService, [$prompt]);\n\n $this->assertEquals([[1], []], $data);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Component\\AskAnything;\n\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Jiminny\\Component\\AskAnything\\AskAnythingPromptService;\nuse Jiminny\\Component\\AskAnything\\Dtos\\AskAnythingPromptDto;\nuse Jiminny\\Contracts\\Repositories\\GroupRepositoryInterface;\nuse Jiminny\\Models\\AskAnything\\AskAnythingPrompt;\nuse Jiminny\\Models\\AskAnything\\AskAnythingPromptTarget;\nuse Jiminny\\Models\\AskAnything\\UserAskAnythingPrompt;\nuse Jiminny\\Models\\Group;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AskAnythingRepository;\nuse Jiminny\\Repositories\\UserRepository;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Tests\\TestCase;\nuse Tests\\Unit\\Traits\\TestPrivateMethod;\n\nclass AskAnythingPromptServiceTest extends TestCase\n{\n use TestPrivateMethod;\n\n private AskAnythingPromptService $askAnythingPromptService;\n private AskAnythingRepository&MockObject $askAnythingRepository;\n private UserRepository&MockObject $userRepository;\n private GroupRepositoryInterface&MockObject $groupRepository;\n\n protected function setUp(): void\n {\n $this->askAnythingRepository = $this->createMock(AskAnythingRepository::class);\n $this->userRepository = $this->createMock(UserRepository::class);\n $this->groupRepository = $this->createMock(GroupRepositoryInterface::class);\n\n $this->askAnythingPromptService = new AskAnythingPromptService(\n $this->askAnythingRepository,\n $this->userRepository,\n $this->groupRepository\n );\n }\n\n public function testGetAskAnythingPrompts(): void\n {\n $user = $this->createMock(User::class);\n $user->expects($this->any())\n ->method('getId')\n ->willReturn(1);\n $user->expects($this->any())\n ->method('getUuid')\n ->willReturn('1');\n $defaultPrompt = $this->createMock(AskAnythingPrompt::class);\n $defaultPrompt->expects($this->once())\n ->method('getOwner')\n ->willReturn(null);\n $defaultPrompt->expects($this->once())\n ->method('getUuid')\n ->willReturn('default-uuid');\n $defaultPrompt->expects($this->once())\n ->method('getTitle')\n ->willReturn('Sentiment');\n $defaultPrompt->expects($this->once())\n ->method('getContent')\n ->willReturn('What was the overall sentiment of the customer during the call?');\n $defaultPrompt->expects($this->once())\n ->method('getHasReports')\n ->willReturn(false);\n $promptOwnedByUser = $this->createMock(AskAnythingPrompt::class);\n $promptOwnedByUser->expects($this->exactly(2))\n ->method('getOwner')\n ->willReturn($user);\n $promptOwnedByUser->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-1st-prompt');\n $promptOwnedByUser->expects($this->once())\n ->method('getTitle')\n ->willReturn('First users prompt');\n $promptOwnedByUser->expects($this->once())\n ->method('getContent')\n ->willReturn('Test prompt');\n $promptOwnedByUser->expects($this->once())\n ->method('getId')\n ->willReturn(99);\n $promptOwnedByUser->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $promptOwnedByUser->expects($this->once())\n ->method('getHasReports')\n ->willReturn(true);\n $defaultPromptOrderedByUser = $this->createMock(AskAnythingPrompt::class);\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getOwner')\n ->willReturn(null);\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getUuid')\n ->willReturn('default-uuid');\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getTitle')\n ->willReturn('Sentiment');\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getContent')\n ->willReturn('What was the overall sentiment of the customer during the call?');\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getHasReports')\n ->willReturn(false);\n $promptOwnedByUserAndSharedWithGroup = $this->createMock(AskAnythingPrompt::class);\n $promptOwnedByUserAndSharedWithGroup->expects($this->exactly(2))\n ->method('getOwner')\n ->willReturn($user);\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-2nd-prompt');\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getTitle')\n ->willReturn('Prompt shared with group');\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getContent')\n ->willReturn('Test prompt that is shared with group');\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getId')\n ->willReturn(109);\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getHasReports')\n ->willReturn(false);\n\n $group = $this->createMock(Group::class);\n $group->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-of-the-group');\n $sharedWithGroup = $this->createMock(UserAskAnythingPrompt::class);\n $sharedWithGroup->expects($this->once())\n ->method('getUser')\n ->willReturn(null);\n $sharedWithGroup->expects($this->once())\n ->method('getGroup')\n ->willReturn($group);\n\n $this->askAnythingRepository->expects($this->exactly(2))\n ->method('findSharedUsersAndGroupsByPromptId')\n ->willReturnMap([\n [99, new Collection([])],\n [109, new Collection([$sharedWithGroup])],\n ]);\n\n $prompts = [$defaultPrompt, $promptOwnedByUser, $defaultPromptOrderedByUser, $promptOwnedByUserAndSharedWithGroup];\n $this->askAnythingRepository->expects($this->once())\n ->method('findPromptsByUserAndTarget')\n ->willReturn(new Collection($prompts));\n\n $expectedDto1 = new AskAnythingPromptDto(\n 'default-uuid',\n 'Sentiment',\n 'What was the overall sentiment of the customer during the call?',\n AskAnythingPromptTarget::call,\n null,\n null,\n null,\n false,\n );\n $expectedDto2 = new AskAnythingPromptDto(\n 'uuid-1st-prompt',\n 'First users prompt',\n 'Test prompt',\n AskAnythingPromptTarget::call,\n '1',\n [],\n [],\n true,\n );\n $expectedDto3 = new AskAnythingPromptDto(\n 'default-uuid',\n 'Sentiment',\n 'What was the overall sentiment of the customer during the call?',\n AskAnythingPromptTarget::call,\n null,\n null,\n null,\n false,\n );\n $expectedDto4 = new AskAnythingPromptDto(\n 'uuid-2nd-prompt',\n 'Prompt shared with group',\n 'Test prompt that is shared with group',\n AskAnythingPromptTarget::call,\n '1',\n [],\n ['uuid-of-the-group'],\n false,\n );\n $dtos = $this->askAnythingPromptService->get($user, AskAnythingPromptTarget::call);\n\n $this->assertEquals([$expectedDto1, $expectedDto2, $expectedDto3, $expectedDto4], $dtos);\n }\n\n public function testEditAskAnythingPrompt(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(123);\n $prompt->expects($this->never())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(123);\n $user->expects($this->once())\n ->method('getUuid')\n ->willReturn('owner-uuid');\n\n $title = 'new title';\n $content = 'new content';\n $shareUsers = ['us-1'];\n $shareGroups = ['gr-1', 'gr-2'];\n\n $shareUser = $this->createMock(User::class);\n $this->userRepository->expects($this->once())\n ->method('findByUuid')\n ->with('us-1')\n ->willReturn($shareUser);\n $shareGroup1 = $this->createMock(Group::class);\n $shareGroup2 = $this->createMock(Group::class);\n $this->groupRepository->expects($this->exactly(2))\n ->method('findByUuid')\n ->willReturnMap([\n ['gr-1', $shareGroup1],\n ['gr-2', $shareGroup2],\n ]);\n\n $editPrompt = $this->createMock(AskAnythingPrompt::class);\n $editPrompt->expects($this->once())\n ->method('getTitle')\n ->willReturn($title);\n $editPrompt->expects($this->once())\n ->method('getContent')\n ->willReturn($content);\n $editPrompt->expects($this->once())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $editPrompt->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-1st-prompt');\n $this->askAnythingRepository->expects($this->once())\n ->method('editPrompt')\n ->with($prompt, $title, $content, [$shareUser], [$shareGroup1, $shareGroup2])\n ->willReturn($editPrompt);\n\n $expectedDto = new AskAnythingPromptDto(\n 'uuid-1st-prompt',\n $title,\n $content,\n AskAnythingPromptTarget::call,\n 'owner-uuid',\n $shareUsers,\n $shareGroups\n );\n $editDto = $this->askAnythingPromptService->edit($prompt, $user, $title, $content, $shareUsers, $shareGroups);\n\n $this->assertEquals($expectedDto, $editDto);\n }\n\n public function testHideDefaultAndCreateAskAnythingPrompt(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(true);\n $prompt->expects($this->once())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getUuid')\n ->willReturn('new-owner-uuid');\n $title = 'title';\n $content = 'content';\n $shareUsers = ['us-1'];\n $shareGroups = [];\n $shareUser = $this->createMock(User::class);\n $this->userRepository->expects($this->once())\n ->method('findByUuid')\n ->with('us-1')\n ->willReturn($shareUser);\n $this->groupRepository->expects($this->never())\n ->method('findByUuid');\n\n $newPrompt = $this->createMock(AskAnythingPrompt::class);\n $newPrompt->expects($this->once())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $newPrompt->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-1st-prompt');\n $newPrompt->expects($this->once())\n ->method('getTitle')\n ->willReturn($title);\n $newPrompt->expects($this->once())\n ->method('getContent')\n ->willReturn($content);\n\n $this->askAnythingRepository->expects($this->once())\n ->method('hidePromptForUser');\n $this->askAnythingRepository->expects($this->once())\n ->method('createPrompt')\n ->willReturn($newPrompt);\n\n $expectedDto = new AskAnythingPromptDto(\n 'uuid-1st-prompt',\n $title,\n $content,\n AskAnythingPromptTarget::call,\n 'new-owner-uuid',\n $shareUsers,\n $shareGroups\n );\n\n $actualDto = $this->askAnythingPromptService->edit($prompt, $user, $title, $content, $shareUsers, $shareGroups);\n\n $this->assertEquals($expectedDto, $actualDto);\n }\n\n public function testDeleteAskAnythingPrompt(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->any())\n ->method('getId')\n ->willReturn(1);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n\n // Use Mockery for the relationship mock (more flexible)\n $relationMock = \\Mockery::mock(\\Illuminate\\Database\\Eloquent\\Relations\\HasMany::class);\n $relationMock->shouldReceive('withTrashed')\n ->once()\n ->andReturnSelf();\n $relationMock->shouldReceive('update')\n ->once()\n ->with(['ask_anything_prompt_id' => null, 'status' => false]);\n\n $prompt->expects($this->once())\n ->method('automatedReports')\n ->willReturn($relationMock);\n\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(1);\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(1, $user)\n ->willReturn($userPrompt);\n $userPrompt->expects($this->once())\n ->method('delete');\n $this->askAnythingRepository->expects($this->any())\n ->method('findSharedUsersAndGroupsByPromptId')\n ->with(1)\n ->willReturn(new Collection([]));\n $this->askAnythingRepository->expects($this->once())\n ->method('deletePrompt');\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testDeleteAskAnythingPromptWithRelations(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->any())\n ->method('getId')\n ->willReturn(1);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $user = $this->createMock(User::class);\n $user->expects($this->any())\n ->method('getId')\n ->willReturn(1);\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(1, $user)\n ->willReturn($userPrompt);\n $userPrompt->expects($this->once())\n ->method('delete');\n $this->askAnythingRepository->expects($this->exactly(3))\n ->method('findSharedUsersAndGroupsByPromptId')\n ->willReturnMap([\n [1, new Collection([$userPrompt])],\n [1, new Collection([])],\n ]);\n $this->askAnythingRepository->expects($this->never())\n ->method('deletePrompt');\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testHideDefaultAskAnythingPrompt(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(true);\n $user = $this->createMock(User::class);\n $this->askAnythingRepository->expects($this->once())\n ->method('hidePromptForUser');\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testHideSharedWithUserAskAnythingPrompt(): void\n {\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $prompt->expects($this->exactly(3))\n ->method('getId')\n ->willReturn(33);\n\n $relationMock = \\Mockery::mock(\\Illuminate\\Database\\Eloquent\\Relations\\HasMany::class);\n $relationMock->shouldReceive('withTrashed')\n ->once()\n ->andReturnSelf();\n $relationMock->shouldReceive('update')\n ->once()\n ->with(['ask_anything_prompt_id' => null, 'status' => false]);\n $prompt->expects($this->once())\n ->method('automatedReports')\n ->willReturn($relationMock);\n\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(2);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(33, $user)\n ->willReturn($userPrompt);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUserGroup')\n ->with(33, $user)\n ->willReturn(null);\n $userPrompt->expects($this->once())\n ->method('delete');\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedUsersAndGroupsByPromptId')\n ->with(33)\n ->willReturn(new Collection([]));\n\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testHideSharedWithUserAndGroupAskAnythingPrompt(): void\n {\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $prompt->expects($this->exactly(2))\n ->method('getId')\n ->willReturn(33);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(2);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(33, $user)\n ->willReturn($userPrompt);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUserGroup')\n ->with(33, $user)\n ->willReturn($userPrompt);\n $userPrompt->expects($this->never())\n ->method('delete');\n $this->askAnythingRepository->expects($this->once())\n ->method('hidePromptForUser')\n ->with($prompt, $user);\n\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testHideSharedWithGroupAskAnythingPrompt(): void\n {\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $prompt->expects($this->exactly(2))\n ->method('getId')\n ->willReturn(33);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(2);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(33, $user)\n ->willReturn(null);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUserGroup')\n ->with(33, $user)\n ->willReturn($userPrompt);\n $userPrompt->expects($this->never())\n ->method('delete');\n $this->askAnythingRepository->expects($this->once())\n ->method('hidePromptForUser')\n ->with($prompt, $user);\n\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testDeleteWithNoSharesAndNotOwner(): void\n {\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $prompt->expects($this->exactly(2))\n ->method('getId')\n ->willReturn(33);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(2);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(33, $user)\n ->willReturn(null);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUserGroup')\n ->with(33, $user)\n ->willReturn(null);\n $userPrompt->expects($this->never())\n ->method('delete');\n $this->askAnythingRepository->expects($this->never())\n ->method('hidePromptForUser');\n\n $this->expectException(\\InvalidArgumentException::class);\n\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testReorderAskAnythingPrompts(): void\n {\n $prompts = ['id1', 'id2', 'id3'];\n $prompt1 = $this->createMock(AskAnythingPrompt::class);\n $prompt2 = $this->createMock(AskAnythingPrompt::class);\n $prompt3 = $this->createMock(AskAnythingPrompt::class);\n $user = $this->createMock(User::class);\n $this->askAnythingRepository->expects($this->exactly(3))\n ->method('getPromptByUuid')\n ->willReturnMap([\n ['id1', $prompt1],\n ['id2', $prompt2],\n ['id3', $prompt3],\n ]);\n $this->askAnythingRepository->expects($this->exactly(3))\n ->method('orderPromptForUser')\n ->willReturnMap([\n [[$prompt1, $user, 1]],\n [[$prompt2, $user, 2]],\n [[$prompt3, $user, 3]],\n ]);\n $this->askAnythingPromptService->reorder($user, $prompts);\n }\n\n public function testCreateAskAnythingPromptWithTwoUsers(): void\n {\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-of-the-user');\n $shareUser1 = $this->createMock(User::class);\n $shareUser2 = $this->createMock(User::class);\n $title = 'Test title';\n $content = 'Test content';\n $target = AskAnythingPromptTarget::call;\n $shareUsers = ['us-1', 'us-2'];\n $shareGroups = [];\n\n $this->userRepository->expects($this->exactly(2))\n ->method('findByUuid')\n ->willReturnMap([\n ['us-1', $shareUser1],\n ['us-2', $shareUser2],\n ]);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('getUuid')\n ->willReturn('prompt-1-uuid');\n $prompt->expects($this->once())\n ->method('getTitle')\n ->willReturn($title);\n $prompt->expects($this->once())\n ->method('getContent')\n ->willReturn($content);\n $this->askAnythingRepository->expects($this->once())\n ->method('createPrompt')\n ->with(\n $user,\n $target,\n $title,\n $content,\n [$shareUser1, $shareUser2],\n [],\n )\n ->willReturn($prompt);\n\n $expectedPromptDto = new AskAnythingPromptDto(\n 'prompt-1-uuid',\n $title,\n $content,\n $target,\n 'uuid-of-the-user',\n $shareUsers,\n $shareGroups,\n );\n\n $actualPromptDto = $this->askAnythingPromptService->create(\n $user,\n $title,\n $content,\n $target,\n $shareUsers,\n $shareGroups\n );\n\n $this->assertEquals($expectedPromptDto, $actualPromptDto);\n }\n\n public function testRecreatePromptsForUserRelations(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('getId')\n ->willReturn(1);\n $prompt->expects($this->once())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $prompt->expects($this->once())\n ->method('getTitle')\n ->willReturn('Test title');\n $prompt->expects($this->once())\n ->method('getContent')\n ->willReturn('Test content');\n\n $sharedPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $sharedUser = $this->createMock(User::class);\n $sharedUser->expects($this->once())\n ->method('isStatusActive')\n ->willReturn(true);\n $sharedUser->expects($this->once())\n ->method('getId')\n ->willReturn(1);\n\n $sharedPrompt->expects($this->once())\n ->method('getUser')\n ->willReturn($sharedUser);\n $sharedPrompt->expects($this->exactly(2))\n ->method('isRemoved')\n ->willReturn(false);\n $sharedPrompt->expects($this->once())\n ->method('delete');\n\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedUsersAndGroupsByPromptId')\n ->with(1)\n ->willReturn(new Collection([$sharedPrompt]));\n\n $this->askAnythingRepository->expects($this->once())\n ->method('createPrompt');\n\n $data = $this->invokePrivateMethod('recreatePromptsForUserRelations', $this->askAnythingPromptService, [$prompt]);\n\n $this->assertEquals([[1], []], $data);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.7124335,"top":0.10055866,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.72140956,"top":0.09896249,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.7287234,"top":0.09896249,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","depth":4,"bounds":{"left":0.4481383,"top":0.09736632,"width":0.29288563,"height":0.8818835},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
1140439531069478179
|
-8755961741003010129
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20676-delete-report-re Project: faVsco.js, menu
JY-20676-delete-report-related-objects, 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
6
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Component\AskAnything;
use Illuminate\Database\Eloquent\Collection;
use Jiminny\Component\AskAnything\AskAnythingPromptService;
use Jiminny\Component\AskAnything\Dtos\AskAnythingPromptDto;
use Jiminny\Contracts\Repositories\GroupRepositoryInterface;
use Jiminny\Models\AskAnything\AskAnythingPrompt;
use Jiminny\Models\AskAnything\AskAnythingPromptTarget;
use Jiminny\Models\AskAnything\UserAskAnythingPrompt;
use Jiminny\Models\Group;
use Jiminny\Models\User;
use Jiminny\Repositories\AskAnythingRepository;
use Jiminny\Repositories\UserRepository;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
use Tests\Unit\Traits\TestPrivateMethod;
class AskAnythingPromptServiceTest extends TestCase
{
use TestPrivateMethod;
private AskAnythingPromptService $askAnythingPromptService;
private AskAnythingRepository&MockObject $askAnythingRepository;
private UserRepository&MockObject $userRepository;
private GroupRepositoryInterface&MockObject $groupRepository;
protected function setUp(): void
{
$this->askAnythingRepository = $this->createMock(AskAnythingRepository::class);
$this->userRepository = $this->createMock(UserRepository::class);
$this->groupRepository = $this->createMock(GroupRepositoryInterface::class);
$this->askAnythingPromptService = new AskAnythingPromptService(
$this->askAnythingRepository,
$this->userRepository,
$this->groupRepository
);
}
public function testGetAskAnythingPrompts(): void
{
$user = $this->createMock(User::class);
$user->expects($this->any())
->method('getId')
->willReturn(1);
$user->expects($this->any())
->method('getUuid')
->willReturn('1');
$defaultPrompt = $this->createMock(AskAnythingPrompt::class);
$defaultPrompt->expects($this->once())
->method('getOwner')
->willReturn(null);
$defaultPrompt->expects($this->once())
->method('getUuid')
->willReturn('default-uuid');
$defaultPrompt->expects($this->once())
->method('getTitle')
->willReturn('Sentiment');
$defaultPrompt->expects($this->once())
->method('getContent')
->willReturn('What was the overall sentiment of the customer during the call?');
$defaultPrompt->expects($this->once())
->method('getHasReports')
->willReturn(false);
$promptOwnedByUser = $this->createMock(AskAnythingPrompt::class);
$promptOwnedByUser->expects($this->exactly(2))
->method('getOwner')
->willReturn($user);
$promptOwnedByUser->expects($this->once())
->method('getUuid')
->willReturn('uuid-1st-prompt');
$promptOwnedByUser->expects($this->once())
->method('getTitle')
->willReturn('First users prompt');
$promptOwnedByUser->expects($this->once())
->method('getContent')
->willReturn('Test prompt');
$promptOwnedByUser->expects($this->once())
->method('getId')
->willReturn(99);
$promptOwnedByUser->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$promptOwnedByUser->expects($this->once())
->method('getHasReports')
->willReturn(true);
$defaultPromptOrderedByUser = $this->createMock(AskAnythingPrompt::class);
$defaultPromptOrderedByUser->expects($this->once())
->method('getOwner')
->willReturn(null);
$defaultPromptOrderedByUser->expects($this->once())
->method('getUuid')
->willReturn('default-uuid');
$defaultPromptOrderedByUser->expects($this->once())
->method('getTitle')
->willReturn('Sentiment');
$defaultPromptOrderedByUser->expects($this->once())
->method('getContent')
->willReturn('What was the overall sentiment of the customer during the call?');
$defaultPromptOrderedByUser->expects($this->once())
->method('getHasReports')
->willReturn(false);
$promptOwnedByUserAndSharedWithGroup = $this->createMock(AskAnythingPrompt::class);
$promptOwnedByUserAndSharedWithGroup->expects($this->exactly(2))
->method('getOwner')
->willReturn($user);
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getUuid')
->willReturn('uuid-2nd-prompt');
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getTitle')
->willReturn('Prompt shared with group');
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getContent')
->willReturn('Test prompt that is shared with group');
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getId')
->willReturn(109);
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getHasReports')
->willReturn(false);
$group = $this->createMock(Group::class);
$group->expects($this->once())
->method('getUuid')
->willReturn('uuid-of-the-group');
$sharedWithGroup = $this->createMock(UserAskAnythingPrompt::class);
$sharedWithGroup->expects($this->once())
->method('getUser')
->willReturn(null);
$sharedWithGroup->expects($this->once())
->method('getGroup')
->willReturn($group);
$this->askAnythingRepository->expects($this->exactly(2))
->method('findSharedUsersAndGroupsByPromptId')
->willReturnMap([
[99, new Collection([])],
[109, new Collection([$sharedWithGroup])],
]);
$prompts = [$defaultPrompt, $promptOwnedByUser, $defaultPromptOrderedByUser, $promptOwnedByUserAndSharedWithGroup];
$this->askAnythingRepository->expects($this->once())
->method('findPromptsByUserAndTarget')
->willReturn(new Collection($prompts));
$expectedDto1 = new AskAnythingPromptDto(
'default-uuid',
'Sentiment',
'What was the overall sentiment of the customer during the call?',
AskAnythingPromptTarget::call,
null,
null,
null,
false,
);
$expectedDto2 = new AskAnythingPromptDto(
'uuid-1st-prompt',
'First users prompt',
'Test prompt',
AskAnythingPromptTarget::call,
'1',
[],
[],
true,
);
$expectedDto3 = new AskAnythingPromptDto(
'default-uuid',
'Sentiment',
'What was the overall sentiment of the customer during the call?',
AskAnythingPromptTarget::call,
null,
null,
null,
false,
);
$expectedDto4 = new AskAnythingPromptDto(
'uuid-2nd-prompt',
'Prompt shared with group',
'Test prompt that is shared with group',
AskAnythingPromptTarget::call,
'1',
[],
['uuid-of-the-group'],
false,
);
$dtos = $this->askAnythingPromptService->get($user, AskAnythingPromptTarget::call);
$this->assertEquals([$expectedDto1, $expectedDto2, $expectedDto3, $expectedDto4], $dtos);
}
public function testEditAskAnythingPrompt(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(123);
$prompt->expects($this->never())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(123);
$user->expects($this->once())
->method('getUuid')
->willReturn('owner-uuid');
$title = 'new title';
$content = 'new content';
$shareUsers = ['us-1'];
$shareGroups = ['gr-1', 'gr-2'];
$shareUser = $this->createMock(User::class);
$this->userRepository->expects($this->once())
->method('findByUuid')
->with('us-1')
->willReturn($shareUser);
$shareGroup1 = $this->createMock(Group::class);
$shareGroup2 = $this->createMock(Group::class);
$this->groupRepository->expects($this->exactly(2))
->method('findByUuid')
->willReturnMap([
['gr-1', $shareGroup1],
['gr-2', $shareGroup2],
]);
$editPrompt = $this->createMock(AskAnythingPrompt::class);
$editPrompt->expects($this->once())
->method('getTitle')
->willReturn($title);
$editPrompt->expects($this->once())
->method('getContent')
->willReturn($content);
$editPrompt->expects($this->once())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$editPrompt->expects($this->once())
->method('getUuid')
->willReturn('uuid-1st-prompt');
$this->askAnythingRepository->expects($this->once())
->method('editPrompt')
->with($prompt, $title, $content, [$shareUser], [$shareGroup1, $shareGroup2])
->willReturn($editPrompt);
$expectedDto = new AskAnythingPromptDto(
'uuid-1st-prompt',
$title,
$content,
AskAnythingPromptTarget::call,
'owner-uuid',
$shareUsers,
$shareGroups
);
$editDto = $this->askAnythingPromptService->edit($prompt, $user, $title, $content, $shareUsers, $shareGroups);
$this->assertEquals($expectedDto, $editDto);
}
public function testHideDefaultAndCreateAskAnythingPrompt(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(true);
$prompt->expects($this->once())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getUuid')
->willReturn('new-owner-uuid');
$title = 'title';
$content = 'content';
$shareUsers = ['us-1'];
$shareGroups = [];
$shareUser = $this->createMock(User::class);
$this->userRepository->expects($this->once())
->method('findByUuid')
->with('us-1')
->willReturn($shareUser);
$this->groupRepository->expects($this->never())
->method('findByUuid');
$newPrompt = $this->createMock(AskAnythingPrompt::class);
$newPrompt->expects($this->once())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$newPrompt->expects($this->once())
->method('getUuid')
->willReturn('uuid-1st-prompt');
$newPrompt->expects($this->once())
->method('getTitle')
->willReturn($title);
$newPrompt->expects($this->once())
->method('getContent')
->willReturn($content);
$this->askAnythingRepository->expects($this->once())
->method('hidePromptForUser');
$this->askAnythingRepository->expects($this->once())
->method('createPrompt')
->willReturn($newPrompt);
$expectedDto = new AskAnythingPromptDto(
'uuid-1st-prompt',
$title,
$content,
AskAnythingPromptTarget::call,
'new-owner-uuid',
$shareUsers,
$shareGroups
);
$actualDto = $this->askAnythingPromptService->edit($prompt, $user, $title, $content, $shareUsers, $shareGroups);
$this->assertEquals($expectedDto, $actualDto);
}
public function testDeleteAskAnythingPrompt(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->any())
->method('getId')
->willReturn(1);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
// Use Mockery for the relationship mock (more flexible)
$relationMock = \Mockery::mock(\Illuminate\Database\Eloquent\Relations\HasMany::class);
$relationMock->shouldReceive('withTrashed')
->once()
->andReturnSelf();
$relationMock->shouldReceive('update')
->once()
->with(['ask_anything_prompt_id' => null, 'status' => false]);
$prompt->expects($this->once())
->method('automatedReports')
->willReturn($relationMock);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(1);
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(1, $user)
->willReturn($userPrompt);
$userPrompt->expects($this->once())
->method('delete');
$this->askAnythingRepository->expects($this->any())
->method('findSharedUsersAndGroupsByPromptId')
->with(1)
->willReturn(new Collection([]));
$this->askAnythingRepository->expects($this->once())
->method('deletePrompt');
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testDeleteAskAnythingPromptWithRelations(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->any())
->method('getId')
->willReturn(1);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$user = $this->createMock(User::class);
$user->expects($this->any())
->method('getId')
->willReturn(1);
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(1, $user)
->willReturn($userPrompt);
$userPrompt->expects($this->once())
->method('delete');
$this->askAnythingRepository->expects($this->exactly(3))
->method('findSharedUsersAndGroupsByPromptId')
->willReturnMap([
[1, new Collection([$userPrompt])],
[1, new Collection([])],
]);
$this->askAnythingRepository->expects($this->never())
->method('deletePrompt');
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testHideDefaultAskAnythingPrompt(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(true);
$user = $this->createMock(User::class);
$this->askAnythingRepository->expects($this->once())
->method('hidePromptForUser');
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testHideSharedWithUserAskAnythingPrompt(): void
{
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$prompt->expects($this->exactly(3))
->method('getId')
->willReturn(33);
$relationMock = \Mockery::mock(\Illuminate\Database\Eloquent\Relations\HasMany::class);
$relationMock->shouldReceive('withTrashed')
->once()
->andReturnSelf();
$relationMock->shouldReceive('update')
->once()
->with(['ask_anything_prompt_id' => null, 'status' => false]);
$prompt->expects($this->once())
->method('automatedReports')
->willReturn($relationMock);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(2);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(33, $user)
->willReturn($userPrompt);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUserGroup')
->with(33, $user)
->willReturn(null);
$userPrompt->expects($this->once())
->method('delete');
$this->askAnythingRepository->expects($this->once())
->method('findSharedUsersAndGroupsByPromptId')
->with(33)
->willReturn(new Collection([]));
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testHideSharedWithUserAndGroupAskAnythingPrompt(): void
{
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$prompt->expects($this->exactly(2))
->method('getId')
->willReturn(33);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(2);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(33, $user)
->willReturn($userPrompt);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUserGroup')
->with(33, $user)
->willReturn($userPrompt);
$userPrompt->expects($this->never())
->method('delete');
$this->askAnythingRepository->expects($this->once())
->method('hidePromptForUser')
->with($prompt, $user);
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testHideSharedWithGroupAskAnythingPrompt(): void
{
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$prompt->expects($this->exactly(2))
->method('getId')
->willReturn(33);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(2);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(33, $user)
->willReturn(null);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUserGroup')
->with(33, $user)
->willReturn($userPrompt);
$userPrompt->expects($this->never())
->method('delete');
$this->askAnythingRepository->expects($this->once())
->method('hidePromptForUser')
->with($prompt, $user);
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testDeleteWithNoSharesAndNotOwner(): void
{
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$prompt->expects($this->exactly(2))
->method('getId')
->willReturn(33);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(2);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(33, $user)
->willReturn(null);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUserGroup')
->with(33, $user)
->willReturn(null);
$userPrompt->expects($this->never())
->method('delete');
$this->askAnythingRepository->expects($this->never())
->method('hidePromptForUser');
$this->expectException(\InvalidArgumentException::class);
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testReorderAskAnythingPrompts(): void
{
$prompts = ['id1', 'id2', 'id3'];
$prompt1 = $this->createMock(AskAnythingPrompt::class);
$prompt2 = $this->createMock(AskAnythingPrompt::class);
$prompt3 = $this->createMock(AskAnythingPrompt::class);
$user = $this->createMock(User::class);
$this->askAnythingRepository->expects($this->exactly(3))
->method('getPromptByUuid')
->willReturnMap([
['id1', $prompt1],
['id2', $prompt2],
['id3', $prompt3],
]);
$this->askAnythingRepository->expects($this->exactly(3))
->method('orderPromptForUser')
->willReturnMap([
[[$prompt1, $user, 1]],
[[$prompt2, $user, 2]],
[[$prompt3, $user, 3]],
]);
$this->askAnythingPromptService->reorder($user, $prompts);
}
public function testCreateAskAnythingPromptWithTwoUsers(): void
{
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getUuid')
->willReturn('uuid-of-the-user');
$shareUser1 = $this->createMock(User::class);
$shareUser2 = $this->createMock(User::class);
$title = 'Test title';
$content = 'Test content';
$target = AskAnythingPromptTarget::call;
$shareUsers = ['us-1', 'us-2'];
$shareGroups = [];
$this->userRepository->expects($this->exactly(2))
->method('findByUuid')
->willReturnMap([
['us-1', $shareUser1],
['us-2', $shareUser2],
]);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('getUuid')
->willReturn('prompt-1-uuid');
$prompt->expects($this->once())
->method('getTitle')
->willReturn($title);
$prompt->expects($this->once())
->method('getContent')
->willReturn($content);
$this->askAnythingRepository->expects($this->once())
->method('createPrompt')
->with(
$user,
$target,
$title,
$content,
[$shareUser1, $shareUser2],
[],
)
->willReturn($prompt);
$expectedPromptDto = new AskAnythingPromptDto(
'prompt-1-uuid',
$title,
$content,
$target,
'uuid-of-the-user',
$shareUsers,
$shareGroups,
);
$actualPromptDto = $this->askAnythingPromptService->create(
$user,
$title,
$content,
$target,
$shareUsers,
$shareGroups
);
$this->assertEquals($expectedPromptDto, $actualPromptDto);
}
public function testRecreatePromptsForUserRelations(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('getId')
->willReturn(1);
$prompt->expects($this->once())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$prompt->expects($this->once())
->method('getTitle')
->willReturn('Test title');
$prompt->expects($this->once())
->method('getContent')
->willReturn('Test content');
$sharedPrompt = $this->createMock(UserAskAnythingPrompt::class);
$sharedUser = $this->createMock(User::class);
$sharedUser->expects($this->once())
->method('isStatusActive')
->willReturn(true);
$sharedUser->expects($this->once())
->method('getId')
->willReturn(1);
$sharedPrompt->expects($this->once())
->method('getUser')
->willReturn($sharedUser);
$sharedPrompt->expects($this->exactly(2))
->method('isRemoved')
->willReturn(false);
$sharedPrompt->expects($this->once())
->method('delete');
$this->askAnythingRepository->expects($this->once())
->method('findSharedUsersAndGroupsByPromptId')
->with(1)
->willReturn(new Collection([$sharedPrompt]));
$this->askAnythingRepository->expects($this->once())
->method('createPrompt');
$data = $this->invokePrivateMethod('recreatePromptsForUserRelations', $this->askAnythingPromptService, [$prompt]);
$this->assertEquals([[1], []], $data);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
56829
|
NULL
|
NULL
|
NULL
|
|
56830
|
NULL
|
0
|
2026-05-19T08:28:14.678477+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779179294678_m1.jpg...
|
PhpStorm
|
faVsco.js – AskAnythingPromptServiceTest.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20676-delete-report-re Project: faVsco.js, menu
JY-20676-delete-report-related-objects, 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
6
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Component\AskAnything;
use Illuminate\Database\Eloquent\Collection;
use Jiminny\Component\AskAnything\AskAnythingPromptService;
use Jiminny\Component\AskAnything\Dtos\AskAnythingPromptDto;
use Jiminny\Contracts\Repositories\GroupRepositoryInterface;
use Jiminny\Models\AskAnything\AskAnythingPrompt;
use Jiminny\Models\AskAnything\AskAnythingPromptTarget;
use Jiminny\Models\AskAnything\UserAskAnythingPrompt;
use Jiminny\Models\Group;
use Jiminny\Models\User;
use Jiminny\Repositories\AskAnythingRepository;
use Jiminny\Repositories\UserRepository;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
use Tests\Unit\Traits\TestPrivateMethod;
class AskAnythingPromptServiceTest extends TestCase
{
use TestPrivateMethod;
private AskAnythingPromptService $askAnythingPromptService;
private AskAnythingRepository&MockObject $askAnythingRepository;
private UserRepository&MockObject $userRepository;
private GroupRepositoryInterface&MockObject $groupRepository;
protected function setUp(): void
{
$this->askAnythingRepository = $this->createMock(AskAnythingRepository::class);
$this->userRepository = $this->createMock(UserRepository::class);
$this->groupRepository = $this->createMock(GroupRepositoryInterface::class);
$this->askAnythingPromptService = new AskAnythingPromptService(
$this->askAnythingRepository,
$this->userRepository,
$this->groupRepository
);
}
public function testGetAskAnythingPrompts(): void
{
$user = $this->createMock(User::class);
$user->expects($this->any())
->method('getId')
->willReturn(1);
$user->expects($this->any())
->method('getUuid')
->willReturn('1');
$defaultPrompt = $this->createMock(AskAnythingPrompt::class);
$defaultPrompt->expects($this->once())
->method('getOwner')
->willReturn(null);
$defaultPrompt->expects($this->once())
->method('getUuid')
->willReturn('default-uuid');
$defaultPrompt->expects($this->once())
->method('getTitle')
->willReturn('Sentiment');
$defaultPrompt->expects($this->once())
->method('getContent')
->willReturn('What was the overall sentiment of the customer during the call?');
$defaultPrompt->expects($this->once())
->method('getHasReports')
->willReturn(false);
$promptOwnedByUser = $this->createMock(AskAnythingPrompt::class);
$promptOwnedByUser->expects($this->exactly(2))
->method('getOwner')
->willReturn($user);
$promptOwnedByUser->expects($this->once())
->method('getUuid')
->willReturn('uuid-1st-prompt');
$promptOwnedByUser->expects($this->once())
->method('getTitle')
->willReturn('First users prompt');
$promptOwnedByUser->expects($this->once())
->method('getContent')
->willReturn('Test prompt');
$promptOwnedByUser->expects($this->once())
->method('getId')
->willReturn(99);
$promptOwnedByUser->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$promptOwnedByUser->expects($this->once())
->method('getHasReports')
->willReturn(true);
$defaultPromptOrderedByUser = $this->createMock(AskAnythingPrompt::class);
$defaultPromptOrderedByUser->expects($this->once())
->method('getOwner')
->willReturn(null);
$defaultPromptOrderedByUser->expects($this->once())
->method('getUuid')
->willReturn('default-uuid');
$defaultPromptOrderedByUser->expects($this->once())
->method('getTitle')
->willReturn('Sentiment');
$defaultPromptOrderedByUser->expects($this->once())
->method('getContent')
->willReturn('What was the overall sentiment of the customer during the call?');
$defaultPromptOrderedByUser->expects($this->once())
->method('getHasReports')
->willReturn(false);
$promptOwnedByUserAndSharedWithGroup = $this->createMock(AskAnythingPrompt::class);
$promptOwnedByUserAndSharedWithGroup->expects($this->exactly(2))
->method('getOwner')
->willReturn($user);
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getUuid')
->willReturn('uuid-2nd-prompt');
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getTitle')
->willReturn('Prompt shared with group');
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getContent')
->willReturn('Test prompt that is shared with group');
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getId')
->willReturn(109);
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getHasReports')
->willReturn(false);
$group = $this->createMock(Group::class);
$group->expects($this->once())
->method('getUuid')
->willReturn('uuid-of-the-group');
$sharedWithGroup = $this->createMock(UserAskAnythingPrompt::class);
$sharedWithGroup->expects($this->once())
->method('getUser')
->willReturn(null);
$sharedWithGroup->expects($this->once())
->method('getGroup')
->willReturn($group);
$this->askAnythingRepository->expects($this->exactly(2))
->method('findSharedUsersAndGroupsByPromptId')
->willReturnMap([
[99, new Collection([])],
[109, new Collection([$sharedWithGroup])],
]);
$prompts = [$defaultPrompt, $promptOwnedByUser, $defaultPromptOrderedByUser, $promptOwnedByUserAndSharedWithGroup];
$this->askAnythingRepository->expects($this->once())
->method('findPromptsByUserAndTarget')
->willReturn(new Collection($prompts));
$expectedDto1 = new AskAnythingPromptDto(
'default-uuid',
'Sentiment',
'What was the overall sentiment of the customer during the call?',
AskAnythingPromptTarget::call,
null,
null,
null,
false,
);
$expectedDto2 = new AskAnythingPromptDto(
'uuid-1st-prompt',
'First users prompt',
'Test prompt',
AskAnythingPromptTarget::call,
'1',
[],
[],
true,
);
$expectedDto3 = new AskAnythingPromptDto(
'default-uuid',
'Sentiment',
'What was the overall sentiment of the customer during the call?',
AskAnythingPromptTarget::call,
null,
null,
null,
false,
);
$expectedDto4 = new AskAnythingPromptDto(
'uuid-2nd-prompt',
'Prompt shared with group',
'Test prompt that is shared with group',
AskAnythingPromptTarget::call,
'1',
[],
['uuid-of-the-group'],
false,
);
$dtos = $this->askAnythingPromptService->get($user, AskAnythingPromptTarget::call);
$this->assertEquals([$expectedDto1, $expectedDto2, $expectedDto3, $expectedDto4], $dtos);
}
public function testEditAskAnythingPrompt(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(123);
$prompt->expects($this->never())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(123);
$user->expects($this->once())
->method('getUuid')
->willReturn('owner-uuid');
$title = 'new title';
$content = 'new content';
$shareUsers = ['us-1'];
$shareGroups = ['gr-1', 'gr-2'];
$shareUser = $this->createMock(User::class);
$this->userRepository->expects($this->once())
->method('findByUuid')
->with('us-1')
->willReturn($shareUser);
$shareGroup1 = $this->createMock(Group::class);
$shareGroup2 = $this->createMock(Group::class);
$this->groupRepository->expects($this->exactly(2))
->method('findByUuid')
->willReturnMap([
['gr-1', $shareGroup1],
['gr-2', $shareGroup2],
]);
$editPrompt = $this->createMock(AskAnythingPrompt::class);
$editPrompt->expects($this->once())
->method('getTitle')
->willReturn($title);
$editPrompt->expects($this->once())
->method('getContent')
->willReturn($content);
$editPrompt->expects($this->once())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$editPrompt->expects($this->once())
->method('getUuid')
->willReturn('uuid-1st-prompt');
$this->askAnythingRepository->expects($this->once())
->method('editPrompt')
->with($prompt, $title, $content, [$shareUser], [$shareGroup1, $shareGroup2])
->willReturn($editPrompt);
$expectedDto = new AskAnythingPromptDto(
'uuid-1st-prompt',
$title,
$content,
AskAnythingPromptTarget::call,
'owner-uuid',
$shareUsers,
$shareGroups
);
$editDto = $this->askAnythingPromptService->edit($prompt, $user, $title, $content, $shareUsers, $shareGroups);
$this->assertEquals($expectedDto, $editDto);
}
public function testHideDefaultAndCreateAskAnythingPrompt(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(true);
$prompt->expects($this->once())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getUuid')
->willReturn('new-owner-uuid');
$title = 'title';
$content = 'content';
$shareUsers = ['us-1'];
$shareGroups = [];
$shareUser = $this->createMock(User::class);
$this->userRepository->expects($this->once())
->method('findByUuid')
->with('us-1')
->willReturn($shareUser);
$this->groupRepository->expects($this->never())
->method('findByUuid');
$newPrompt = $this->createMock(AskAnythingPrompt::class);
$newPrompt->expects($this->once())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$newPrompt->expects($this->once())
->method('getUuid')
->willReturn('uuid-1st-prompt');
$newPrompt->expects($this->once())
->method('getTitle')
->willReturn($title);
$newPrompt->expects($this->once())
->method('getContent')
->willReturn($content);
$this->askAnythingRepository->expects($this->once())
->method('hidePromptForUser');
$this->askAnythingRepository->expects($this->once())
->method('createPrompt')
->willReturn($newPrompt);
$expectedDto = new AskAnythingPromptDto(
'uuid-1st-prompt',
$title,
$content,
AskAnythingPromptTarget::call,
'new-owner-uuid',
$shareUsers,
$shareGroups
);
$actualDto = $this->askAnythingPromptService->edit($prompt, $user, $title, $content, $shareUsers, $shareGroups);
$this->assertEquals($expectedDto, $actualDto);
}
public function testDeleteAskAnythingPrompt(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->any())
->method('getId')
->willReturn(1);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
// Use Mockery for the relationship mock (more flexible)
$relationMock = \Mockery::mock(\Illuminate\Database\Eloquent\Relations\HasMany::class);
$relationMock->shouldReceive('withTrashed')
->once()
->andReturnSelf();
$relationMock->shouldReceive('update')
->once()
->with(['ask_anything_prompt_id' => null, 'status' => false]);
$prompt->expects($this->once())
->method('automatedReports')
->willReturn($relationMock);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(1);
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(1, $user)
->willReturn($userPrompt);
$userPrompt->expects($this->once())
->method('delete');
$this->askAnythingRepository->expects($this->any())
->method('findSharedUsersAndGroupsByPromptId')
->with(1)
->willReturn(new Collection([]));
$this->askAnythingRepository->expects($this->once())
->method('deletePrompt');
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testDeleteAskAnythingPromptWithRelations(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->any())
->method('getId')
->willReturn(1);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$user = $this->createMock(User::class);
$user->expects($this->any())
->method('getId')
->willReturn(1);
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(1, $user)
->willReturn($userPrompt);
$userPrompt->expects($this->once())
->method('delete');
$this->askAnythingRepository->expects($this->exactly(3))
->method('findSharedUsersAndGroupsByPromptId')
->willReturnMap([
[1, new Collection([$userPrompt])],
[1, new Collection([])],
]);
$this->askAnythingRepository->expects($this->never())
->method('deletePrompt');
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testHideDefaultAskAnythingPrompt(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(true);
$user = $this->createMock(User::class);
$this->askAnythingRepository->expects($this->once())
->method('hidePromptForUser');
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testHideSharedWithUserAskAnythingPrompt(): void
{
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$prompt->expects($this->exactly(3))
->method('getId')
->willReturn(33);
$relationMock = \Mockery::mock(\Illuminate\Database\Eloquent\Relations\HasMany::class);
$relationMock->shouldReceive('withTrashed')
->once()
->andReturnSelf();
$relationMock->shouldReceive('update')
->once()
->with(['ask_anything_prompt_id' => null, 'status' => false]);
$prompt->expects($this->once())
->method('automatedReports')
->willReturn($relationMock);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(2);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(33, $user)
->willReturn($userPrompt);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUserGroup')
->with(33, $user)
->willReturn(null);
$userPrompt->expects($this->once())
->method('delete');
$this->askAnythingRepository->expects($this->once())
->method('findSharedUsersAndGroupsByPromptId')
->with(33)
->willReturn(new Collection([]));
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testHideSharedWithUserAndGroupAskAnythingPrompt(): void
{
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$prompt->expects($this->exactly(2))
->method('getId')
->willReturn(33);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(2);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(33, $user)
->willReturn($userPrompt);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUserGroup')
->with(33, $user)
->willReturn($userPrompt);
$userPrompt->expects($this->never())
->method('delete');
$this->askAnythingRepository->expects($this->once())
->method('hidePromptForUser')
->with($prompt, $user);
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testHideSharedWithGroupAskAnythingPrompt(): void
{
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$prompt->expects($this->exactly(2))
->method('getId')
->willReturn(33);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(2);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(33, $user)
->willReturn(null);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUserGroup')
->with(33, $user)
->willReturn($userPrompt);
$userPrompt->expects($this->never())
->method('delete');
$this->askAnythingRepository->expects($this->once())
->method('hidePromptForUser')
->with($prompt, $user);
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testDeleteWithNoSharesAndNotOwner(): void
{
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$prompt->expects($this->exactly(2))
->method('getId')
->willReturn(33);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(2);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(33, $user)
->willReturn(null);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUserGroup')
->with(33, $user)
->willReturn(null);
$userPrompt->expects($this->never())
->method('delete');
$this->askAnythingRepository->expects($this->never())
->method('hidePromptForUser');
$this->expectException(\InvalidArgumentException::class);
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testReorderAskAnythingPrompts(): void
{
$prompts = ['id1', 'id2', 'id3'];
$prompt1 = $this->createMock(AskAnythingPrompt::class);
$prompt2 = $this->createMock(AskAnythingPrompt::class);
$prompt3 = $this->createMock(AskAnythingPrompt::class);
$user = $this->createMock(User::class);
$this->askAnythingRepository->expects($this->exactly(3))
->method('getPromptByUuid')
->willReturnMap([
['id1', $prompt1],
['id2', $prompt2],
['id3', $prompt3],
]);
$this->askAnythingRepository->expects($this->exactly(3))
->method('orderPromptForUser')
->willReturnMap([
[[$prompt1, $user, 1]],
[[$prompt2, $user, 2]],
[[$prompt3, $user, 3]],
]);
$this->askAnythingPromptService->reorder($user, $prompts);
}
public function testCreateAskAnythingPromptWithTwoUsers(): void
{
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getUuid')
->willReturn('uuid-of-the-user');
$shareUser1 = $this->createMock(User::class);
$shareUser2 = $this->createMock(User::class);
$title = 'Test title';
$content = 'Test content';
$target = AskAnythingPromptTarget::call;
$shareUsers = ['us-1', 'us-2'];
$shareGroups = [];
$this->userRepository->expects($this->exactly(2))
->method('findByUuid')
->willReturnMap([
['us-1', $shareUser1],
['us-2', $shareUser2],
]);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('getUuid')
->willReturn('prompt-1-uuid');
$prompt->expects($this->once())
->method('getTitle')
->willReturn($title);
$prompt->expects($this->once())
->method('getContent')
->willReturn($content);
$this->askAnythingRepository->expects($this->once())
->method('createPrompt')
->with(
$user,
$target,
$title,
$content,
[$shareUser1, $shareUser2],
[],
)
->willReturn($prompt);
$expectedPromptDto = new AskAnythingPromptDto(
'prompt-1-uuid',
$title,
$content,
$target,
'uuid-of-the-user',
$shareUsers,
$shareGroups,
);
$actualPromptDto = $this->askAnythingPromptService->create(
$user,
$title,
$content,
$target,
$shareUsers,
$shareGroups
);
$this->assertEquals($expectedPromptDto, $actualPromptDto);
}
public function testRecreatePromptsForUserRelations(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('getId')
->willReturn(1);
$prompt->expects($this->once())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$prompt->expects($this->once())
->method('getTitle')
->willReturn('Test title');
$prompt->expects($this->once())
->method('getContent')
->willReturn('Test content');
$sharedPrompt = $this->createMock(UserAskAnythingPrompt::class);
$sharedUser = $this->createMock(User::class);
$sharedUser->expects($this->once())
->method('isStatusActive')
->willReturn(true);
$sharedUser->expects($this->once())
->method('getId')
->willReturn(1);
$sharedPrompt->expects($this->once())
->method('getUser')
->willReturn($sharedUser);
$sharedPrompt->expects($this->exactly(2))
->method('isRemoved')
->willReturn(false);
$sharedPrompt->expects($this->once())
->method('delete');
$this->askAnythingRepository->expects($this->once())
->method('findSharedUsersAndGroupsByPromptId')
->with(1)
->willReturn(new Collection([$sharedPrompt]));
$this->askAnythingRepository->expects($this->once())
->method('createPrompt');
$data = $this->invokePrivateMethod('recreatePromptsForUserRelations', $this->askAnythingPromptService, [$prompt]);
$this->assertEquals([[1], []], $data);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20676-delete-report-related-objects, menu","depth":5,"on_screen":true,"help_text":"Git Branch: JY-20676-delete-report-related-objects","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":"6","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.016666668,"height":0.02111111},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.02111111},"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.025555555},"on_screen":false,"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.0,"top":0.0,"width":0.014583333,"height":0.025555555},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Component\\AskAnything;\n\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Jiminny\\Component\\AskAnything\\AskAnythingPromptService;\nuse Jiminny\\Component\\AskAnything\\Dtos\\AskAnythingPromptDto;\nuse Jiminny\\Contracts\\Repositories\\GroupRepositoryInterface;\nuse Jiminny\\Models\\AskAnything\\AskAnythingPrompt;\nuse Jiminny\\Models\\AskAnything\\AskAnythingPromptTarget;\nuse Jiminny\\Models\\AskAnything\\UserAskAnythingPrompt;\nuse Jiminny\\Models\\Group;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AskAnythingRepository;\nuse Jiminny\\Repositories\\UserRepository;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Tests\\TestCase;\nuse Tests\\Unit\\Traits\\TestPrivateMethod;\n\nclass AskAnythingPromptServiceTest extends TestCase\n{\n use TestPrivateMethod;\n\n private AskAnythingPromptService $askAnythingPromptService;\n private AskAnythingRepository&MockObject $askAnythingRepository;\n private UserRepository&MockObject $userRepository;\n private GroupRepositoryInterface&MockObject $groupRepository;\n\n protected function setUp(): void\n {\n $this->askAnythingRepository = $this->createMock(AskAnythingRepository::class);\n $this->userRepository = $this->createMock(UserRepository::class);\n $this->groupRepository = $this->createMock(GroupRepositoryInterface::class);\n\n $this->askAnythingPromptService = new AskAnythingPromptService(\n $this->askAnythingRepository,\n $this->userRepository,\n $this->groupRepository\n );\n }\n\n public function testGetAskAnythingPrompts(): void\n {\n $user = $this->createMock(User::class);\n $user->expects($this->any())\n ->method('getId')\n ->willReturn(1);\n $user->expects($this->any())\n ->method('getUuid')\n ->willReturn('1');\n $defaultPrompt = $this->createMock(AskAnythingPrompt::class);\n $defaultPrompt->expects($this->once())\n ->method('getOwner')\n ->willReturn(null);\n $defaultPrompt->expects($this->once())\n ->method('getUuid')\n ->willReturn('default-uuid');\n $defaultPrompt->expects($this->once())\n ->method('getTitle')\n ->willReturn('Sentiment');\n $defaultPrompt->expects($this->once())\n ->method('getContent')\n ->willReturn('What was the overall sentiment of the customer during the call?');\n $defaultPrompt->expects($this->once())\n ->method('getHasReports')\n ->willReturn(false);\n $promptOwnedByUser = $this->createMock(AskAnythingPrompt::class);\n $promptOwnedByUser->expects($this->exactly(2))\n ->method('getOwner')\n ->willReturn($user);\n $promptOwnedByUser->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-1st-prompt');\n $promptOwnedByUser->expects($this->once())\n ->method('getTitle')\n ->willReturn('First users prompt');\n $promptOwnedByUser->expects($this->once())\n ->method('getContent')\n ->willReturn('Test prompt');\n $promptOwnedByUser->expects($this->once())\n ->method('getId')\n ->willReturn(99);\n $promptOwnedByUser->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $promptOwnedByUser->expects($this->once())\n ->method('getHasReports')\n ->willReturn(true);\n $defaultPromptOrderedByUser = $this->createMock(AskAnythingPrompt::class);\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getOwner')\n ->willReturn(null);\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getUuid')\n ->willReturn('default-uuid');\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getTitle')\n ->willReturn('Sentiment');\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getContent')\n ->willReturn('What was the overall sentiment of the customer during the call?');\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getHasReports')\n ->willReturn(false);\n $promptOwnedByUserAndSharedWithGroup = $this->createMock(AskAnythingPrompt::class);\n $promptOwnedByUserAndSharedWithGroup->expects($this->exactly(2))\n ->method('getOwner')\n ->willReturn($user);\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-2nd-prompt');\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getTitle')\n ->willReturn('Prompt shared with group');\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getContent')\n ->willReturn('Test prompt that is shared with group');\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getId')\n ->willReturn(109);\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getHasReports')\n ->willReturn(false);\n\n $group = $this->createMock(Group::class);\n $group->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-of-the-group');\n $sharedWithGroup = $this->createMock(UserAskAnythingPrompt::class);\n $sharedWithGroup->expects($this->once())\n ->method('getUser')\n ->willReturn(null);\n $sharedWithGroup->expects($this->once())\n ->method('getGroup')\n ->willReturn($group);\n\n $this->askAnythingRepository->expects($this->exactly(2))\n ->method('findSharedUsersAndGroupsByPromptId')\n ->willReturnMap([\n [99, new Collection([])],\n [109, new Collection([$sharedWithGroup])],\n ]);\n\n $prompts = [$defaultPrompt, $promptOwnedByUser, $defaultPromptOrderedByUser, $promptOwnedByUserAndSharedWithGroup];\n $this->askAnythingRepository->expects($this->once())\n ->method('findPromptsByUserAndTarget')\n ->willReturn(new Collection($prompts));\n\n $expectedDto1 = new AskAnythingPromptDto(\n 'default-uuid',\n 'Sentiment',\n 'What was the overall sentiment of the customer during the call?',\n AskAnythingPromptTarget::call,\n null,\n null,\n null,\n false,\n );\n $expectedDto2 = new AskAnythingPromptDto(\n 'uuid-1st-prompt',\n 'First users prompt',\n 'Test prompt',\n AskAnythingPromptTarget::call,\n '1',\n [],\n [],\n true,\n );\n $expectedDto3 = new AskAnythingPromptDto(\n 'default-uuid',\n 'Sentiment',\n 'What was the overall sentiment of the customer during the call?',\n AskAnythingPromptTarget::call,\n null,\n null,\n null,\n false,\n );\n $expectedDto4 = new AskAnythingPromptDto(\n 'uuid-2nd-prompt',\n 'Prompt shared with group',\n 'Test prompt that is shared with group',\n AskAnythingPromptTarget::call,\n '1',\n [],\n ['uuid-of-the-group'],\n false,\n );\n $dtos = $this->askAnythingPromptService->get($user, AskAnythingPromptTarget::call);\n\n $this->assertEquals([$expectedDto1, $expectedDto2, $expectedDto3, $expectedDto4], $dtos);\n }\n\n public function testEditAskAnythingPrompt(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(123);\n $prompt->expects($this->never())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(123);\n $user->expects($this->once())\n ->method('getUuid')\n ->willReturn('owner-uuid');\n\n $title = 'new title';\n $content = 'new content';\n $shareUsers = ['us-1'];\n $shareGroups = ['gr-1', 'gr-2'];\n\n $shareUser = $this->createMock(User::class);\n $this->userRepository->expects($this->once())\n ->method('findByUuid')\n ->with('us-1')\n ->willReturn($shareUser);\n $shareGroup1 = $this->createMock(Group::class);\n $shareGroup2 = $this->createMock(Group::class);\n $this->groupRepository->expects($this->exactly(2))\n ->method('findByUuid')\n ->willReturnMap([\n ['gr-1', $shareGroup1],\n ['gr-2', $shareGroup2],\n ]);\n\n $editPrompt = $this->createMock(AskAnythingPrompt::class);\n $editPrompt->expects($this->once())\n ->method('getTitle')\n ->willReturn($title);\n $editPrompt->expects($this->once())\n ->method('getContent')\n ->willReturn($content);\n $editPrompt->expects($this->once())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $editPrompt->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-1st-prompt');\n $this->askAnythingRepository->expects($this->once())\n ->method('editPrompt')\n ->with($prompt, $title, $content, [$shareUser], [$shareGroup1, $shareGroup2])\n ->willReturn($editPrompt);\n\n $expectedDto = new AskAnythingPromptDto(\n 'uuid-1st-prompt',\n $title,\n $content,\n AskAnythingPromptTarget::call,\n 'owner-uuid',\n $shareUsers,\n $shareGroups\n );\n $editDto = $this->askAnythingPromptService->edit($prompt, $user, $title, $content, $shareUsers, $shareGroups);\n\n $this->assertEquals($expectedDto, $editDto);\n }\n\n public function testHideDefaultAndCreateAskAnythingPrompt(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(true);\n $prompt->expects($this->once())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getUuid')\n ->willReturn('new-owner-uuid');\n $title = 'title';\n $content = 'content';\n $shareUsers = ['us-1'];\n $shareGroups = [];\n $shareUser = $this->createMock(User::class);\n $this->userRepository->expects($this->once())\n ->method('findByUuid')\n ->with('us-1')\n ->willReturn($shareUser);\n $this->groupRepository->expects($this->never())\n ->method('findByUuid');\n\n $newPrompt = $this->createMock(AskAnythingPrompt::class);\n $newPrompt->expects($this->once())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $newPrompt->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-1st-prompt');\n $newPrompt->expects($this->once())\n ->method('getTitle')\n ->willReturn($title);\n $newPrompt->expects($this->once())\n ->method('getContent')\n ->willReturn($content);\n\n $this->askAnythingRepository->expects($this->once())\n ->method('hidePromptForUser');\n $this->askAnythingRepository->expects($this->once())\n ->method('createPrompt')\n ->willReturn($newPrompt);\n\n $expectedDto = new AskAnythingPromptDto(\n 'uuid-1st-prompt',\n $title,\n $content,\n AskAnythingPromptTarget::call,\n 'new-owner-uuid',\n $shareUsers,\n $shareGroups\n );\n\n $actualDto = $this->askAnythingPromptService->edit($prompt, $user, $title, $content, $shareUsers, $shareGroups);\n\n $this->assertEquals($expectedDto, $actualDto);\n }\n\n public function testDeleteAskAnythingPrompt(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->any())\n ->method('getId')\n ->willReturn(1);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n\n // Use Mockery for the relationship mock (more flexible)\n $relationMock = \\Mockery::mock(\\Illuminate\\Database\\Eloquent\\Relations\\HasMany::class);\n $relationMock->shouldReceive('withTrashed')\n ->once()\n ->andReturnSelf();\n $relationMock->shouldReceive('update')\n ->once()\n ->with(['ask_anything_prompt_id' => null, 'status' => false]);\n\n $prompt->expects($this->once())\n ->method('automatedReports')\n ->willReturn($relationMock);\n\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(1);\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(1, $user)\n ->willReturn($userPrompt);\n $userPrompt->expects($this->once())\n ->method('delete');\n $this->askAnythingRepository->expects($this->any())\n ->method('findSharedUsersAndGroupsByPromptId')\n ->with(1)\n ->willReturn(new Collection([]));\n $this->askAnythingRepository->expects($this->once())\n ->method('deletePrompt');\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testDeleteAskAnythingPromptWithRelations(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->any())\n ->method('getId')\n ->willReturn(1);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $user = $this->createMock(User::class);\n $user->expects($this->any())\n ->method('getId')\n ->willReturn(1);\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(1, $user)\n ->willReturn($userPrompt);\n $userPrompt->expects($this->once())\n ->method('delete');\n $this->askAnythingRepository->expects($this->exactly(3))\n ->method('findSharedUsersAndGroupsByPromptId')\n ->willReturnMap([\n [1, new Collection([$userPrompt])],\n [1, new Collection([])],\n ]);\n $this->askAnythingRepository->expects($this->never())\n ->method('deletePrompt');\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testHideDefaultAskAnythingPrompt(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(true);\n $user = $this->createMock(User::class);\n $this->askAnythingRepository->expects($this->once())\n ->method('hidePromptForUser');\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testHideSharedWithUserAskAnythingPrompt(): void\n {\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $prompt->expects($this->exactly(3))\n ->method('getId')\n ->willReturn(33);\n\n $relationMock = \\Mockery::mock(\\Illuminate\\Database\\Eloquent\\Relations\\HasMany::class);\n $relationMock->shouldReceive('withTrashed')\n ->once()\n ->andReturnSelf();\n $relationMock->shouldReceive('update')\n ->once()\n ->with(['ask_anything_prompt_id' => null, 'status' => false]);\n $prompt->expects($this->once())\n ->method('automatedReports')\n ->willReturn($relationMock);\n\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(2);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(33, $user)\n ->willReturn($userPrompt);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUserGroup')\n ->with(33, $user)\n ->willReturn(null);\n $userPrompt->expects($this->once())\n ->method('delete');\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedUsersAndGroupsByPromptId')\n ->with(33)\n ->willReturn(new Collection([]));\n\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testHideSharedWithUserAndGroupAskAnythingPrompt(): void\n {\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $prompt->expects($this->exactly(2))\n ->method('getId')\n ->willReturn(33);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(2);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(33, $user)\n ->willReturn($userPrompt);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUserGroup')\n ->with(33, $user)\n ->willReturn($userPrompt);\n $userPrompt->expects($this->never())\n ->method('delete');\n $this->askAnythingRepository->expects($this->once())\n ->method('hidePromptForUser')\n ->with($prompt, $user);\n\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testHideSharedWithGroupAskAnythingPrompt(): void\n {\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $prompt->expects($this->exactly(2))\n ->method('getId')\n ->willReturn(33);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(2);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(33, $user)\n ->willReturn(null);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUserGroup')\n ->with(33, $user)\n ->willReturn($userPrompt);\n $userPrompt->expects($this->never())\n ->method('delete');\n $this->askAnythingRepository->expects($this->once())\n ->method('hidePromptForUser')\n ->with($prompt, $user);\n\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testDeleteWithNoSharesAndNotOwner(): void\n {\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $prompt->expects($this->exactly(2))\n ->method('getId')\n ->willReturn(33);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(2);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(33, $user)\n ->willReturn(null);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUserGroup')\n ->with(33, $user)\n ->willReturn(null);\n $userPrompt->expects($this->never())\n ->method('delete');\n $this->askAnythingRepository->expects($this->never())\n ->method('hidePromptForUser');\n\n $this->expectException(\\InvalidArgumentException::class);\n\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testReorderAskAnythingPrompts(): void\n {\n $prompts = ['id1', 'id2', 'id3'];\n $prompt1 = $this->createMock(AskAnythingPrompt::class);\n $prompt2 = $this->createMock(AskAnythingPrompt::class);\n $prompt3 = $this->createMock(AskAnythingPrompt::class);\n $user = $this->createMock(User::class);\n $this->askAnythingRepository->expects($this->exactly(3))\n ->method('getPromptByUuid')\n ->willReturnMap([\n ['id1', $prompt1],\n ['id2', $prompt2],\n ['id3', $prompt3],\n ]);\n $this->askAnythingRepository->expects($this->exactly(3))\n ->method('orderPromptForUser')\n ->willReturnMap([\n [[$prompt1, $user, 1]],\n [[$prompt2, $user, 2]],\n [[$prompt3, $user, 3]],\n ]);\n $this->askAnythingPromptService->reorder($user, $prompts);\n }\n\n public function testCreateAskAnythingPromptWithTwoUsers(): void\n {\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-of-the-user');\n $shareUser1 = $this->createMock(User::class);\n $shareUser2 = $this->createMock(User::class);\n $title = 'Test title';\n $content = 'Test content';\n $target = AskAnythingPromptTarget::call;\n $shareUsers = ['us-1', 'us-2'];\n $shareGroups = [];\n\n $this->userRepository->expects($this->exactly(2))\n ->method('findByUuid')\n ->willReturnMap([\n ['us-1', $shareUser1],\n ['us-2', $shareUser2],\n ]);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('getUuid')\n ->willReturn('prompt-1-uuid');\n $prompt->expects($this->once())\n ->method('getTitle')\n ->willReturn($title);\n $prompt->expects($this->once())\n ->method('getContent')\n ->willReturn($content);\n $this->askAnythingRepository->expects($this->once())\n ->method('createPrompt')\n ->with(\n $user,\n $target,\n $title,\n $content,\n [$shareUser1, $shareUser2],\n [],\n )\n ->willReturn($prompt);\n\n $expectedPromptDto = new AskAnythingPromptDto(\n 'prompt-1-uuid',\n $title,\n $content,\n $target,\n 'uuid-of-the-user',\n $shareUsers,\n $shareGroups,\n );\n\n $actualPromptDto = $this->askAnythingPromptService->create(\n $user,\n $title,\n $content,\n $target,\n $shareUsers,\n $shareGroups\n );\n\n $this->assertEquals($expectedPromptDto, $actualPromptDto);\n }\n\n public function testRecreatePromptsForUserRelations(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('getId')\n ->willReturn(1);\n $prompt->expects($this->once())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $prompt->expects($this->once())\n ->method('getTitle')\n ->willReturn('Test title');\n $prompt->expects($this->once())\n ->method('getContent')\n ->willReturn('Test content');\n\n $sharedPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $sharedUser = $this->createMock(User::class);\n $sharedUser->expects($this->once())\n ->method('isStatusActive')\n ->willReturn(true);\n $sharedUser->expects($this->once())\n ->method('getId')\n ->willReturn(1);\n\n $sharedPrompt->expects($this->once())\n ->method('getUser')\n ->willReturn($sharedUser);\n $sharedPrompt->expects($this->exactly(2))\n ->method('isRemoved')\n ->willReturn(false);\n $sharedPrompt->expects($this->once())\n ->method('delete');\n\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedUsersAndGroupsByPromptId')\n ->with(1)\n ->willReturn(new Collection([$sharedPrompt]));\n\n $this->askAnythingRepository->expects($this->once())\n ->method('createPrompt');\n\n $data = $this->invokePrivateMethod('recreatePromptsForUserRelations', $this->askAnythingPromptService, [$prompt]);\n\n $this->assertEquals([[1], []], $data);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Component\\AskAnything;\n\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Jiminny\\Component\\AskAnything\\AskAnythingPromptService;\nuse Jiminny\\Component\\AskAnything\\Dtos\\AskAnythingPromptDto;\nuse Jiminny\\Contracts\\Repositories\\GroupRepositoryInterface;\nuse Jiminny\\Models\\AskAnything\\AskAnythingPrompt;\nuse Jiminny\\Models\\AskAnything\\AskAnythingPromptTarget;\nuse Jiminny\\Models\\AskAnything\\UserAskAnythingPrompt;\nuse Jiminny\\Models\\Group;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AskAnythingRepository;\nuse Jiminny\\Repositories\\UserRepository;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Tests\\TestCase;\nuse Tests\\Unit\\Traits\\TestPrivateMethod;\n\nclass AskAnythingPromptServiceTest extends TestCase\n{\n use TestPrivateMethod;\n\n private AskAnythingPromptService $askAnythingPromptService;\n private AskAnythingRepository&MockObject $askAnythingRepository;\n private UserRepository&MockObject $userRepository;\n private GroupRepositoryInterface&MockObject $groupRepository;\n\n protected function setUp(): void\n {\n $this->askAnythingRepository = $this->createMock(AskAnythingRepository::class);\n $this->userRepository = $this->createMock(UserRepository::class);\n $this->groupRepository = $this->createMock(GroupRepositoryInterface::class);\n\n $this->askAnythingPromptService = new AskAnythingPromptService(\n $this->askAnythingRepository,\n $this->userRepository,\n $this->groupRepository\n );\n }\n\n public function testGetAskAnythingPrompts(): void\n {\n $user = $this->createMock(User::class);\n $user->expects($this->any())\n ->method('getId')\n ->willReturn(1);\n $user->expects($this->any())\n ->method('getUuid')\n ->willReturn('1');\n $defaultPrompt = $this->createMock(AskAnythingPrompt::class);\n $defaultPrompt->expects($this->once())\n ->method('getOwner')\n ->willReturn(null);\n $defaultPrompt->expects($this->once())\n ->method('getUuid')\n ->willReturn('default-uuid');\n $defaultPrompt->expects($this->once())\n ->method('getTitle')\n ->willReturn('Sentiment');\n $defaultPrompt->expects($this->once())\n ->method('getContent')\n ->willReturn('What was the overall sentiment of the customer during the call?');\n $defaultPrompt->expects($this->once())\n ->method('getHasReports')\n ->willReturn(false);\n $promptOwnedByUser = $this->createMock(AskAnythingPrompt::class);\n $promptOwnedByUser->expects($this->exactly(2))\n ->method('getOwner')\n ->willReturn($user);\n $promptOwnedByUser->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-1st-prompt');\n $promptOwnedByUser->expects($this->once())\n ->method('getTitle')\n ->willReturn('First users prompt');\n $promptOwnedByUser->expects($this->once())\n ->method('getContent')\n ->willReturn('Test prompt');\n $promptOwnedByUser->expects($this->once())\n ->method('getId')\n ->willReturn(99);\n $promptOwnedByUser->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $promptOwnedByUser->expects($this->once())\n ->method('getHasReports')\n ->willReturn(true);\n $defaultPromptOrderedByUser = $this->createMock(AskAnythingPrompt::class);\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getOwner')\n ->willReturn(null);\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getUuid')\n ->willReturn('default-uuid');\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getTitle')\n ->willReturn('Sentiment');\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getContent')\n ->willReturn('What was the overall sentiment of the customer during the call?');\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getHasReports')\n ->willReturn(false);\n $promptOwnedByUserAndSharedWithGroup = $this->createMock(AskAnythingPrompt::class);\n $promptOwnedByUserAndSharedWithGroup->expects($this->exactly(2))\n ->method('getOwner')\n ->willReturn($user);\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-2nd-prompt');\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getTitle')\n ->willReturn('Prompt shared with group');\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getContent')\n ->willReturn('Test prompt that is shared with group');\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getId')\n ->willReturn(109);\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getHasReports')\n ->willReturn(false);\n\n $group = $this->createMock(Group::class);\n $group->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-of-the-group');\n $sharedWithGroup = $this->createMock(UserAskAnythingPrompt::class);\n $sharedWithGroup->expects($this->once())\n ->method('getUser')\n ->willReturn(null);\n $sharedWithGroup->expects($this->once())\n ->method('getGroup')\n ->willReturn($group);\n\n $this->askAnythingRepository->expects($this->exactly(2))\n ->method('findSharedUsersAndGroupsByPromptId')\n ->willReturnMap([\n [99, new Collection([])],\n [109, new Collection([$sharedWithGroup])],\n ]);\n\n $prompts = [$defaultPrompt, $promptOwnedByUser, $defaultPromptOrderedByUser, $promptOwnedByUserAndSharedWithGroup];\n $this->askAnythingRepository->expects($this->once())\n ->method('findPromptsByUserAndTarget')\n ->willReturn(new Collection($prompts));\n\n $expectedDto1 = new AskAnythingPromptDto(\n 'default-uuid',\n 'Sentiment',\n 'What was the overall sentiment of the customer during the call?',\n AskAnythingPromptTarget::call,\n null,\n null,\n null,\n false,\n );\n $expectedDto2 = new AskAnythingPromptDto(\n 'uuid-1st-prompt',\n 'First users prompt',\n 'Test prompt',\n AskAnythingPromptTarget::call,\n '1',\n [],\n [],\n true,\n );\n $expectedDto3 = new AskAnythingPromptDto(\n 'default-uuid',\n 'Sentiment',\n 'What was the overall sentiment of the customer during the call?',\n AskAnythingPromptTarget::call,\n null,\n null,\n null,\n false,\n );\n $expectedDto4 = new AskAnythingPromptDto(\n 'uuid-2nd-prompt',\n 'Prompt shared with group',\n 'Test prompt that is shared with group',\n AskAnythingPromptTarget::call,\n '1',\n [],\n ['uuid-of-the-group'],\n false,\n );\n $dtos = $this->askAnythingPromptService->get($user, AskAnythingPromptTarget::call);\n\n $this->assertEquals([$expectedDto1, $expectedDto2, $expectedDto3, $expectedDto4], $dtos);\n }\n\n public function testEditAskAnythingPrompt(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(123);\n $prompt->expects($this->never())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(123);\n $user->expects($this->once())\n ->method('getUuid')\n ->willReturn('owner-uuid');\n\n $title = 'new title';\n $content = 'new content';\n $shareUsers = ['us-1'];\n $shareGroups = ['gr-1', 'gr-2'];\n\n $shareUser = $this->createMock(User::class);\n $this->userRepository->expects($this->once())\n ->method('findByUuid')\n ->with('us-1')\n ->willReturn($shareUser);\n $shareGroup1 = $this->createMock(Group::class);\n $shareGroup2 = $this->createMock(Group::class);\n $this->groupRepository->expects($this->exactly(2))\n ->method('findByUuid')\n ->willReturnMap([\n ['gr-1', $shareGroup1],\n ['gr-2', $shareGroup2],\n ]);\n\n $editPrompt = $this->createMock(AskAnythingPrompt::class);\n $editPrompt->expects($this->once())\n ->method('getTitle')\n ->willReturn($title);\n $editPrompt->expects($this->once())\n ->method('getContent')\n ->willReturn($content);\n $editPrompt->expects($this->once())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $editPrompt->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-1st-prompt');\n $this->askAnythingRepository->expects($this->once())\n ->method('editPrompt')\n ->with($prompt, $title, $content, [$shareUser], [$shareGroup1, $shareGroup2])\n ->willReturn($editPrompt);\n\n $expectedDto = new AskAnythingPromptDto(\n 'uuid-1st-prompt',\n $title,\n $content,\n AskAnythingPromptTarget::call,\n 'owner-uuid',\n $shareUsers,\n $shareGroups\n );\n $editDto = $this->askAnythingPromptService->edit($prompt, $user, $title, $content, $shareUsers, $shareGroups);\n\n $this->assertEquals($expectedDto, $editDto);\n }\n\n public function testHideDefaultAndCreateAskAnythingPrompt(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(true);\n $prompt->expects($this->once())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getUuid')\n ->willReturn('new-owner-uuid');\n $title = 'title';\n $content = 'content';\n $shareUsers = ['us-1'];\n $shareGroups = [];\n $shareUser = $this->createMock(User::class);\n $this->userRepository->expects($this->once())\n ->method('findByUuid')\n ->with('us-1')\n ->willReturn($shareUser);\n $this->groupRepository->expects($this->never())\n ->method('findByUuid');\n\n $newPrompt = $this->createMock(AskAnythingPrompt::class);\n $newPrompt->expects($this->once())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $newPrompt->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-1st-prompt');\n $newPrompt->expects($this->once())\n ->method('getTitle')\n ->willReturn($title);\n $newPrompt->expects($this->once())\n ->method('getContent')\n ->willReturn($content);\n\n $this->askAnythingRepository->expects($this->once())\n ->method('hidePromptForUser');\n $this->askAnythingRepository->expects($this->once())\n ->method('createPrompt')\n ->willReturn($newPrompt);\n\n $expectedDto = new AskAnythingPromptDto(\n 'uuid-1st-prompt',\n $title,\n $content,\n AskAnythingPromptTarget::call,\n 'new-owner-uuid',\n $shareUsers,\n $shareGroups\n );\n\n $actualDto = $this->askAnythingPromptService->edit($prompt, $user, $title, $content, $shareUsers, $shareGroups);\n\n $this->assertEquals($expectedDto, $actualDto);\n }\n\n public function testDeleteAskAnythingPrompt(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->any())\n ->method('getId')\n ->willReturn(1);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n\n // Use Mockery for the relationship mock (more flexible)\n $relationMock = \\Mockery::mock(\\Illuminate\\Database\\Eloquent\\Relations\\HasMany::class);\n $relationMock->shouldReceive('withTrashed')\n ->once()\n ->andReturnSelf();\n $relationMock->shouldReceive('update')\n ->once()\n ->with(['ask_anything_prompt_id' => null, 'status' => false]);\n\n $prompt->expects($this->once())\n ->method('automatedReports')\n ->willReturn($relationMock);\n\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(1);\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(1, $user)\n ->willReturn($userPrompt);\n $userPrompt->expects($this->once())\n ->method('delete');\n $this->askAnythingRepository->expects($this->any())\n ->method('findSharedUsersAndGroupsByPromptId')\n ->with(1)\n ->willReturn(new Collection([]));\n $this->askAnythingRepository->expects($this->once())\n ->method('deletePrompt');\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testDeleteAskAnythingPromptWithRelations(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->any())\n ->method('getId')\n ->willReturn(1);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $user = $this->createMock(User::class);\n $user->expects($this->any())\n ->method('getId')\n ->willReturn(1);\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(1, $user)\n ->willReturn($userPrompt);\n $userPrompt->expects($this->once())\n ->method('delete');\n $this->askAnythingRepository->expects($this->exactly(3))\n ->method('findSharedUsersAndGroupsByPromptId')\n ->willReturnMap([\n [1, new Collection([$userPrompt])],\n [1, new Collection([])],\n ]);\n $this->askAnythingRepository->expects($this->never())\n ->method('deletePrompt');\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testHideDefaultAskAnythingPrompt(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(true);\n $user = $this->createMock(User::class);\n $this->askAnythingRepository->expects($this->once())\n ->method('hidePromptForUser');\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testHideSharedWithUserAskAnythingPrompt(): void\n {\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $prompt->expects($this->exactly(3))\n ->method('getId')\n ->willReturn(33);\n\n $relationMock = \\Mockery::mock(\\Illuminate\\Database\\Eloquent\\Relations\\HasMany::class);\n $relationMock->shouldReceive('withTrashed')\n ->once()\n ->andReturnSelf();\n $relationMock->shouldReceive('update')\n ->once()\n ->with(['ask_anything_prompt_id' => null, 'status' => false]);\n $prompt->expects($this->once())\n ->method('automatedReports')\n ->willReturn($relationMock);\n\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(2);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(33, $user)\n ->willReturn($userPrompt);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUserGroup')\n ->with(33, $user)\n ->willReturn(null);\n $userPrompt->expects($this->once())\n ->method('delete');\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedUsersAndGroupsByPromptId')\n ->with(33)\n ->willReturn(new Collection([]));\n\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testHideSharedWithUserAndGroupAskAnythingPrompt(): void\n {\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $prompt->expects($this->exactly(2))\n ->method('getId')\n ->willReturn(33);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(2);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(33, $user)\n ->willReturn($userPrompt);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUserGroup')\n ->with(33, $user)\n ->willReturn($userPrompt);\n $userPrompt->expects($this->never())\n ->method('delete');\n $this->askAnythingRepository->expects($this->once())\n ->method('hidePromptForUser')\n ->with($prompt, $user);\n\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testHideSharedWithGroupAskAnythingPrompt(): void\n {\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $prompt->expects($this->exactly(2))\n ->method('getId')\n ->willReturn(33);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(2);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(33, $user)\n ->willReturn(null);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUserGroup')\n ->with(33, $user)\n ->willReturn($userPrompt);\n $userPrompt->expects($this->never())\n ->method('delete');\n $this->askAnythingRepository->expects($this->once())\n ->method('hidePromptForUser')\n ->with($prompt, $user);\n\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testDeleteWithNoSharesAndNotOwner(): void\n {\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $prompt->expects($this->exactly(2))\n ->method('getId')\n ->willReturn(33);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(2);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(33, $user)\n ->willReturn(null);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUserGroup')\n ->with(33, $user)\n ->willReturn(null);\n $userPrompt->expects($this->never())\n ->method('delete');\n $this->askAnythingRepository->expects($this->never())\n ->method('hidePromptForUser');\n\n $this->expectException(\\InvalidArgumentException::class);\n\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testReorderAskAnythingPrompts(): void\n {\n $prompts = ['id1', 'id2', 'id3'];\n $prompt1 = $this->createMock(AskAnythingPrompt::class);\n $prompt2 = $this->createMock(AskAnythingPrompt::class);\n $prompt3 = $this->createMock(AskAnythingPrompt::class);\n $user = $this->createMock(User::class);\n $this->askAnythingRepository->expects($this->exactly(3))\n ->method('getPromptByUuid')\n ->willReturnMap([\n ['id1', $prompt1],\n ['id2', $prompt2],\n ['id3', $prompt3],\n ]);\n $this->askAnythingRepository->expects($this->exactly(3))\n ->method('orderPromptForUser')\n ->willReturnMap([\n [[$prompt1, $user, 1]],\n [[$prompt2, $user, 2]],\n [[$prompt3, $user, 3]],\n ]);\n $this->askAnythingPromptService->reorder($user, $prompts);\n }\n\n public function testCreateAskAnythingPromptWithTwoUsers(): void\n {\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-of-the-user');\n $shareUser1 = $this->createMock(User::class);\n $shareUser2 = $this->createMock(User::class);\n $title = 'Test title';\n $content = 'Test content';\n $target = AskAnythingPromptTarget::call;\n $shareUsers = ['us-1', 'us-2'];\n $shareGroups = [];\n\n $this->userRepository->expects($this->exactly(2))\n ->method('findByUuid')\n ->willReturnMap([\n ['us-1', $shareUser1],\n ['us-2', $shareUser2],\n ]);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('getUuid')\n ->willReturn('prompt-1-uuid');\n $prompt->expects($this->once())\n ->method('getTitle')\n ->willReturn($title);\n $prompt->expects($this->once())\n ->method('getContent')\n ->willReturn($content);\n $this->askAnythingRepository->expects($this->once())\n ->method('createPrompt')\n ->with(\n $user,\n $target,\n $title,\n $content,\n [$shareUser1, $shareUser2],\n [],\n )\n ->willReturn($prompt);\n\n $expectedPromptDto = new AskAnythingPromptDto(\n 'prompt-1-uuid',\n $title,\n $content,\n $target,\n 'uuid-of-the-user',\n $shareUsers,\n $shareGroups,\n );\n\n $actualPromptDto = $this->askAnythingPromptService->create(\n $user,\n $title,\n $content,\n $target,\n $shareUsers,\n $shareGroups\n );\n\n $this->assertEquals($expectedPromptDto, $actualPromptDto);\n }\n\n public function testRecreatePromptsForUserRelations(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('getId')\n ->willReturn(1);\n $prompt->expects($this->once())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $prompt->expects($this->once())\n ->method('getTitle')\n ->willReturn('Test title');\n $prompt->expects($this->once())\n ->method('getContent')\n ->willReturn('Test content');\n\n $sharedPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $sharedUser = $this->createMock(User::class);\n $sharedUser->expects($this->once())\n ->method('isStatusActive')\n ->willReturn(true);\n $sharedUser->expects($this->once())\n ->method('getId')\n ->willReturn(1);\n\n $sharedPrompt->expects($this->once())\n ->method('getUser')\n ->willReturn($sharedUser);\n $sharedPrompt->expects($this->exactly(2))\n ->method('isRemoved')\n ->willReturn(false);\n $sharedPrompt->expects($this->once())\n ->method('delete');\n\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedUsersAndGroupsByPromptId')\n ->with(1)\n ->willReturn(new Collection([$sharedPrompt]));\n\n $this->askAnythingRepository->expects($this->once())\n ->method('createPrompt');\n\n $data = $this->invokePrivateMethod('recreatePromptsForUserRelations', $this->askAnythingPromptService, [$prompt]);\n\n $this->assertEquals([[1], []], $data);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
1140439531069478179
|
-8755961741003010129
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20676-delete-report-re Project: faVsco.js, menu
JY-20676-delete-report-related-objects, 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
6
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Component\AskAnything;
use Illuminate\Database\Eloquent\Collection;
use Jiminny\Component\AskAnything\AskAnythingPromptService;
use Jiminny\Component\AskAnything\Dtos\AskAnythingPromptDto;
use Jiminny\Contracts\Repositories\GroupRepositoryInterface;
use Jiminny\Models\AskAnything\AskAnythingPrompt;
use Jiminny\Models\AskAnything\AskAnythingPromptTarget;
use Jiminny\Models\AskAnything\UserAskAnythingPrompt;
use Jiminny\Models\Group;
use Jiminny\Models\User;
use Jiminny\Repositories\AskAnythingRepository;
use Jiminny\Repositories\UserRepository;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
use Tests\Unit\Traits\TestPrivateMethod;
class AskAnythingPromptServiceTest extends TestCase
{
use TestPrivateMethod;
private AskAnythingPromptService $askAnythingPromptService;
private AskAnythingRepository&MockObject $askAnythingRepository;
private UserRepository&MockObject $userRepository;
private GroupRepositoryInterface&MockObject $groupRepository;
protected function setUp(): void
{
$this->askAnythingRepository = $this->createMock(AskAnythingRepository::class);
$this->userRepository = $this->createMock(UserRepository::class);
$this->groupRepository = $this->createMock(GroupRepositoryInterface::class);
$this->askAnythingPromptService = new AskAnythingPromptService(
$this->askAnythingRepository,
$this->userRepository,
$this->groupRepository
);
}
public function testGetAskAnythingPrompts(): void
{
$user = $this->createMock(User::class);
$user->expects($this->any())
->method('getId')
->willReturn(1);
$user->expects($this->any())
->method('getUuid')
->willReturn('1');
$defaultPrompt = $this->createMock(AskAnythingPrompt::class);
$defaultPrompt->expects($this->once())
->method('getOwner')
->willReturn(null);
$defaultPrompt->expects($this->once())
->method('getUuid')
->willReturn('default-uuid');
$defaultPrompt->expects($this->once())
->method('getTitle')
->willReturn('Sentiment');
$defaultPrompt->expects($this->once())
->method('getContent')
->willReturn('What was the overall sentiment of the customer during the call?');
$defaultPrompt->expects($this->once())
->method('getHasReports')
->willReturn(false);
$promptOwnedByUser = $this->createMock(AskAnythingPrompt::class);
$promptOwnedByUser->expects($this->exactly(2))
->method('getOwner')
->willReturn($user);
$promptOwnedByUser->expects($this->once())
->method('getUuid')
->willReturn('uuid-1st-prompt');
$promptOwnedByUser->expects($this->once())
->method('getTitle')
->willReturn('First users prompt');
$promptOwnedByUser->expects($this->once())
->method('getContent')
->willReturn('Test prompt');
$promptOwnedByUser->expects($this->once())
->method('getId')
->willReturn(99);
$promptOwnedByUser->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$promptOwnedByUser->expects($this->once())
->method('getHasReports')
->willReturn(true);
$defaultPromptOrderedByUser = $this->createMock(AskAnythingPrompt::class);
$defaultPromptOrderedByUser->expects($this->once())
->method('getOwner')
->willReturn(null);
$defaultPromptOrderedByUser->expects($this->once())
->method('getUuid')
->willReturn('default-uuid');
$defaultPromptOrderedByUser->expects($this->once())
->method('getTitle')
->willReturn('Sentiment');
$defaultPromptOrderedByUser->expects($this->once())
->method('getContent')
->willReturn('What was the overall sentiment of the customer during the call?');
$defaultPromptOrderedByUser->expects($this->once())
->method('getHasReports')
->willReturn(false);
$promptOwnedByUserAndSharedWithGroup = $this->createMock(AskAnythingPrompt::class);
$promptOwnedByUserAndSharedWithGroup->expects($this->exactly(2))
->method('getOwner')
->willReturn($user);
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getUuid')
->willReturn('uuid-2nd-prompt');
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getTitle')
->willReturn('Prompt shared with group');
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getContent')
->willReturn('Test prompt that is shared with group');
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getId')
->willReturn(109);
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getHasReports')
->willReturn(false);
$group = $this->createMock(Group::class);
$group->expects($this->once())
->method('getUuid')
->willReturn('uuid-of-the-group');
$sharedWithGroup = $this->createMock(UserAskAnythingPrompt::class);
$sharedWithGroup->expects($this->once())
->method('getUser')
->willReturn(null);
$sharedWithGroup->expects($this->once())
->method('getGroup')
->willReturn($group);
$this->askAnythingRepository->expects($this->exactly(2))
->method('findSharedUsersAndGroupsByPromptId')
->willReturnMap([
[99, new Collection([])],
[109, new Collection([$sharedWithGroup])],
]);
$prompts = [$defaultPrompt, $promptOwnedByUser, $defaultPromptOrderedByUser, $promptOwnedByUserAndSharedWithGroup];
$this->askAnythingRepository->expects($this->once())
->method('findPromptsByUserAndTarget')
->willReturn(new Collection($prompts));
$expectedDto1 = new AskAnythingPromptDto(
'default-uuid',
'Sentiment',
'What was the overall sentiment of the customer during the call?',
AskAnythingPromptTarget::call,
null,
null,
null,
false,
);
$expectedDto2 = new AskAnythingPromptDto(
'uuid-1st-prompt',
'First users prompt',
'Test prompt',
AskAnythingPromptTarget::call,
'1',
[],
[],
true,
);
$expectedDto3 = new AskAnythingPromptDto(
'default-uuid',
'Sentiment',
'What was the overall sentiment of the customer during the call?',
AskAnythingPromptTarget::call,
null,
null,
null,
false,
);
$expectedDto4 = new AskAnythingPromptDto(
'uuid-2nd-prompt',
'Prompt shared with group',
'Test prompt that is shared with group',
AskAnythingPromptTarget::call,
'1',
[],
['uuid-of-the-group'],
false,
);
$dtos = $this->askAnythingPromptService->get($user, AskAnythingPromptTarget::call);
$this->assertEquals([$expectedDto1, $expectedDto2, $expectedDto3, $expectedDto4], $dtos);
}
public function testEditAskAnythingPrompt(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(123);
$prompt->expects($this->never())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(123);
$user->expects($this->once())
->method('getUuid')
->willReturn('owner-uuid');
$title = 'new title';
$content = 'new content';
$shareUsers = ['us-1'];
$shareGroups = ['gr-1', 'gr-2'];
$shareUser = $this->createMock(User::class);
$this->userRepository->expects($this->once())
->method('findByUuid')
->with('us-1')
->willReturn($shareUser);
$shareGroup1 = $this->createMock(Group::class);
$shareGroup2 = $this->createMock(Group::class);
$this->groupRepository->expects($this->exactly(2))
->method('findByUuid')
->willReturnMap([
['gr-1', $shareGroup1],
['gr-2', $shareGroup2],
]);
$editPrompt = $this->createMock(AskAnythingPrompt::class);
$editPrompt->expects($this->once())
->method('getTitle')
->willReturn($title);
$editPrompt->expects($this->once())
->method('getContent')
->willReturn($content);
$editPrompt->expects($this->once())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$editPrompt->expects($this->once())
->method('getUuid')
->willReturn('uuid-1st-prompt');
$this->askAnythingRepository->expects($this->once())
->method('editPrompt')
->with($prompt, $title, $content, [$shareUser], [$shareGroup1, $shareGroup2])
->willReturn($editPrompt);
$expectedDto = new AskAnythingPromptDto(
'uuid-1st-prompt',
$title,
$content,
AskAnythingPromptTarget::call,
'owner-uuid',
$shareUsers,
$shareGroups
);
$editDto = $this->askAnythingPromptService->edit($prompt, $user, $title, $content, $shareUsers, $shareGroups);
$this->assertEquals($expectedDto, $editDto);
}
public function testHideDefaultAndCreateAskAnythingPrompt(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(true);
$prompt->expects($this->once())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getUuid')
->willReturn('new-owner-uuid');
$title = 'title';
$content = 'content';
$shareUsers = ['us-1'];
$shareGroups = [];
$shareUser = $this->createMock(User::class);
$this->userRepository->expects($this->once())
->method('findByUuid')
->with('us-1')
->willReturn($shareUser);
$this->groupRepository->expects($this->never())
->method('findByUuid');
$newPrompt = $this->createMock(AskAnythingPrompt::class);
$newPrompt->expects($this->once())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$newPrompt->expects($this->once())
->method('getUuid')
->willReturn('uuid-1st-prompt');
$newPrompt->expects($this->once())
->method('getTitle')
->willReturn($title);
$newPrompt->expects($this->once())
->method('getContent')
->willReturn($content);
$this->askAnythingRepository->expects($this->once())
->method('hidePromptForUser');
$this->askAnythingRepository->expects($this->once())
->method('createPrompt')
->willReturn($newPrompt);
$expectedDto = new AskAnythingPromptDto(
'uuid-1st-prompt',
$title,
$content,
AskAnythingPromptTarget::call,
'new-owner-uuid',
$shareUsers,
$shareGroups
);
$actualDto = $this->askAnythingPromptService->edit($prompt, $user, $title, $content, $shareUsers, $shareGroups);
$this->assertEquals($expectedDto, $actualDto);
}
public function testDeleteAskAnythingPrompt(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->any())
->method('getId')
->willReturn(1);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
// Use Mockery for the relationship mock (more flexible)
$relationMock = \Mockery::mock(\Illuminate\Database\Eloquent\Relations\HasMany::class);
$relationMock->shouldReceive('withTrashed')
->once()
->andReturnSelf();
$relationMock->shouldReceive('update')
->once()
->with(['ask_anything_prompt_id' => null, 'status' => false]);
$prompt->expects($this->once())
->method('automatedReports')
->willReturn($relationMock);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(1);
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(1, $user)
->willReturn($userPrompt);
$userPrompt->expects($this->once())
->method('delete');
$this->askAnythingRepository->expects($this->any())
->method('findSharedUsersAndGroupsByPromptId')
->with(1)
->willReturn(new Collection([]));
$this->askAnythingRepository->expects($this->once())
->method('deletePrompt');
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testDeleteAskAnythingPromptWithRelations(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->any())
->method('getId')
->willReturn(1);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$user = $this->createMock(User::class);
$user->expects($this->any())
->method('getId')
->willReturn(1);
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(1, $user)
->willReturn($userPrompt);
$userPrompt->expects($this->once())
->method('delete');
$this->askAnythingRepository->expects($this->exactly(3))
->method('findSharedUsersAndGroupsByPromptId')
->willReturnMap([
[1, new Collection([$userPrompt])],
[1, new Collection([])],
]);
$this->askAnythingRepository->expects($this->never())
->method('deletePrompt');
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testHideDefaultAskAnythingPrompt(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(true);
$user = $this->createMock(User::class);
$this->askAnythingRepository->expects($this->once())
->method('hidePromptForUser');
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testHideSharedWithUserAskAnythingPrompt(): void
{
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$prompt->expects($this->exactly(3))
->method('getId')
->willReturn(33);
$relationMock = \Mockery::mock(\Illuminate\Database\Eloquent\Relations\HasMany::class);
$relationMock->shouldReceive('withTrashed')
->once()
->andReturnSelf();
$relationMock->shouldReceive('update')
->once()
->with(['ask_anything_prompt_id' => null, 'status' => false]);
$prompt->expects($this->once())
->method('automatedReports')
->willReturn($relationMock);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(2);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(33, $user)
->willReturn($userPrompt);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUserGroup')
->with(33, $user)
->willReturn(null);
$userPrompt->expects($this->once())
->method('delete');
$this->askAnythingRepository->expects($this->once())
->method('findSharedUsersAndGroupsByPromptId')
->with(33)
->willReturn(new Collection([]));
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testHideSharedWithUserAndGroupAskAnythingPrompt(): void
{
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$prompt->expects($this->exactly(2))
->method('getId')
->willReturn(33);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(2);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(33, $user)
->willReturn($userPrompt);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUserGroup')
->with(33, $user)
->willReturn($userPrompt);
$userPrompt->expects($this->never())
->method('delete');
$this->askAnythingRepository->expects($this->once())
->method('hidePromptForUser')
->with($prompt, $user);
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testHideSharedWithGroupAskAnythingPrompt(): void
{
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$prompt->expects($this->exactly(2))
->method('getId')
->willReturn(33);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(2);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(33, $user)
->willReturn(null);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUserGroup')
->with(33, $user)
->willReturn($userPrompt);
$userPrompt->expects($this->never())
->method('delete');
$this->askAnythingRepository->expects($this->once())
->method('hidePromptForUser')
->with($prompt, $user);
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testDeleteWithNoSharesAndNotOwner(): void
{
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$prompt->expects($this->exactly(2))
->method('getId')
->willReturn(33);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(2);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(33, $user)
->willReturn(null);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUserGroup')
->with(33, $user)
->willReturn(null);
$userPrompt->expects($this->never())
->method('delete');
$this->askAnythingRepository->expects($this->never())
->method('hidePromptForUser');
$this->expectException(\InvalidArgumentException::class);
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testReorderAskAnythingPrompts(): void
{
$prompts = ['id1', 'id2', 'id3'];
$prompt1 = $this->createMock(AskAnythingPrompt::class);
$prompt2 = $this->createMock(AskAnythingPrompt::class);
$prompt3 = $this->createMock(AskAnythingPrompt::class);
$user = $this->createMock(User::class);
$this->askAnythingRepository->expects($this->exactly(3))
->method('getPromptByUuid')
->willReturnMap([
['id1', $prompt1],
['id2', $prompt2],
['id3', $prompt3],
]);
$this->askAnythingRepository->expects($this->exactly(3))
->method('orderPromptForUser')
->willReturnMap([
[[$prompt1, $user, 1]],
[[$prompt2, $user, 2]],
[[$prompt3, $user, 3]],
]);
$this->askAnythingPromptService->reorder($user, $prompts);
}
public function testCreateAskAnythingPromptWithTwoUsers(): void
{
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getUuid')
->willReturn('uuid-of-the-user');
$shareUser1 = $this->createMock(User::class);
$shareUser2 = $this->createMock(User::class);
$title = 'Test title';
$content = 'Test content';
$target = AskAnythingPromptTarget::call;
$shareUsers = ['us-1', 'us-2'];
$shareGroups = [];
$this->userRepository->expects($this->exactly(2))
->method('findByUuid')
->willReturnMap([
['us-1', $shareUser1],
['us-2', $shareUser2],
]);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('getUuid')
->willReturn('prompt-1-uuid');
$prompt->expects($this->once())
->method('getTitle')
->willReturn($title);
$prompt->expects($this->once())
->method('getContent')
->willReturn($content);
$this->askAnythingRepository->expects($this->once())
->method('createPrompt')
->with(
$user,
$target,
$title,
$content,
[$shareUser1, $shareUser2],
[],
)
->willReturn($prompt);
$expectedPromptDto = new AskAnythingPromptDto(
'prompt-1-uuid',
$title,
$content,
$target,
'uuid-of-the-user',
$shareUsers,
$shareGroups,
);
$actualPromptDto = $this->askAnythingPromptService->create(
$user,
$title,
$content,
$target,
$shareUsers,
$shareGroups
);
$this->assertEquals($expectedPromptDto, $actualPromptDto);
}
public function testRecreatePromptsForUserRelations(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('getId')
->willReturn(1);
$prompt->expects($this->once())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$prompt->expects($this->once())
->method('getTitle')
->willReturn('Test title');
$prompt->expects($this->once())
->method('getContent')
->willReturn('Test content');
$sharedPrompt = $this->createMock(UserAskAnythingPrompt::class);
$sharedUser = $this->createMock(User::class);
$sharedUser->expects($this->once())
->method('isStatusActive')
->willReturn(true);
$sharedUser->expects($this->once())
->method('getId')
->willReturn(1);
$sharedPrompt->expects($this->once())
->method('getUser')
->willReturn($sharedUser);
$sharedPrompt->expects($this->exactly(2))
->method('isRemoved')
->willReturn(false);
$sharedPrompt->expects($this->once())
->method('delete');
$this->askAnythingRepository->expects($this->once())
->method('findSharedUsersAndGroupsByPromptId')
->with(1)
->willReturn(new Collection([$sharedPrompt]));
$this->askAnythingRepository->expects($this->once())
->method('createPrompt');
$data = $this->invokePrivateMethod('recreatePromptsForUserRelations', $this->askAnythingPromptService, [$prompt]);
$this->assertEquals([[1], []], $data);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
56826
|
NULL
|
NULL
|
NULL
|
|
56829
|
NULL
|
0
|
2026-05-19T08:28:06.944958+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779179286944_m2.jpg...
|
PhpStorm
|
faVsco.js – AskAnythingPromptServiceTest.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20676-delete-report-re Project: faVsco.js, menu
JY-20676-delete-report-related-objects, 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
6
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Component\AskAnything;
use Illuminate\Database\Eloquent\Collection;
use Jiminny\Component\AskAnything\AskAnythingPromptService;
use Jiminny\Component\AskAnything\Dtos\AskAnythingPromptDto;
use Jiminny\Contracts\Repositories\GroupRepositoryInterface;
use Jiminny\Models\AskAnything\AskAnythingPrompt;
use Jiminny\Models\AskAnything\AskAnythingPromptTarget;
use Jiminny\Models\AskAnything\UserAskAnythingPrompt;
use Jiminny\Models\Group;
use Jiminny\Models\User;
use Jiminny\Repositories\AskAnythingRepository;
use Jiminny\Repositories\UserRepository;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
use Tests\Unit\Traits\TestPrivateMethod;
class AskAnythingPromptServiceTest extends TestCase
{
use TestPrivateMethod;
private AskAnythingPromptService $askAnythingPromptService;
private AskAnythingRepository&MockObject $askAnythingRepository;
private UserRepository&MockObject $userRepository;
private GroupRepositoryInterface&MockObject $groupRepository;
protected function setUp(): void
{
$this->askAnythingRepository = $this->createMock(AskAnythingRepository::class);
$this->userRepository = $this->createMock(UserRepository::class);
$this->groupRepository = $this->createMock(GroupRepositoryInterface::class);
$this->askAnythingPromptService = new AskAnythingPromptService(
$this->askAnythingRepository,
$this->userRepository,
$this->groupRepository
);
}
public function testGetAskAnythingPrompts(): void
{
$user = $this->createMock(User::class);
$user->expects($this->any())
->method('getId')
->willReturn(1);
$user->expects($this->any())
->method('getUuid')
->willReturn('1');
$defaultPrompt = $this->createMock(AskAnythingPrompt::class);
$defaultPrompt->expects($this->once())
->method('getOwner')
->willReturn(null);
$defaultPrompt->expects($this->once())
->method('getUuid')
->willReturn('default-uuid');
$defaultPrompt->expects($this->once())
->method('getTitle')
->willReturn('Sentiment');
$defaultPrompt->expects($this->once())
->method('getContent')
->willReturn('What was the overall sentiment of the customer during the call?');
$defaultPrompt->expects($this->once())
->method('getHasReports')
->willReturn(false);
$promptOwnedByUser = $this->createMock(AskAnythingPrompt::class);
$promptOwnedByUser->expects($this->exactly(2))
->method('getOwner')
->willReturn($user);
$promptOwnedByUser->expects($this->once())
->method('getUuid')
->willReturn('uuid-1st-prompt');
$promptOwnedByUser->expects($this->once())
->method('getTitle')
->willReturn('First users prompt');
$promptOwnedByUser->expects($this->once())
->method('getContent')
->willReturn('Test prompt');
$promptOwnedByUser->expects($this->once())
->method('getId')
->willReturn(99);
$promptOwnedByUser->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$promptOwnedByUser->expects($this->once())
->method('getHasReports')
->willReturn(true);
$defaultPromptOrderedByUser = $this->createMock(AskAnythingPrompt::class);
$defaultPromptOrderedByUser->expects($this->once())
->method('getOwner')
->willReturn(null);
$defaultPromptOrderedByUser->expects($this->once())
->method('getUuid')
->willReturn('default-uuid');
$defaultPromptOrderedByUser->expects($this->once())
->method('getTitle')
->willReturn('Sentiment');
$defaultPromptOrderedByUser->expects($this->once())
->method('getContent')
->willReturn('What was the overall sentiment of the customer during the call?');
$defaultPromptOrderedByUser->expects($this->once())
->method('getHasReports')
->willReturn(false);
$promptOwnedByUserAndSharedWithGroup = $this->createMock(AskAnythingPrompt::class);
$promptOwnedByUserAndSharedWithGroup->expects($this->exactly(2))
->method('getOwner')
->willReturn($user);
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getUuid')
->willReturn('uuid-2nd-prompt');
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getTitle')
->willReturn('Prompt shared with group');
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getContent')
->willReturn('Test prompt that is shared with group');
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getId')
->willReturn(109);
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getHasReports')
->willReturn(false);
$group = $this->createMock(Group::class);
$group->expects($this->once())
->method('getUuid')
->willReturn('uuid-of-the-group');
$sharedWithGroup = $this->createMock(UserAskAnythingPrompt::class);
$sharedWithGroup->expects($this->once())
->method('getUser')
->willReturn(null);
$sharedWithGroup->expects($this->once())
->method('getGroup')
->willReturn($group);
$this->askAnythingRepository->expects($this->exactly(2))
->method('findSharedUsersAndGroupsByPromptId')
->willReturnMap([
[99, new Collection([])],
[109, new Collection([$sharedWithGroup])],
]);
$prompts = [$defaultPrompt, $promptOwnedByUser, $defaultPromptOrderedByUser, $promptOwnedByUserAndSharedWithGroup];
$this->askAnythingRepository->expects($this->once())
->method('findPromptsByUserAndTarget')
->willReturn(new Collection($prompts));
$expectedDto1 = new AskAnythingPromptDto(
'default-uuid',
'Sentiment',
'What was the overall sentiment of the customer during the call?',
AskAnythingPromptTarget::call,
null,
null,
null,
false,
);
$expectedDto2 = new AskAnythingPromptDto(
'uuid-1st-prompt',
'First users prompt',
'Test prompt',
AskAnythingPromptTarget::call,
'1',
[],
[],
true,
);
$expectedDto3 = new AskAnythingPromptDto(
'default-uuid',
'Sentiment',
'What was the overall sentiment of the customer during the call?',
AskAnythingPromptTarget::call,
null,
null,
null,
false,
);
$expectedDto4 = new AskAnythingPromptDto(
'uuid-2nd-prompt',
'Prompt shared with group',
'Test prompt that is shared with group',
AskAnythingPromptTarget::call,
'1',
[],
['uuid-of-the-group'],
false,
);
$dtos = $this->askAnythingPromptService->get($user, AskAnythingPromptTarget::call);
$this->assertEquals([$expectedDto1, $expectedDto2, $expectedDto3, $expectedDto4], $dtos);
}
public function testEditAskAnythingPrompt(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(123);
$prompt->expects($this->never())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(123);
$user->expects($this->once())
->method('getUuid')
->willReturn('owner-uuid');
$title = 'new title';
$content = 'new content';
$shareUsers = ['us-1'];
$shareGroups = ['gr-1', 'gr-2'];
$shareUser = $this->createMock(User::class);
$this->userRepository->expects($this->once())
->method('findByUuid')
->with('us-1')
->willReturn($shareUser);
$shareGroup1 = $this->createMock(Group::class);
$shareGroup2 = $this->createMock(Group::class);
$this->groupRepository->expects($this->exactly(2))
->method('findByUuid')
->willReturnMap([
['gr-1', $shareGroup1],
['gr-2', $shareGroup2],
]);
$editPrompt = $this->createMock(AskAnythingPrompt::class);
$editPrompt->expects($this->once())
->method('getTitle')
->willReturn($title);
$editPrompt->expects($this->once())
->method('getContent')
->willReturn($content);
$editPrompt->expects($this->once())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$editPrompt->expects($this->once())
->method('getUuid')
->willReturn('uuid-1st-prompt');
$this->askAnythingRepository->expects($this->once())
->method('editPrompt')
->with($prompt, $title, $content, [$shareUser], [$shareGroup1, $shareGroup2])
->willReturn($editPrompt);
$expectedDto = new AskAnythingPromptDto(
'uuid-1st-prompt',
$title,
$content,
AskAnythingPromptTarget::call,
'owner-uuid',
$shareUsers,
$shareGroups
);
$editDto = $this->askAnythingPromptService->edit($prompt, $user, $title, $content, $shareUsers, $shareGroups);
$this->assertEquals($expectedDto, $editDto);
}
public function testHideDefaultAndCreateAskAnythingPrompt(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(true);
$prompt->expects($this->once())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getUuid')
->willReturn('new-owner-uuid');
$title = 'title';
$content = 'content';
$shareUsers = ['us-1'];
$shareGroups = [];
$shareUser = $this->createMock(User::class);
$this->userRepository->expects($this->once())
->method('findByUuid')
->with('us-1')
->willReturn($shareUser);
$this->groupRepository->expects($this->never())
->method('findByUuid');
$newPrompt = $this->createMock(AskAnythingPrompt::class);
$newPrompt->expects($this->once())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$newPrompt->expects($this->once())
->method('getUuid')
->willReturn('uuid-1st-prompt');
$newPrompt->expects($this->once())
->method('getTitle')
->willReturn($title);
$newPrompt->expects($this->once())
->method('getContent')
->willReturn($content);
$this->askAnythingRepository->expects($this->once())
->method('hidePromptForUser');
$this->askAnythingRepository->expects($this->once())
->method('createPrompt')
->willReturn($newPrompt);
$expectedDto = new AskAnythingPromptDto(
'uuid-1st-prompt',
$title,
$content,
AskAnythingPromptTarget::call,
'new-owner-uuid',
$shareUsers,
$shareGroups
);
$actualDto = $this->askAnythingPromptService->edit($prompt, $user, $title, $content, $shareUsers, $shareGroups);
$this->assertEquals($expectedDto, $actualDto);
}
public function testDeleteAskAnythingPrompt(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->any())
->method('getId')
->willReturn(1);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
// Use Mockery for the relationship mock (more flexible)
$relationMock = \Mockery::mock(\Illuminate\Database\Eloquent\Relations\HasMany::class);
$relationMock->shouldReceive('withTrashed')
->once()
->andReturnSelf();
$relationMock->shouldReceive('update')
->once()
->with(['ask_anything_prompt_id' => null, 'status' => false]);
$prompt->expects($this->once())
->method('automatedReports')
->willReturn($relationMock);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(1);
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(1, $user)
->willReturn($userPrompt);
$userPrompt->expects($this->once())
->method('delete');
$this->askAnythingRepository->expects($this->any())
->method('findSharedUsersAndGroupsByPromptId')
->with(1)
->willReturn(new Collection([]));
$this->askAnythingRepository->expects($this->once())
->method('deletePrompt');
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testDeleteAskAnythingPromptWithRelations(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->any())
->method('getId')
->willReturn(1);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$user = $this->createMock(User::class);
$user->expects($this->any())
->method('getId')
->willReturn(1);
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(1, $user)
->willReturn($userPrompt);
$userPrompt->expects($this->once())
->method('delete');
$this->askAnythingRepository->expects($this->exactly(3))
->method('findSharedUsersAndGroupsByPromptId')
->willReturnMap([
[1, new Collection([$userPrompt])],
[1, new Collection([])],
]);
$this->askAnythingRepository->expects($this->never())
->method('deletePrompt');
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testHideDefaultAskAnythingPrompt(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(true);
$user = $this->createMock(User::class);
$this->askAnythingRepository->expects($this->once())
->method('hidePromptForUser');
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testHideSharedWithUserAskAnythingPrompt(): void
{
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$prompt->expects($this->exactly(3))
->method('getId')
->willReturn(33);
$relationMock = \Mockery::mock(\Illuminate\Database\Eloquent\Relations\HasMany::class);
$relationMock->shouldReceive('withTrashed')
->once()
->andReturnSelf();
$relationMock->shouldReceive('update')
->once()
->with(['ask_anything_prompt_id' => null, 'status' => false]);
$prompt->expects($this->once())
->method('automatedReports')
->willReturn($relationMock);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(2);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(33, $user)
->willReturn($userPrompt);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUserGroup')
->with(33, $user)
->willReturn(null);
$userPrompt->expects($this->once())
->method('delete');
$this->askAnythingRepository->expects($this->once())
->method('findSharedUsersAndGroupsByPromptId')
->with(33)
->willReturn(new Collection([]));
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testHideSharedWithUserAndGroupAskAnythingPrompt(): void
{
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$prompt->expects($this->exactly(2))
->method('getId')
->willReturn(33);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(2);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(33, $user)
->willReturn($userPrompt);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUserGroup')
->with(33, $user)
->willReturn($userPrompt);
$userPrompt->expects($this->never())
->method('delete');
$this->askAnythingRepository->expects($this->once())
->method('hidePromptForUser')
->with($prompt, $user);
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testHideSharedWithGroupAskAnythingPrompt(): void
{
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$prompt->expects($this->exactly(2))
->method('getId')
->willReturn(33);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(2);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(33, $user)
->willReturn(null);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUserGroup')
->with(33, $user)
->willReturn($userPrompt);
$userPrompt->expects($this->never())
->method('delete');
$this->askAnythingRepository->expects($this->once())
->method('hidePromptForUser')
->with($prompt, $user);
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testDeleteWithNoSharesAndNotOwner(): void
{
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$prompt->expects($this->exactly(2))
->method('getId')
->willReturn(33);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(2);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(33, $user)
->willReturn(null);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUserGroup')
->with(33, $user)
->willReturn(null);
$userPrompt->expects($this->never())
->method('delete');
$this->askAnythingRepository->expects($this->never())
->method('hidePromptForUser');
$this->expectException(\InvalidArgumentException::class);
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testReorderAskAnythingPrompts(): void
{
$prompts = ['id1', 'id2', 'id3'];
$prompt1 = $this->createMock(AskAnythingPrompt::class);
$prompt2 = $this->createMock(AskAnythingPrompt::class);
$prompt3 = $this->createMock(AskAnythingPrompt::class);
$user = $this->createMock(User::class);
$this->askAnythingRepository->expects($this->exactly(3))
->method('getPromptByUuid')
->willReturnMap([
['id1', $prompt1],
['id2', $prompt2],
['id3', $prompt3],
]);
$this->askAnythingRepository->expects($this->exactly(3))
->method('orderPromptForUser')
->willReturnMap([
[[$prompt1, $user, 1]],
[[$prompt2, $user, 2]],
[[$prompt3, $user, 3]],
]);
$this->askAnythingPromptService->reorder($user, $prompts);
}
public function testCreateAskAnythingPromptWithTwoUsers(): void
{
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getUuid')
->willReturn('uuid-of-the-user');
$shareUser1 = $this->createMock(User::class);
$shareUser2 = $this->createMock(User::class);
$title = 'Test title';
$content = 'Test content';
$target = AskAnythingPromptTarget::call;
$shareUsers = ['us-1', 'us-2'];
$shareGroups = [];
$this->userRepository->expects($this->exactly(2))
->method('findByUuid')
->willReturnMap([
['us-1', $shareUser1],
['us-2', $shareUser2],
]);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('getUuid')
->willReturn('prompt-1-uuid');
$prompt->expects($this->once())
->method('getTitle')
->willReturn($title);
$prompt->expects($this->once())
->method('getContent')
->willReturn($content);
$this->askAnythingRepository->expects($this->once())
->method('createPrompt')
->with(
$user,
$target,
$title,
$content,
[$shareUser1, $shareUser2],
[],
)
->willReturn($prompt);
$expectedPromptDto = new AskAnythingPromptDto(
'prompt-1-uuid',
$title,
$content,
$target,
'uuid-of-the-user',
$shareUsers,
$shareGroups,
);
$actualPromptDto = $this->askAnythingPromptService->create(
$user,
$title,
$content,
$target,
$shareUsers,
$shareGroups
);
$this->assertEquals($expectedPromptDto, $actualPromptDto);
}
public function testRecreatePromptsForUserRelations(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('getId')
->willReturn(1);
$prompt->expects($this->once())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$prompt->expects($this->once())
->method('getTitle')
->willReturn('Test title');
$prompt->expects($this->once())
->method('getContent')
->willReturn('Test content');
$sharedPrompt = $this->createMock(UserAskAnythingPrompt::class);
$sharedUser = $this->createMock(User::class);
$sharedUser->expects($this->once())
->method('isStatusActive')
->willReturn(true);
$sharedUser->expects($this->once())
->method('getId')
->willReturn(1);
$sharedPrompt->expects($this->once())
->method('getUser')
->willReturn($sharedUser);
$sharedPrompt->expects($this->exactly(2))
->method('isRemoved')
->willReturn(false);
$sharedPrompt->expects($this->once())
->method('delete');
$this->askAnythingRepository->expects($this->once())
->method('findSharedUsersAndGroupsByPromptId')
->with(1)
->willReturn(new Collection([$sharedPrompt]));
$this->askAnythingRepository->expects($this->once())
->method('createPrompt');
$data = $this->invokePrivateMethod('recreatePromptsForUserRelations', $this->askAnythingPromptService, [$prompt]);
$this->assertEquals([[1], []], $data);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20676-delete-report-related-objects, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.098071806,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20676-delete-report-related-objects","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":"6","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.007978723,"height":0.0},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.00731383,"height":0.0},"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.00731383,"height":0.0},"on_screen":false,"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.27027926,"top":1.0,"width":0.006981383,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Component\\AskAnything;\n\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Jiminny\\Component\\AskAnything\\AskAnythingPromptService;\nuse Jiminny\\Component\\AskAnything\\Dtos\\AskAnythingPromptDto;\nuse Jiminny\\Contracts\\Repositories\\GroupRepositoryInterface;\nuse Jiminny\\Models\\AskAnything\\AskAnythingPrompt;\nuse Jiminny\\Models\\AskAnything\\AskAnythingPromptTarget;\nuse Jiminny\\Models\\AskAnything\\UserAskAnythingPrompt;\nuse Jiminny\\Models\\Group;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AskAnythingRepository;\nuse Jiminny\\Repositories\\UserRepository;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Tests\\TestCase;\nuse Tests\\Unit\\Traits\\TestPrivateMethod;\n\nclass AskAnythingPromptServiceTest extends TestCase\n{\n use TestPrivateMethod;\n\n private AskAnythingPromptService $askAnythingPromptService;\n private AskAnythingRepository&MockObject $askAnythingRepository;\n private UserRepository&MockObject $userRepository;\n private GroupRepositoryInterface&MockObject $groupRepository;\n\n protected function setUp(): void\n {\n $this->askAnythingRepository = $this->createMock(AskAnythingRepository::class);\n $this->userRepository = $this->createMock(UserRepository::class);\n $this->groupRepository = $this->createMock(GroupRepositoryInterface::class);\n\n $this->askAnythingPromptService = new AskAnythingPromptService(\n $this->askAnythingRepository,\n $this->userRepository,\n $this->groupRepository\n );\n }\n\n public function testGetAskAnythingPrompts(): void\n {\n $user = $this->createMock(User::class);\n $user->expects($this->any())\n ->method('getId')\n ->willReturn(1);\n $user->expects($this->any())\n ->method('getUuid')\n ->willReturn('1');\n $defaultPrompt = $this->createMock(AskAnythingPrompt::class);\n $defaultPrompt->expects($this->once())\n ->method('getOwner')\n ->willReturn(null);\n $defaultPrompt->expects($this->once())\n ->method('getUuid')\n ->willReturn('default-uuid');\n $defaultPrompt->expects($this->once())\n ->method('getTitle')\n ->willReturn('Sentiment');\n $defaultPrompt->expects($this->once())\n ->method('getContent')\n ->willReturn('What was the overall sentiment of the customer during the call?');\n $defaultPrompt->expects($this->once())\n ->method('getHasReports')\n ->willReturn(false);\n $promptOwnedByUser = $this->createMock(AskAnythingPrompt::class);\n $promptOwnedByUser->expects($this->exactly(2))\n ->method('getOwner')\n ->willReturn($user);\n $promptOwnedByUser->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-1st-prompt');\n $promptOwnedByUser->expects($this->once())\n ->method('getTitle')\n ->willReturn('First users prompt');\n $promptOwnedByUser->expects($this->once())\n ->method('getContent')\n ->willReturn('Test prompt');\n $promptOwnedByUser->expects($this->once())\n ->method('getId')\n ->willReturn(99);\n $promptOwnedByUser->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $promptOwnedByUser->expects($this->once())\n ->method('getHasReports')\n ->willReturn(true);\n $defaultPromptOrderedByUser = $this->createMock(AskAnythingPrompt::class);\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getOwner')\n ->willReturn(null);\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getUuid')\n ->willReturn('default-uuid');\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getTitle')\n ->willReturn('Sentiment');\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getContent')\n ->willReturn('What was the overall sentiment of the customer during the call?');\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getHasReports')\n ->willReturn(false);\n $promptOwnedByUserAndSharedWithGroup = $this->createMock(AskAnythingPrompt::class);\n $promptOwnedByUserAndSharedWithGroup->expects($this->exactly(2))\n ->method('getOwner')\n ->willReturn($user);\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-2nd-prompt');\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getTitle')\n ->willReturn('Prompt shared with group');\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getContent')\n ->willReturn('Test prompt that is shared with group');\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getId')\n ->willReturn(109);\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getHasReports')\n ->willReturn(false);\n\n $group = $this->createMock(Group::class);\n $group->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-of-the-group');\n $sharedWithGroup = $this->createMock(UserAskAnythingPrompt::class);\n $sharedWithGroup->expects($this->once())\n ->method('getUser')\n ->willReturn(null);\n $sharedWithGroup->expects($this->once())\n ->method('getGroup')\n ->willReturn($group);\n\n $this->askAnythingRepository->expects($this->exactly(2))\n ->method('findSharedUsersAndGroupsByPromptId')\n ->willReturnMap([\n [99, new Collection([])],\n [109, new Collection([$sharedWithGroup])],\n ]);\n\n $prompts = [$defaultPrompt, $promptOwnedByUser, $defaultPromptOrderedByUser, $promptOwnedByUserAndSharedWithGroup];\n $this->askAnythingRepository->expects($this->once())\n ->method('findPromptsByUserAndTarget')\n ->willReturn(new Collection($prompts));\n\n $expectedDto1 = new AskAnythingPromptDto(\n 'default-uuid',\n 'Sentiment',\n 'What was the overall sentiment of the customer during the call?',\n AskAnythingPromptTarget::call,\n null,\n null,\n null,\n false,\n );\n $expectedDto2 = new AskAnythingPromptDto(\n 'uuid-1st-prompt',\n 'First users prompt',\n 'Test prompt',\n AskAnythingPromptTarget::call,\n '1',\n [],\n [],\n true,\n );\n $expectedDto3 = new AskAnythingPromptDto(\n 'default-uuid',\n 'Sentiment',\n 'What was the overall sentiment of the customer during the call?',\n AskAnythingPromptTarget::call,\n null,\n null,\n null,\n false,\n );\n $expectedDto4 = new AskAnythingPromptDto(\n 'uuid-2nd-prompt',\n 'Prompt shared with group',\n 'Test prompt that is shared with group',\n AskAnythingPromptTarget::call,\n '1',\n [],\n ['uuid-of-the-group'],\n false,\n );\n $dtos = $this->askAnythingPromptService->get($user, AskAnythingPromptTarget::call);\n\n $this->assertEquals([$expectedDto1, $expectedDto2, $expectedDto3, $expectedDto4], $dtos);\n }\n\n public function testEditAskAnythingPrompt(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(123);\n $prompt->expects($this->never())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(123);\n $user->expects($this->once())\n ->method('getUuid')\n ->willReturn('owner-uuid');\n\n $title = 'new title';\n $content = 'new content';\n $shareUsers = ['us-1'];\n $shareGroups = ['gr-1', 'gr-2'];\n\n $shareUser = $this->createMock(User::class);\n $this->userRepository->expects($this->once())\n ->method('findByUuid')\n ->with('us-1')\n ->willReturn($shareUser);\n $shareGroup1 = $this->createMock(Group::class);\n $shareGroup2 = $this->createMock(Group::class);\n $this->groupRepository->expects($this->exactly(2))\n ->method('findByUuid')\n ->willReturnMap([\n ['gr-1', $shareGroup1],\n ['gr-2', $shareGroup2],\n ]);\n\n $editPrompt = $this->createMock(AskAnythingPrompt::class);\n $editPrompt->expects($this->once())\n ->method('getTitle')\n ->willReturn($title);\n $editPrompt->expects($this->once())\n ->method('getContent')\n ->willReturn($content);\n $editPrompt->expects($this->once())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $editPrompt->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-1st-prompt');\n $this->askAnythingRepository->expects($this->once())\n ->method('editPrompt')\n ->with($prompt, $title, $content, [$shareUser], [$shareGroup1, $shareGroup2])\n ->willReturn($editPrompt);\n\n $expectedDto = new AskAnythingPromptDto(\n 'uuid-1st-prompt',\n $title,\n $content,\n AskAnythingPromptTarget::call,\n 'owner-uuid',\n $shareUsers,\n $shareGroups\n );\n $editDto = $this->askAnythingPromptService->edit($prompt, $user, $title, $content, $shareUsers, $shareGroups);\n\n $this->assertEquals($expectedDto, $editDto);\n }\n\n public function testHideDefaultAndCreateAskAnythingPrompt(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(true);\n $prompt->expects($this->once())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getUuid')\n ->willReturn('new-owner-uuid');\n $title = 'title';\n $content = 'content';\n $shareUsers = ['us-1'];\n $shareGroups = [];\n $shareUser = $this->createMock(User::class);\n $this->userRepository->expects($this->once())\n ->method('findByUuid')\n ->with('us-1')\n ->willReturn($shareUser);\n $this->groupRepository->expects($this->never())\n ->method('findByUuid');\n\n $newPrompt = $this->createMock(AskAnythingPrompt::class);\n $newPrompt->expects($this->once())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $newPrompt->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-1st-prompt');\n $newPrompt->expects($this->once())\n ->method('getTitle')\n ->willReturn($title);\n $newPrompt->expects($this->once())\n ->method('getContent')\n ->willReturn($content);\n\n $this->askAnythingRepository->expects($this->once())\n ->method('hidePromptForUser');\n $this->askAnythingRepository->expects($this->once())\n ->method('createPrompt')\n ->willReturn($newPrompt);\n\n $expectedDto = new AskAnythingPromptDto(\n 'uuid-1st-prompt',\n $title,\n $content,\n AskAnythingPromptTarget::call,\n 'new-owner-uuid',\n $shareUsers,\n $shareGroups\n );\n\n $actualDto = $this->askAnythingPromptService->edit($prompt, $user, $title, $content, $shareUsers, $shareGroups);\n\n $this->assertEquals($expectedDto, $actualDto);\n }\n\n public function testDeleteAskAnythingPrompt(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->any())\n ->method('getId')\n ->willReturn(1);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n\n // Use Mockery for the relationship mock (more flexible)\n $relationMock = \\Mockery::mock(\\Illuminate\\Database\\Eloquent\\Relations\\HasMany::class);\n $relationMock->shouldReceive('withTrashed')\n ->once()\n ->andReturnSelf();\n $relationMock->shouldReceive('update')\n ->once()\n ->with(['ask_anything_prompt_id' => null, 'status' => false]);\n\n $prompt->expects($this->once())\n ->method('automatedReports')\n ->willReturn($relationMock);\n\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(1);\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(1, $user)\n ->willReturn($userPrompt);\n $userPrompt->expects($this->once())\n ->method('delete');\n $this->askAnythingRepository->expects($this->any())\n ->method('findSharedUsersAndGroupsByPromptId')\n ->with(1)\n ->willReturn(new Collection([]));\n $this->askAnythingRepository->expects($this->once())\n ->method('deletePrompt');\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testDeleteAskAnythingPromptWithRelations(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->any())\n ->method('getId')\n ->willReturn(1);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $user = $this->createMock(User::class);\n $user->expects($this->any())\n ->method('getId')\n ->willReturn(1);\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(1, $user)\n ->willReturn($userPrompt);\n $userPrompt->expects($this->once())\n ->method('delete');\n $this->askAnythingRepository->expects($this->exactly(3))\n ->method('findSharedUsersAndGroupsByPromptId')\n ->willReturnMap([\n [1, new Collection([$userPrompt])],\n [1, new Collection([])],\n ]);\n $this->askAnythingRepository->expects($this->never())\n ->method('deletePrompt');\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testHideDefaultAskAnythingPrompt(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(true);\n $user = $this->createMock(User::class);\n $this->askAnythingRepository->expects($this->once())\n ->method('hidePromptForUser');\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testHideSharedWithUserAskAnythingPrompt(): void\n {\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $prompt->expects($this->exactly(3))\n ->method('getId')\n ->willReturn(33);\n\n $relationMock = \\Mockery::mock(\\Illuminate\\Database\\Eloquent\\Relations\\HasMany::class);\n $relationMock->shouldReceive('withTrashed')\n ->once()\n ->andReturnSelf();\n $relationMock->shouldReceive('update')\n ->once()\n ->with(['ask_anything_prompt_id' => null, 'status' => false]);\n $prompt->expects($this->once())\n ->method('automatedReports')\n ->willReturn($relationMock);\n\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(2);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(33, $user)\n ->willReturn($userPrompt);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUserGroup')\n ->with(33, $user)\n ->willReturn(null);\n $userPrompt->expects($this->once())\n ->method('delete');\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedUsersAndGroupsByPromptId')\n ->with(33)\n ->willReturn(new Collection([]));\n\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testHideSharedWithUserAndGroupAskAnythingPrompt(): void\n {\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $prompt->expects($this->exactly(2))\n ->method('getId')\n ->willReturn(33);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(2);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(33, $user)\n ->willReturn($userPrompt);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUserGroup')\n ->with(33, $user)\n ->willReturn($userPrompt);\n $userPrompt->expects($this->never())\n ->method('delete');\n $this->askAnythingRepository->expects($this->once())\n ->method('hidePromptForUser')\n ->with($prompt, $user);\n\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testHideSharedWithGroupAskAnythingPrompt(): void\n {\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $prompt->expects($this->exactly(2))\n ->method('getId')\n ->willReturn(33);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(2);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(33, $user)\n ->willReturn(null);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUserGroup')\n ->with(33, $user)\n ->willReturn($userPrompt);\n $userPrompt->expects($this->never())\n ->method('delete');\n $this->askAnythingRepository->expects($this->once())\n ->method('hidePromptForUser')\n ->with($prompt, $user);\n\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testDeleteWithNoSharesAndNotOwner(): void\n {\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $prompt->expects($this->exactly(2))\n ->method('getId')\n ->willReturn(33);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(2);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(33, $user)\n ->willReturn(null);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUserGroup')\n ->with(33, $user)\n ->willReturn(null);\n $userPrompt->expects($this->never())\n ->method('delete');\n $this->askAnythingRepository->expects($this->never())\n ->method('hidePromptForUser');\n\n $this->expectException(\\InvalidArgumentException::class);\n\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testReorderAskAnythingPrompts(): void\n {\n $prompts = ['id1', 'id2', 'id3'];\n $prompt1 = $this->createMock(AskAnythingPrompt::class);\n $prompt2 = $this->createMock(AskAnythingPrompt::class);\n $prompt3 = $this->createMock(AskAnythingPrompt::class);\n $user = $this->createMock(User::class);\n $this->askAnythingRepository->expects($this->exactly(3))\n ->method('getPromptByUuid')\n ->willReturnMap([\n ['id1', $prompt1],\n ['id2', $prompt2],\n ['id3', $prompt3],\n ]);\n $this->askAnythingRepository->expects($this->exactly(3))\n ->method('orderPromptForUser')\n ->willReturnMap([\n [[$prompt1, $user, 1]],\n [[$prompt2, $user, 2]],\n [[$prompt3, $user, 3]],\n ]);\n $this->askAnythingPromptService->reorder($user, $prompts);\n }\n\n public function testCreateAskAnythingPromptWithTwoUsers(): void\n {\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-of-the-user');\n $shareUser1 = $this->createMock(User::class);\n $shareUser2 = $this->createMock(User::class);\n $title = 'Test title';\n $content = 'Test content';\n $target = AskAnythingPromptTarget::call;\n $shareUsers = ['us-1', 'us-2'];\n $shareGroups = [];\n\n $this->userRepository->expects($this->exactly(2))\n ->method('findByUuid')\n ->willReturnMap([\n ['us-1', $shareUser1],\n ['us-2', $shareUser2],\n ]);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('getUuid')\n ->willReturn('prompt-1-uuid');\n $prompt->expects($this->once())\n ->method('getTitle')\n ->willReturn($title);\n $prompt->expects($this->once())\n ->method('getContent')\n ->willReturn($content);\n $this->askAnythingRepository->expects($this->once())\n ->method('createPrompt')\n ->with(\n $user,\n $target,\n $title,\n $content,\n [$shareUser1, $shareUser2],\n [],\n )\n ->willReturn($prompt);\n\n $expectedPromptDto = new AskAnythingPromptDto(\n 'prompt-1-uuid',\n $title,\n $content,\n $target,\n 'uuid-of-the-user',\n $shareUsers,\n $shareGroups,\n );\n\n $actualPromptDto = $this->askAnythingPromptService->create(\n $user,\n $title,\n $content,\n $target,\n $shareUsers,\n $shareGroups\n );\n\n $this->assertEquals($expectedPromptDto, $actualPromptDto);\n }\n\n public function testRecreatePromptsForUserRelations(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('getId')\n ->willReturn(1);\n $prompt->expects($this->once())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $prompt->expects($this->once())\n ->method('getTitle')\n ->willReturn('Test title');\n $prompt->expects($this->once())\n ->method('getContent')\n ->willReturn('Test content');\n\n $sharedPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $sharedUser = $this->createMock(User::class);\n $sharedUser->expects($this->once())\n ->method('isStatusActive')\n ->willReturn(true);\n $sharedUser->expects($this->once())\n ->method('getId')\n ->willReturn(1);\n\n $sharedPrompt->expects($this->once())\n ->method('getUser')\n ->willReturn($sharedUser);\n $sharedPrompt->expects($this->exactly(2))\n ->method('isRemoved')\n ->willReturn(false);\n $sharedPrompt->expects($this->once())\n ->method('delete');\n\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedUsersAndGroupsByPromptId')\n ->with(1)\n ->willReturn(new Collection([$sharedPrompt]));\n\n $this->askAnythingRepository->expects($this->once())\n ->method('createPrompt');\n\n $data = $this->invokePrivateMethod('recreatePromptsForUserRelations', $this->askAnythingPromptService, [$prompt]);\n\n $this->assertEquals([[1], []], $data);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Component\\AskAnything;\n\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Jiminny\\Component\\AskAnything\\AskAnythingPromptService;\nuse Jiminny\\Component\\AskAnything\\Dtos\\AskAnythingPromptDto;\nuse Jiminny\\Contracts\\Repositories\\GroupRepositoryInterface;\nuse Jiminny\\Models\\AskAnything\\AskAnythingPrompt;\nuse Jiminny\\Models\\AskAnything\\AskAnythingPromptTarget;\nuse Jiminny\\Models\\AskAnything\\UserAskAnythingPrompt;\nuse Jiminny\\Models\\Group;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AskAnythingRepository;\nuse Jiminny\\Repositories\\UserRepository;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse Tests\\TestCase;\nuse Tests\\Unit\\Traits\\TestPrivateMethod;\n\nclass AskAnythingPromptServiceTest extends TestCase\n{\n use TestPrivateMethod;\n\n private AskAnythingPromptService $askAnythingPromptService;\n private AskAnythingRepository&MockObject $askAnythingRepository;\n private UserRepository&MockObject $userRepository;\n private GroupRepositoryInterface&MockObject $groupRepository;\n\n protected function setUp(): void\n {\n $this->askAnythingRepository = $this->createMock(AskAnythingRepository::class);\n $this->userRepository = $this->createMock(UserRepository::class);\n $this->groupRepository = $this->createMock(GroupRepositoryInterface::class);\n\n $this->askAnythingPromptService = new AskAnythingPromptService(\n $this->askAnythingRepository,\n $this->userRepository,\n $this->groupRepository\n );\n }\n\n public function testGetAskAnythingPrompts(): void\n {\n $user = $this->createMock(User::class);\n $user->expects($this->any())\n ->method('getId')\n ->willReturn(1);\n $user->expects($this->any())\n ->method('getUuid')\n ->willReturn('1');\n $defaultPrompt = $this->createMock(AskAnythingPrompt::class);\n $defaultPrompt->expects($this->once())\n ->method('getOwner')\n ->willReturn(null);\n $defaultPrompt->expects($this->once())\n ->method('getUuid')\n ->willReturn('default-uuid');\n $defaultPrompt->expects($this->once())\n ->method('getTitle')\n ->willReturn('Sentiment');\n $defaultPrompt->expects($this->once())\n ->method('getContent')\n ->willReturn('What was the overall sentiment of the customer during the call?');\n $defaultPrompt->expects($this->once())\n ->method('getHasReports')\n ->willReturn(false);\n $promptOwnedByUser = $this->createMock(AskAnythingPrompt::class);\n $promptOwnedByUser->expects($this->exactly(2))\n ->method('getOwner')\n ->willReturn($user);\n $promptOwnedByUser->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-1st-prompt');\n $promptOwnedByUser->expects($this->once())\n ->method('getTitle')\n ->willReturn('First users prompt');\n $promptOwnedByUser->expects($this->once())\n ->method('getContent')\n ->willReturn('Test prompt');\n $promptOwnedByUser->expects($this->once())\n ->method('getId')\n ->willReturn(99);\n $promptOwnedByUser->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $promptOwnedByUser->expects($this->once())\n ->method('getHasReports')\n ->willReturn(true);\n $defaultPromptOrderedByUser = $this->createMock(AskAnythingPrompt::class);\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getOwner')\n ->willReturn(null);\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getUuid')\n ->willReturn('default-uuid');\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getTitle')\n ->willReturn('Sentiment');\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getContent')\n ->willReturn('What was the overall sentiment of the customer during the call?');\n $defaultPromptOrderedByUser->expects($this->once())\n ->method('getHasReports')\n ->willReturn(false);\n $promptOwnedByUserAndSharedWithGroup = $this->createMock(AskAnythingPrompt::class);\n $promptOwnedByUserAndSharedWithGroup->expects($this->exactly(2))\n ->method('getOwner')\n ->willReturn($user);\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-2nd-prompt');\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getTitle')\n ->willReturn('Prompt shared with group');\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getContent')\n ->willReturn('Test prompt that is shared with group');\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getId')\n ->willReturn(109);\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $promptOwnedByUserAndSharedWithGroup->expects($this->once())\n ->method('getHasReports')\n ->willReturn(false);\n\n $group = $this->createMock(Group::class);\n $group->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-of-the-group');\n $sharedWithGroup = $this->createMock(UserAskAnythingPrompt::class);\n $sharedWithGroup->expects($this->once())\n ->method('getUser')\n ->willReturn(null);\n $sharedWithGroup->expects($this->once())\n ->method('getGroup')\n ->willReturn($group);\n\n $this->askAnythingRepository->expects($this->exactly(2))\n ->method('findSharedUsersAndGroupsByPromptId')\n ->willReturnMap([\n [99, new Collection([])],\n [109, new Collection([$sharedWithGroup])],\n ]);\n\n $prompts = [$defaultPrompt, $promptOwnedByUser, $defaultPromptOrderedByUser, $promptOwnedByUserAndSharedWithGroup];\n $this->askAnythingRepository->expects($this->once())\n ->method('findPromptsByUserAndTarget')\n ->willReturn(new Collection($prompts));\n\n $expectedDto1 = new AskAnythingPromptDto(\n 'default-uuid',\n 'Sentiment',\n 'What was the overall sentiment of the customer during the call?',\n AskAnythingPromptTarget::call,\n null,\n null,\n null,\n false,\n );\n $expectedDto2 = new AskAnythingPromptDto(\n 'uuid-1st-prompt',\n 'First users prompt',\n 'Test prompt',\n AskAnythingPromptTarget::call,\n '1',\n [],\n [],\n true,\n );\n $expectedDto3 = new AskAnythingPromptDto(\n 'default-uuid',\n 'Sentiment',\n 'What was the overall sentiment of the customer during the call?',\n AskAnythingPromptTarget::call,\n null,\n null,\n null,\n false,\n );\n $expectedDto4 = new AskAnythingPromptDto(\n 'uuid-2nd-prompt',\n 'Prompt shared with group',\n 'Test prompt that is shared with group',\n AskAnythingPromptTarget::call,\n '1',\n [],\n ['uuid-of-the-group'],\n false,\n );\n $dtos = $this->askAnythingPromptService->get($user, AskAnythingPromptTarget::call);\n\n $this->assertEquals([$expectedDto1, $expectedDto2, $expectedDto3, $expectedDto4], $dtos);\n }\n\n public function testEditAskAnythingPrompt(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(123);\n $prompt->expects($this->never())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(123);\n $user->expects($this->once())\n ->method('getUuid')\n ->willReturn('owner-uuid');\n\n $title = 'new title';\n $content = 'new content';\n $shareUsers = ['us-1'];\n $shareGroups = ['gr-1', 'gr-2'];\n\n $shareUser = $this->createMock(User::class);\n $this->userRepository->expects($this->once())\n ->method('findByUuid')\n ->with('us-1')\n ->willReturn($shareUser);\n $shareGroup1 = $this->createMock(Group::class);\n $shareGroup2 = $this->createMock(Group::class);\n $this->groupRepository->expects($this->exactly(2))\n ->method('findByUuid')\n ->willReturnMap([\n ['gr-1', $shareGroup1],\n ['gr-2', $shareGroup2],\n ]);\n\n $editPrompt = $this->createMock(AskAnythingPrompt::class);\n $editPrompt->expects($this->once())\n ->method('getTitle')\n ->willReturn($title);\n $editPrompt->expects($this->once())\n ->method('getContent')\n ->willReturn($content);\n $editPrompt->expects($this->once())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $editPrompt->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-1st-prompt');\n $this->askAnythingRepository->expects($this->once())\n ->method('editPrompt')\n ->with($prompt, $title, $content, [$shareUser], [$shareGroup1, $shareGroup2])\n ->willReturn($editPrompt);\n\n $expectedDto = new AskAnythingPromptDto(\n 'uuid-1st-prompt',\n $title,\n $content,\n AskAnythingPromptTarget::call,\n 'owner-uuid',\n $shareUsers,\n $shareGroups\n );\n $editDto = $this->askAnythingPromptService->edit($prompt, $user, $title, $content, $shareUsers, $shareGroups);\n\n $this->assertEquals($expectedDto, $editDto);\n }\n\n public function testHideDefaultAndCreateAskAnythingPrompt(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(true);\n $prompt->expects($this->once())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getUuid')\n ->willReturn('new-owner-uuid');\n $title = 'title';\n $content = 'content';\n $shareUsers = ['us-1'];\n $shareGroups = [];\n $shareUser = $this->createMock(User::class);\n $this->userRepository->expects($this->once())\n ->method('findByUuid')\n ->with('us-1')\n ->willReturn($shareUser);\n $this->groupRepository->expects($this->never())\n ->method('findByUuid');\n\n $newPrompt = $this->createMock(AskAnythingPrompt::class);\n $newPrompt->expects($this->once())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $newPrompt->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-1st-prompt');\n $newPrompt->expects($this->once())\n ->method('getTitle')\n ->willReturn($title);\n $newPrompt->expects($this->once())\n ->method('getContent')\n ->willReturn($content);\n\n $this->askAnythingRepository->expects($this->once())\n ->method('hidePromptForUser');\n $this->askAnythingRepository->expects($this->once())\n ->method('createPrompt')\n ->willReturn($newPrompt);\n\n $expectedDto = new AskAnythingPromptDto(\n 'uuid-1st-prompt',\n $title,\n $content,\n AskAnythingPromptTarget::call,\n 'new-owner-uuid',\n $shareUsers,\n $shareGroups\n );\n\n $actualDto = $this->askAnythingPromptService->edit($prompt, $user, $title, $content, $shareUsers, $shareGroups);\n\n $this->assertEquals($expectedDto, $actualDto);\n }\n\n public function testDeleteAskAnythingPrompt(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->any())\n ->method('getId')\n ->willReturn(1);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n\n // Use Mockery for the relationship mock (more flexible)\n $relationMock = \\Mockery::mock(\\Illuminate\\Database\\Eloquent\\Relations\\HasMany::class);\n $relationMock->shouldReceive('withTrashed')\n ->once()\n ->andReturnSelf();\n $relationMock->shouldReceive('update')\n ->once()\n ->with(['ask_anything_prompt_id' => null, 'status' => false]);\n\n $prompt->expects($this->once())\n ->method('automatedReports')\n ->willReturn($relationMock);\n\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(1);\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(1, $user)\n ->willReturn($userPrompt);\n $userPrompt->expects($this->once())\n ->method('delete');\n $this->askAnythingRepository->expects($this->any())\n ->method('findSharedUsersAndGroupsByPromptId')\n ->with(1)\n ->willReturn(new Collection([]));\n $this->askAnythingRepository->expects($this->once())\n ->method('deletePrompt');\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testDeleteAskAnythingPromptWithRelations(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->any())\n ->method('getId')\n ->willReturn(1);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $user = $this->createMock(User::class);\n $user->expects($this->any())\n ->method('getId')\n ->willReturn(1);\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(1, $user)\n ->willReturn($userPrompt);\n $userPrompt->expects($this->once())\n ->method('delete');\n $this->askAnythingRepository->expects($this->exactly(3))\n ->method('findSharedUsersAndGroupsByPromptId')\n ->willReturnMap([\n [1, new Collection([$userPrompt])],\n [1, new Collection([])],\n ]);\n $this->askAnythingRepository->expects($this->never())\n ->method('deletePrompt');\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testHideDefaultAskAnythingPrompt(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(true);\n $user = $this->createMock(User::class);\n $this->askAnythingRepository->expects($this->once())\n ->method('hidePromptForUser');\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testHideSharedWithUserAskAnythingPrompt(): void\n {\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $prompt->expects($this->exactly(3))\n ->method('getId')\n ->willReturn(33);\n\n $relationMock = \\Mockery::mock(\\Illuminate\\Database\\Eloquent\\Relations\\HasMany::class);\n $relationMock->shouldReceive('withTrashed')\n ->once()\n ->andReturnSelf();\n $relationMock->shouldReceive('update')\n ->once()\n ->with(['ask_anything_prompt_id' => null, 'status' => false]);\n $prompt->expects($this->once())\n ->method('automatedReports')\n ->willReturn($relationMock);\n\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(2);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(33, $user)\n ->willReturn($userPrompt);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUserGroup')\n ->with(33, $user)\n ->willReturn(null);\n $userPrompt->expects($this->once())\n ->method('delete');\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedUsersAndGroupsByPromptId')\n ->with(33)\n ->willReturn(new Collection([]));\n\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testHideSharedWithUserAndGroupAskAnythingPrompt(): void\n {\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $prompt->expects($this->exactly(2))\n ->method('getId')\n ->willReturn(33);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(2);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(33, $user)\n ->willReturn($userPrompt);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUserGroup')\n ->with(33, $user)\n ->willReturn($userPrompt);\n $userPrompt->expects($this->never())\n ->method('delete');\n $this->askAnythingRepository->expects($this->once())\n ->method('hidePromptForUser')\n ->with($prompt, $user);\n\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testHideSharedWithGroupAskAnythingPrompt(): void\n {\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $prompt->expects($this->exactly(2))\n ->method('getId')\n ->willReturn(33);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(2);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(33, $user)\n ->willReturn(null);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUserGroup')\n ->with(33, $user)\n ->willReturn($userPrompt);\n $userPrompt->expects($this->never())\n ->method('delete');\n $this->askAnythingRepository->expects($this->once())\n ->method('hidePromptForUser')\n ->with($prompt, $user);\n\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testDeleteWithNoSharesAndNotOwner(): void\n {\n $userPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('isDefaultPrompt')\n ->willReturn(false);\n $prompt->expects($this->once())\n ->method('getOwnerId')\n ->willReturn(1);\n $prompt->expects($this->exactly(2))\n ->method('getId')\n ->willReturn(33);\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getId')\n ->willReturn(2);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUser')\n ->with(33, $user)\n ->willReturn(null);\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedPromptByUserGroup')\n ->with(33, $user)\n ->willReturn(null);\n $userPrompt->expects($this->never())\n ->method('delete');\n $this->askAnythingRepository->expects($this->never())\n ->method('hidePromptForUser');\n\n $this->expectException(\\InvalidArgumentException::class);\n\n $this->askAnythingPromptService->delete($prompt, $user);\n }\n\n public function testReorderAskAnythingPrompts(): void\n {\n $prompts = ['id1', 'id2', 'id3'];\n $prompt1 = $this->createMock(AskAnythingPrompt::class);\n $prompt2 = $this->createMock(AskAnythingPrompt::class);\n $prompt3 = $this->createMock(AskAnythingPrompt::class);\n $user = $this->createMock(User::class);\n $this->askAnythingRepository->expects($this->exactly(3))\n ->method('getPromptByUuid')\n ->willReturnMap([\n ['id1', $prompt1],\n ['id2', $prompt2],\n ['id3', $prompt3],\n ]);\n $this->askAnythingRepository->expects($this->exactly(3))\n ->method('orderPromptForUser')\n ->willReturnMap([\n [[$prompt1, $user, 1]],\n [[$prompt2, $user, 2]],\n [[$prompt3, $user, 3]],\n ]);\n $this->askAnythingPromptService->reorder($user, $prompts);\n }\n\n public function testCreateAskAnythingPromptWithTwoUsers(): void\n {\n $user = $this->createMock(User::class);\n $user->expects($this->once())\n ->method('getUuid')\n ->willReturn('uuid-of-the-user');\n $shareUser1 = $this->createMock(User::class);\n $shareUser2 = $this->createMock(User::class);\n $title = 'Test title';\n $content = 'Test content';\n $target = AskAnythingPromptTarget::call;\n $shareUsers = ['us-1', 'us-2'];\n $shareGroups = [];\n\n $this->userRepository->expects($this->exactly(2))\n ->method('findByUuid')\n ->willReturnMap([\n ['us-1', $shareUser1],\n ['us-2', $shareUser2],\n ]);\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('getUuid')\n ->willReturn('prompt-1-uuid');\n $prompt->expects($this->once())\n ->method('getTitle')\n ->willReturn($title);\n $prompt->expects($this->once())\n ->method('getContent')\n ->willReturn($content);\n $this->askAnythingRepository->expects($this->once())\n ->method('createPrompt')\n ->with(\n $user,\n $target,\n $title,\n $content,\n [$shareUser1, $shareUser2],\n [],\n )\n ->willReturn($prompt);\n\n $expectedPromptDto = new AskAnythingPromptDto(\n 'prompt-1-uuid',\n $title,\n $content,\n $target,\n 'uuid-of-the-user',\n $shareUsers,\n $shareGroups,\n );\n\n $actualPromptDto = $this->askAnythingPromptService->create(\n $user,\n $title,\n $content,\n $target,\n $shareUsers,\n $shareGroups\n );\n\n $this->assertEquals($expectedPromptDto, $actualPromptDto);\n }\n\n public function testRecreatePromptsForUserRelations(): void\n {\n $prompt = $this->createMock(AskAnythingPrompt::class);\n $prompt->expects($this->once())\n ->method('getId')\n ->willReturn(1);\n $prompt->expects($this->once())\n ->method('getTarget')\n ->willReturn(AskAnythingPromptTarget::call);\n $prompt->expects($this->once())\n ->method('getTitle')\n ->willReturn('Test title');\n $prompt->expects($this->once())\n ->method('getContent')\n ->willReturn('Test content');\n\n $sharedPrompt = $this->createMock(UserAskAnythingPrompt::class);\n $sharedUser = $this->createMock(User::class);\n $sharedUser->expects($this->once())\n ->method('isStatusActive')\n ->willReturn(true);\n $sharedUser->expects($this->once())\n ->method('getId')\n ->willReturn(1);\n\n $sharedPrompt->expects($this->once())\n ->method('getUser')\n ->willReturn($sharedUser);\n $sharedPrompt->expects($this->exactly(2))\n ->method('isRemoved')\n ->willReturn(false);\n $sharedPrompt->expects($this->once())\n ->method('delete');\n\n $this->askAnythingRepository->expects($this->once())\n ->method('findSharedUsersAndGroupsByPromptId')\n ->with(1)\n ->willReturn(new Collection([$sharedPrompt]));\n\n $this->askAnythingRepository->expects($this->once())\n ->method('createPrompt');\n\n $data = $this->invokePrivateMethod('recreatePromptsForUserRelations', $this->askAnythingPromptService, [$prompt]);\n\n $this->assertEquals([[1], []], $data);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.7124335,"top":0.10055866,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.72140956,"top":0.09896249,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.7287234,"top":0.09896249,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","depth":4,"bounds":{"left":0.4481383,"top":0.09736632,"width":0.29288563,"height":0.8818835},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
1140439531069478179
|
-8755961741003010129
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20676-delete-report-re Project: faVsco.js, menu
JY-20676-delete-report-related-objects, 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
6
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Component\AskAnything;
use Illuminate\Database\Eloquent\Collection;
use Jiminny\Component\AskAnything\AskAnythingPromptService;
use Jiminny\Component\AskAnything\Dtos\AskAnythingPromptDto;
use Jiminny\Contracts\Repositories\GroupRepositoryInterface;
use Jiminny\Models\AskAnything\AskAnythingPrompt;
use Jiminny\Models\AskAnything\AskAnythingPromptTarget;
use Jiminny\Models\AskAnything\UserAskAnythingPrompt;
use Jiminny\Models\Group;
use Jiminny\Models\User;
use Jiminny\Repositories\AskAnythingRepository;
use Jiminny\Repositories\UserRepository;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
use Tests\Unit\Traits\TestPrivateMethod;
class AskAnythingPromptServiceTest extends TestCase
{
use TestPrivateMethod;
private AskAnythingPromptService $askAnythingPromptService;
private AskAnythingRepository&MockObject $askAnythingRepository;
private UserRepository&MockObject $userRepository;
private GroupRepositoryInterface&MockObject $groupRepository;
protected function setUp(): void
{
$this->askAnythingRepository = $this->createMock(AskAnythingRepository::class);
$this->userRepository = $this->createMock(UserRepository::class);
$this->groupRepository = $this->createMock(GroupRepositoryInterface::class);
$this->askAnythingPromptService = new AskAnythingPromptService(
$this->askAnythingRepository,
$this->userRepository,
$this->groupRepository
);
}
public function testGetAskAnythingPrompts(): void
{
$user = $this->createMock(User::class);
$user->expects($this->any())
->method('getId')
->willReturn(1);
$user->expects($this->any())
->method('getUuid')
->willReturn('1');
$defaultPrompt = $this->createMock(AskAnythingPrompt::class);
$defaultPrompt->expects($this->once())
->method('getOwner')
->willReturn(null);
$defaultPrompt->expects($this->once())
->method('getUuid')
->willReturn('default-uuid');
$defaultPrompt->expects($this->once())
->method('getTitle')
->willReturn('Sentiment');
$defaultPrompt->expects($this->once())
->method('getContent')
->willReturn('What was the overall sentiment of the customer during the call?');
$defaultPrompt->expects($this->once())
->method('getHasReports')
->willReturn(false);
$promptOwnedByUser = $this->createMock(AskAnythingPrompt::class);
$promptOwnedByUser->expects($this->exactly(2))
->method('getOwner')
->willReturn($user);
$promptOwnedByUser->expects($this->once())
->method('getUuid')
->willReturn('uuid-1st-prompt');
$promptOwnedByUser->expects($this->once())
->method('getTitle')
->willReturn('First users prompt');
$promptOwnedByUser->expects($this->once())
->method('getContent')
->willReturn('Test prompt');
$promptOwnedByUser->expects($this->once())
->method('getId')
->willReturn(99);
$promptOwnedByUser->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$promptOwnedByUser->expects($this->once())
->method('getHasReports')
->willReturn(true);
$defaultPromptOrderedByUser = $this->createMock(AskAnythingPrompt::class);
$defaultPromptOrderedByUser->expects($this->once())
->method('getOwner')
->willReturn(null);
$defaultPromptOrderedByUser->expects($this->once())
->method('getUuid')
->willReturn('default-uuid');
$defaultPromptOrderedByUser->expects($this->once())
->method('getTitle')
->willReturn('Sentiment');
$defaultPromptOrderedByUser->expects($this->once())
->method('getContent')
->willReturn('What was the overall sentiment of the customer during the call?');
$defaultPromptOrderedByUser->expects($this->once())
->method('getHasReports')
->willReturn(false);
$promptOwnedByUserAndSharedWithGroup = $this->createMock(AskAnythingPrompt::class);
$promptOwnedByUserAndSharedWithGroup->expects($this->exactly(2))
->method('getOwner')
->willReturn($user);
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getUuid')
->willReturn('uuid-2nd-prompt');
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getTitle')
->willReturn('Prompt shared with group');
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getContent')
->willReturn('Test prompt that is shared with group');
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getId')
->willReturn(109);
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$promptOwnedByUserAndSharedWithGroup->expects($this->once())
->method('getHasReports')
->willReturn(false);
$group = $this->createMock(Group::class);
$group->expects($this->once())
->method('getUuid')
->willReturn('uuid-of-the-group');
$sharedWithGroup = $this->createMock(UserAskAnythingPrompt::class);
$sharedWithGroup->expects($this->once())
->method('getUser')
->willReturn(null);
$sharedWithGroup->expects($this->once())
->method('getGroup')
->willReturn($group);
$this->askAnythingRepository->expects($this->exactly(2))
->method('findSharedUsersAndGroupsByPromptId')
->willReturnMap([
[99, new Collection([])],
[109, new Collection([$sharedWithGroup])],
]);
$prompts = [$defaultPrompt, $promptOwnedByUser, $defaultPromptOrderedByUser, $promptOwnedByUserAndSharedWithGroup];
$this->askAnythingRepository->expects($this->once())
->method('findPromptsByUserAndTarget')
->willReturn(new Collection($prompts));
$expectedDto1 = new AskAnythingPromptDto(
'default-uuid',
'Sentiment',
'What was the overall sentiment of the customer during the call?',
AskAnythingPromptTarget::call,
null,
null,
null,
false,
);
$expectedDto2 = new AskAnythingPromptDto(
'uuid-1st-prompt',
'First users prompt',
'Test prompt',
AskAnythingPromptTarget::call,
'1',
[],
[],
true,
);
$expectedDto3 = new AskAnythingPromptDto(
'default-uuid',
'Sentiment',
'What was the overall sentiment of the customer during the call?',
AskAnythingPromptTarget::call,
null,
null,
null,
false,
);
$expectedDto4 = new AskAnythingPromptDto(
'uuid-2nd-prompt',
'Prompt shared with group',
'Test prompt that is shared with group',
AskAnythingPromptTarget::call,
'1',
[],
['uuid-of-the-group'],
false,
);
$dtos = $this->askAnythingPromptService->get($user, AskAnythingPromptTarget::call);
$this->assertEquals([$expectedDto1, $expectedDto2, $expectedDto3, $expectedDto4], $dtos);
}
public function testEditAskAnythingPrompt(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(123);
$prompt->expects($this->never())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(123);
$user->expects($this->once())
->method('getUuid')
->willReturn('owner-uuid');
$title = 'new title';
$content = 'new content';
$shareUsers = ['us-1'];
$shareGroups = ['gr-1', 'gr-2'];
$shareUser = $this->createMock(User::class);
$this->userRepository->expects($this->once())
->method('findByUuid')
->with('us-1')
->willReturn($shareUser);
$shareGroup1 = $this->createMock(Group::class);
$shareGroup2 = $this->createMock(Group::class);
$this->groupRepository->expects($this->exactly(2))
->method('findByUuid')
->willReturnMap([
['gr-1', $shareGroup1],
['gr-2', $shareGroup2],
]);
$editPrompt = $this->createMock(AskAnythingPrompt::class);
$editPrompt->expects($this->once())
->method('getTitle')
->willReturn($title);
$editPrompt->expects($this->once())
->method('getContent')
->willReturn($content);
$editPrompt->expects($this->once())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$editPrompt->expects($this->once())
->method('getUuid')
->willReturn('uuid-1st-prompt');
$this->askAnythingRepository->expects($this->once())
->method('editPrompt')
->with($prompt, $title, $content, [$shareUser], [$shareGroup1, $shareGroup2])
->willReturn($editPrompt);
$expectedDto = new AskAnythingPromptDto(
'uuid-1st-prompt',
$title,
$content,
AskAnythingPromptTarget::call,
'owner-uuid',
$shareUsers,
$shareGroups
);
$editDto = $this->askAnythingPromptService->edit($prompt, $user, $title, $content, $shareUsers, $shareGroups);
$this->assertEquals($expectedDto, $editDto);
}
public function testHideDefaultAndCreateAskAnythingPrompt(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(true);
$prompt->expects($this->once())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getUuid')
->willReturn('new-owner-uuid');
$title = 'title';
$content = 'content';
$shareUsers = ['us-1'];
$shareGroups = [];
$shareUser = $this->createMock(User::class);
$this->userRepository->expects($this->once())
->method('findByUuid')
->with('us-1')
->willReturn($shareUser);
$this->groupRepository->expects($this->never())
->method('findByUuid');
$newPrompt = $this->createMock(AskAnythingPrompt::class);
$newPrompt->expects($this->once())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$newPrompt->expects($this->once())
->method('getUuid')
->willReturn('uuid-1st-prompt');
$newPrompt->expects($this->once())
->method('getTitle')
->willReturn($title);
$newPrompt->expects($this->once())
->method('getContent')
->willReturn($content);
$this->askAnythingRepository->expects($this->once())
->method('hidePromptForUser');
$this->askAnythingRepository->expects($this->once())
->method('createPrompt')
->willReturn($newPrompt);
$expectedDto = new AskAnythingPromptDto(
'uuid-1st-prompt',
$title,
$content,
AskAnythingPromptTarget::call,
'new-owner-uuid',
$shareUsers,
$shareGroups
);
$actualDto = $this->askAnythingPromptService->edit($prompt, $user, $title, $content, $shareUsers, $shareGroups);
$this->assertEquals($expectedDto, $actualDto);
}
public function testDeleteAskAnythingPrompt(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->any())
->method('getId')
->willReturn(1);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
// Use Mockery for the relationship mock (more flexible)
$relationMock = \Mockery::mock(\Illuminate\Database\Eloquent\Relations\HasMany::class);
$relationMock->shouldReceive('withTrashed')
->once()
->andReturnSelf();
$relationMock->shouldReceive('update')
->once()
->with(['ask_anything_prompt_id' => null, 'status' => false]);
$prompt->expects($this->once())
->method('automatedReports')
->willReturn($relationMock);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(1);
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(1, $user)
->willReturn($userPrompt);
$userPrompt->expects($this->once())
->method('delete');
$this->askAnythingRepository->expects($this->any())
->method('findSharedUsersAndGroupsByPromptId')
->with(1)
->willReturn(new Collection([]));
$this->askAnythingRepository->expects($this->once())
->method('deletePrompt');
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testDeleteAskAnythingPromptWithRelations(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->any())
->method('getId')
->willReturn(1);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$user = $this->createMock(User::class);
$user->expects($this->any())
->method('getId')
->willReturn(1);
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(1, $user)
->willReturn($userPrompt);
$userPrompt->expects($this->once())
->method('delete');
$this->askAnythingRepository->expects($this->exactly(3))
->method('findSharedUsersAndGroupsByPromptId')
->willReturnMap([
[1, new Collection([$userPrompt])],
[1, new Collection([])],
]);
$this->askAnythingRepository->expects($this->never())
->method('deletePrompt');
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testHideDefaultAskAnythingPrompt(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(true);
$user = $this->createMock(User::class);
$this->askAnythingRepository->expects($this->once())
->method('hidePromptForUser');
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testHideSharedWithUserAskAnythingPrompt(): void
{
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$prompt->expects($this->exactly(3))
->method('getId')
->willReturn(33);
$relationMock = \Mockery::mock(\Illuminate\Database\Eloquent\Relations\HasMany::class);
$relationMock->shouldReceive('withTrashed')
->once()
->andReturnSelf();
$relationMock->shouldReceive('update')
->once()
->with(['ask_anything_prompt_id' => null, 'status' => false]);
$prompt->expects($this->once())
->method('automatedReports')
->willReturn($relationMock);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(2);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(33, $user)
->willReturn($userPrompt);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUserGroup')
->with(33, $user)
->willReturn(null);
$userPrompt->expects($this->once())
->method('delete');
$this->askAnythingRepository->expects($this->once())
->method('findSharedUsersAndGroupsByPromptId')
->with(33)
->willReturn(new Collection([]));
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testHideSharedWithUserAndGroupAskAnythingPrompt(): void
{
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$prompt->expects($this->exactly(2))
->method('getId')
->willReturn(33);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(2);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(33, $user)
->willReturn($userPrompt);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUserGroup')
->with(33, $user)
->willReturn($userPrompt);
$userPrompt->expects($this->never())
->method('delete');
$this->askAnythingRepository->expects($this->once())
->method('hidePromptForUser')
->with($prompt, $user);
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testHideSharedWithGroupAskAnythingPrompt(): void
{
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$prompt->expects($this->exactly(2))
->method('getId')
->willReturn(33);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(2);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(33, $user)
->willReturn(null);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUserGroup')
->with(33, $user)
->willReturn($userPrompt);
$userPrompt->expects($this->never())
->method('delete');
$this->askAnythingRepository->expects($this->once())
->method('hidePromptForUser')
->with($prompt, $user);
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testDeleteWithNoSharesAndNotOwner(): void
{
$userPrompt = $this->createMock(UserAskAnythingPrompt::class);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('isDefaultPrompt')
->willReturn(false);
$prompt->expects($this->once())
->method('getOwnerId')
->willReturn(1);
$prompt->expects($this->exactly(2))
->method('getId')
->willReturn(33);
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getId')
->willReturn(2);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUser')
->with(33, $user)
->willReturn(null);
$this->askAnythingRepository->expects($this->once())
->method('findSharedPromptByUserGroup')
->with(33, $user)
->willReturn(null);
$userPrompt->expects($this->never())
->method('delete');
$this->askAnythingRepository->expects($this->never())
->method('hidePromptForUser');
$this->expectException(\InvalidArgumentException::class);
$this->askAnythingPromptService->delete($prompt, $user);
}
public function testReorderAskAnythingPrompts(): void
{
$prompts = ['id1', 'id2', 'id3'];
$prompt1 = $this->createMock(AskAnythingPrompt::class);
$prompt2 = $this->createMock(AskAnythingPrompt::class);
$prompt3 = $this->createMock(AskAnythingPrompt::class);
$user = $this->createMock(User::class);
$this->askAnythingRepository->expects($this->exactly(3))
->method('getPromptByUuid')
->willReturnMap([
['id1', $prompt1],
['id2', $prompt2],
['id3', $prompt3],
]);
$this->askAnythingRepository->expects($this->exactly(3))
->method('orderPromptForUser')
->willReturnMap([
[[$prompt1, $user, 1]],
[[$prompt2, $user, 2]],
[[$prompt3, $user, 3]],
]);
$this->askAnythingPromptService->reorder($user, $prompts);
}
public function testCreateAskAnythingPromptWithTwoUsers(): void
{
$user = $this->createMock(User::class);
$user->expects($this->once())
->method('getUuid')
->willReturn('uuid-of-the-user');
$shareUser1 = $this->createMock(User::class);
$shareUser2 = $this->createMock(User::class);
$title = 'Test title';
$content = 'Test content';
$target = AskAnythingPromptTarget::call;
$shareUsers = ['us-1', 'us-2'];
$shareGroups = [];
$this->userRepository->expects($this->exactly(2))
->method('findByUuid')
->willReturnMap([
['us-1', $shareUser1],
['us-2', $shareUser2],
]);
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('getUuid')
->willReturn('prompt-1-uuid');
$prompt->expects($this->once())
->method('getTitle')
->willReturn($title);
$prompt->expects($this->once())
->method('getContent')
->willReturn($content);
$this->askAnythingRepository->expects($this->once())
->method('createPrompt')
->with(
$user,
$target,
$title,
$content,
[$shareUser1, $shareUser2],
[],
)
->willReturn($prompt);
$expectedPromptDto = new AskAnythingPromptDto(
'prompt-1-uuid',
$title,
$content,
$target,
'uuid-of-the-user',
$shareUsers,
$shareGroups,
);
$actualPromptDto = $this->askAnythingPromptService->create(
$user,
$title,
$content,
$target,
$shareUsers,
$shareGroups
);
$this->assertEquals($expectedPromptDto, $actualPromptDto);
}
public function testRecreatePromptsForUserRelations(): void
{
$prompt = $this->createMock(AskAnythingPrompt::class);
$prompt->expects($this->once())
->method('getId')
->willReturn(1);
$prompt->expects($this->once())
->method('getTarget')
->willReturn(AskAnythingPromptTarget::call);
$prompt->expects($this->once())
->method('getTitle')
->willReturn('Test title');
$prompt->expects($this->once())
->method('getContent')
->willReturn('Test content');
$sharedPrompt = $this->createMock(UserAskAnythingPrompt::class);
$sharedUser = $this->createMock(User::class);
$sharedUser->expects($this->once())
->method('isStatusActive')
->willReturn(true);
$sharedUser->expects($this->once())
->method('getId')
->willReturn(1);
$sharedPrompt->expects($this->once())
->method('getUser')
->willReturn($sharedUser);
$sharedPrompt->expects($this->exactly(2))
->method('isRemoved')
->willReturn(false);
$sharedPrompt->expects($this->once())
->method('delete');
$this->askAnythingRepository->expects($this->once())
->method('findSharedUsersAndGroupsByPromptId')
->with(1)
->willReturn(new Collection([$sharedPrompt]));
$this->askAnythingRepository->expects($this->once())
->method('createPrompt');
$data = $this->invokePrivateMethod('recreatePromptsForUserRelations', $this->askAnythingPromptService, [$prompt]);
$this->assertEquals([[1], []], $data);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
56804
|
NULL
|
0
|
2026-05-19T08:23:08.201015+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779178988201_m1.jpg...
|
Firefox
|
NULL
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpAPPDOCKER• ₴1D SlackFileEditViewGoHistoryWindowHelpAPPDOCKER• ₴1DEV (-zsh)₴82app/Jobs/Crm/MatchActivityCrmData.phpapp/Jobs/Middleware/HandleHubspotRateLimit.phpAPP (-zst47++++++p42++++++*app/Mcp/Servers/JiminnyServer.phpapp/Mcp/Tools/GetMeTool.php157++++++•app/Models/Feature/FeatureEnum.phpapp/Services/Activity/HubSpot/ProviderResolver.php+-app/Services/Activity/HubSpot/ProviderResolverInterface.phpapp/Services/Activity/HubSpot/Providers/Provider.phpapp/Services/Activity/HubSpot/Providers/ProviderKixie.php+-app/Services/Activity/HubSpot/Providers/Provider0rum.phpapp/Services/Activity/HubSpot/Providers/ProviderTwilio.phpapp/Services/Activity/HubSpot/Providers/ProviderTwilioFlex.phpapp/Services/Activity/HubSpot/Service.phpapp/Services/Crm/Hubspot/Client.phpapp/Services/Crm/Hubspot/HubspotClientInterface.phpapp/Services/Crm/Hubspot/Pagination/HubspotPaginationService.phpapp/Services/Crm/Hubspot/Pagination/PaginationState.phpdatabase/migrations/2026_05_13_124153_create_mcp_feature_flag.phptests/Feature/Mcp/GetMeToolFeatureTest.phptests/Feature/Mcp/ListCallsToolFeatureTest.phptests/Feature/Mcp/McpTestHelpersTrait.phptests/Unit/Component/ES/ChunkSizeTest.phptests/Unit/Component/ES/Processor/DT0s/SelectionListTest.phptests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.phptests/Unit/Component/MeetingBot/Service/ParticipantMatcherTest.phptests/Unit/Exceptions/RateLimitExceptionTest.phptests/Unit/Jobs/Crm/MatchActivityCrmDataTest.phptests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.phptests/Unit/Services/Activity/HubSpot/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ClientTest.phptests/Unit/Services/Crm/Hubspot/Pagination/HubspotPaginationServiceTest.php97++++++-132++++++•15++++++21++++--2+-25++++++.140++++++•2+-19++++++50++++++-27++++++-39++++++-6856++++++-+-151++++++-109++++++-250++++++-283++++++=37 files changed, 1587 insertions(+), 344 deletions(-)create mode 100644 app/Component/ES/ChunkSize.phpcreate mode 100644 app/Jobs/Middleware/HandleHubspotRateLimit.phpcreate mode 100644 app/Mcp/Tools/GetMeTool.phpcreate mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.phpcreate mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.phpcreate mode 100644 tests/Unit/Component/ES/ChunkSizeTest.phpcreate mode 100644 tests/Unit/Exceptions/RateLimitExceptionTest.phpcreate mode 100644 tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.phplukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pullAlready up to date.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20676-delete-reSwitched to a new branch 'JY-20676-delete-report-related-objects'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20676-delete-report-related-obHomeDMsActivityFilesLaterMore> 0EDJiminny ...# Jiminny-Dg# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi...• Direct messages€. Vasil Vasilev8. Nikolay Yankov%. Galya Dimitrova. Aneliya Angelovaão Stefka Stoyanova. Stoyan Tomovd Todor Stamatov "Kd. Mario GeorgievNikolay Ivanovd. James Graham2 Stoyan TanevRo Steliyan GeorgievLukas Kovalik y... OAppsJira CloudToastSupport Daily • in 3 h 37 m100% <73• Tue 19 May 11:23:08Describe what you are looking forNikolay Yankov6 0MessagesAdd canvasO Files+Nikolay YankovYesterday ~имаше ли нещь . y-..-Lukas Kovalik 2:28 PMтрябва да си вързан към SF да работиNikolay Yankov 2:28 PMaxaaaNikolay Yankov 2:41 PMимаме approve на PRда го даваме за QA?Lukas Kovalik 2:42 PMдаNikolay Yankov 3:02 PMтестове фейлватрьннах го 2 пътиToday ~Nikolay Yankov 10:05 AM/api/v2/user/ask-anything-prompts?target=on_demandhas_reports/api/v2/user/ask-anything-prompts/3381a35f-f1a3-431d-9510-bd079cd80ed6DELETE/api/vl/activity/saved-searchMessage Nikolay Yankov...
|
NULL
|
2432208365555967643
|
NULL
|
idle
|
ocr
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpAPPDOCKER• ₴1D SlackFileEditViewGoHistoryWindowHelpAPPDOCKER• ₴1DEV (-zsh)₴82app/Jobs/Crm/MatchActivityCrmData.phpapp/Jobs/Middleware/HandleHubspotRateLimit.phpAPP (-zst47++++++p42++++++*app/Mcp/Servers/JiminnyServer.phpapp/Mcp/Tools/GetMeTool.php157++++++•app/Models/Feature/FeatureEnum.phpapp/Services/Activity/HubSpot/ProviderResolver.php+-app/Services/Activity/HubSpot/ProviderResolverInterface.phpapp/Services/Activity/HubSpot/Providers/Provider.phpapp/Services/Activity/HubSpot/Providers/ProviderKixie.php+-app/Services/Activity/HubSpot/Providers/Provider0rum.phpapp/Services/Activity/HubSpot/Providers/ProviderTwilio.phpapp/Services/Activity/HubSpot/Providers/ProviderTwilioFlex.phpapp/Services/Activity/HubSpot/Service.phpapp/Services/Crm/Hubspot/Client.phpapp/Services/Crm/Hubspot/HubspotClientInterface.phpapp/Services/Crm/Hubspot/Pagination/HubspotPaginationService.phpapp/Services/Crm/Hubspot/Pagination/PaginationState.phpdatabase/migrations/2026_05_13_124153_create_mcp_feature_flag.phptests/Feature/Mcp/GetMeToolFeatureTest.phptests/Feature/Mcp/ListCallsToolFeatureTest.phptests/Feature/Mcp/McpTestHelpersTrait.phptests/Unit/Component/ES/ChunkSizeTest.phptests/Unit/Component/ES/Processor/DT0s/SelectionListTest.phptests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.phptests/Unit/Component/MeetingBot/Service/ParticipantMatcherTest.phptests/Unit/Exceptions/RateLimitExceptionTest.phptests/Unit/Jobs/Crm/MatchActivityCrmDataTest.phptests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.phptests/Unit/Services/Activity/HubSpot/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ClientTest.phptests/Unit/Services/Crm/Hubspot/Pagination/HubspotPaginationServiceTest.php97++++++-132++++++•15++++++21++++--2+-25++++++.140++++++•2+-19++++++50++++++-27++++++-39++++++-6856++++++-+-151++++++-109++++++-250++++++-283++++++=37 files changed, 1587 insertions(+), 344 deletions(-)create mode 100644 app/Component/ES/ChunkSize.phpcreate mode 100644 app/Jobs/Middleware/HandleHubspotRateLimit.phpcreate mode 100644 app/Mcp/Tools/GetMeTool.phpcreate mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.phpcreate mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.phpcreate mode 100644 tests/Unit/Component/ES/ChunkSizeTest.phpcreate mode 100644 tests/Unit/Exceptions/RateLimitExceptionTest.phpcreate mode 100644 tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.phplukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pullAlready up to date.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20676-delete-reSwitched to a new branch 'JY-20676-delete-report-related-objects'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20676-delete-report-related-obHomeDMsActivityFilesLaterMore> 0EDJiminny ...# Jiminny-Dg# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi...• Direct messages€. Vasil Vasilev8. Nikolay Yankov%. Galya Dimitrova. Aneliya Angelovaão Stefka Stoyanova. Stoyan Tomovd Todor Stamatov "Kd. Mario GeorgievNikolay Ivanovd. James Graham2 Stoyan TanevRo Steliyan GeorgievLukas Kovalik y... OAppsJira CloudToastSupport Daily • in 3 h 37 m100% <73• Tue 19 May 11:23:08Describe what you are looking forNikolay Yankov6 0MessagesAdd canvasO Files+Nikolay YankovYesterday ~имаше ли нещь . y-..-Lukas Kovalik 2:28 PMтрябва да си вързан към SF да работиNikolay Yankov 2:28 PMaxaaaNikolay Yankov 2:41 PMимаме approve на PRда го даваме за QA?Lukas Kovalik 2:42 PMдаNikolay Yankov 3:02 PMтестове фейлватрьннах го 2 пътиToday ~Nikolay Yankov 10:05 AM/api/v2/user/ask-anything-prompts?target=on_demandhas_reports/api/v2/user/ask-anything-prompts/3381a35f-f1a3-431d-9510-bd079cd80ed6DELETE/api/vl/activity/saved-searchMessage Nikolay Yankov...
|
56802
|
NULL
|
NULL
|
NULL
|
|
56803
|
NULL
|
0
|
2026-05-19T08:22:57.354180+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779178977354_m2.jpg...
|
Firefox
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Notion CalendarVIewWindowneltrTavsco.s%9 JY-20676- Notion CalendarVIewWindowneltrTavsco.s%9 JY-20676-delete-roledey© AskAnythingPromptDto.phpD Events© AsKAnytningPromptservice.ongc Historyservice.ongD AskJiminnyAiWAWSBillingManagementu cachew countryDatabaseDatadogDatettimeDeallnsightsN DealRisks1N GlasticSearchM EloquentEncoding• EncryptionDESD Faker• FeatureFlagsD FFMpeg• FileSystem• Gong_ cuzzienutoD KeyPoints• Kiosk_ LanquageDetectionW LOCKS• MathMediapioeline2 MobileSettinas• Model2 Notification• NudgeIM ParagranhBreaker1 PartitionedCookieM PlavbackPade• PlaylistProphetM PronhetAfD ProsperWorksM Auonc© ActivityController.php© AskAnythingPromptService.phpxpip aplionpAskAnythingControlle© AskAnythingPrompt.ph© AutomatedReportsServicec) Automateakeport.pnpC AskAnythingFicelest.php© Search.phpclass AskanythingPromptservicepublic function createl$shareUsers[] = $this->userRepository->findByUuid($userforeach ($shareGroupsUuids as $groupUuid) ($shareGroupsl] = Sthis->groupRepository->findByUuid($gr$prompt = $this->askAnythingRepository->createPrompt($target,$title,$content,$shareUsers,ssharebroups.return new AskAnythingPromptDtoCsprompt->getuu1dosprompt->getlitleosprompt->gettontentor$target,$user->getUuid(),SshareGrouosUuids.$prompt->has reports,* Abaram arrau<string> Ssharelisenslluids* @param array<string> $shareGroupsUuids* @throws InvalidArgumentExceptionpublic function edit(AskAnythingPrompt $prompt,User $user,string $title,string $content,AinnalYchanoll concltttanearray ssharebroupsuu1ds): AskAnythingPromptDto 4...,167public function deletedAskAnvthingPromot SpromotUser SuserLukas Kovalik's No..A Home• No upcoming events7 View allNew page• WorkHubspot API callsS Hubspot© CRMWork KnowledgeE DSK Report 2025E DSK Report 2024€ Transactions@ Report 2023AR 2026ad laterport 2024— New agentWorkspace* Quick NoteWorkKnowledge*e Ideas@ Finance hubE Home views( Integration-appNew chat *dE Work• suppont Dally • In 3n 30m100% 2• lue Ty May 11-22:0/Month v= WorkWork• Jira ticket# Today8a Yesterd:e Date: Todav v° + FilteAa Name( Delete saved searc+ New paqeF SprintAn NameG Sprint 1 Q1@ Sprint 2 Q1Sorint 3p@ Sprint 4 Q1" Sorint 5 011 Sprint 6 Q1"Sorint7 01@ Sprint 8 Q1+ New pageDailyE TableAa Namee This moo00na0June 2026Chloe cross (Parental Leave - 256 days)(Ivelina Hristova (Parental Leave - 184 days)Andrea Zlatanova (Parental Leave - 189 days)Iliyana Netseva (PTO - 2 days)( Laura Zelinkova (PTO - 4 days)Day off for Culture and Literacy .Kara Jones (Unpaid Leave of Absence - 9 days)12 morechioe cross (Parental Leave - 256 days)Ivelina Hristova (Parental Leave - 184 days)Andrea Zlatanova (Parental Leave - 189 davs)Kara Jones (Unpaid Leave of Absence - 9 days)Calum Scott (PTO - 2 days(Nick Yankov (PTO - 1 day)09:45 Daily - Platform15:00 suppor DallyChioe Cross (Parental Leave - 256 days)Ivelina Hristova (Parental Leave - 184 davs)Platform Office Day15:00 Preparation for Refinement15:00 Support Daily16:00 [Platforml Refinement15:00 support DallyChloe Cross (Parental Leave - 256 davs)Andrea Zlatanova (Parental Leave - 189 days)Stoyan Tomov (PTO - 4.5 days)15:00 Preparation for Refinement09:45 Daily - Platform15:00 Support DailyIvelina Hristova (Parental Leave - 184 days)Andros Zlatanovs (Darontal loava- 190 dove)15:00 Preparation for Refinement(James Graham (PTO - 4 days)Platform Office Dav16:00 (Platform] Refinement •2 moreChloe Cross (Parental Leave - 256 days)Ivelina Hristova (Parental Leave - 184 days)Andrea Zlatanova (Parental Leave - 189 days)Mario Georaiev (PTO - 6 davs)09:45 Daily - Platform15:00 Preparation for Refinement3 more15:00 Support DailyWedk(10:00 [Platform] Planning I Sessi.. 09:45 Daily - Platform09:45 Daily - Platform15:00 Support Daily17:00 Al chapter(10:00 [Platform) Planning I Sessi...10:00 Mid Sprint Check-in15:00 suppon Dally16:00 Sprint Review09:45 Daily - Platform15:00 Support Dailv|10:00 [Platforml Plannina I Sessi..2 more09:45 Daily - Platform2 more15:00 support Dail09:45 Daily - Platform15:00 support Dally17:30 Lukas/Stefka 12109:45 Daily - Platform15:00 support Dally09:45 Daily - Platform15:00 Support Dailv17:30 Lukas/Stefka 121Rebecca Butler (PTO - 1 day)09:45 Daily - Platform15:00 Support Daily09:45 Daily - Platform10:00 Jiminny Tech Day10:30 Backend Chapter2 moreStefka Stoyanova (PTO - 1 day)09:45 Daily - PlatformMario Georgiev (PTO - 6 days)Georgi Bayraktarov (PTO - 0.5 d...15:00 Support DailyGeorai Bavraktaroy (PTO - 1.5 dav)09:45 Daily - Platform2 more09:45 Daily - Platform15:00 Support DailySviatok svätého Cyrila a Met...
|
NULL
|
-2525445104651332524
|
NULL
|
idle
|
ocr
|
NULL
|
Notion CalendarVIewWindowneltrTavsco.s%9 JY-20676- Notion CalendarVIewWindowneltrTavsco.s%9 JY-20676-delete-roledey© AskAnythingPromptDto.phpD Events© AsKAnytningPromptservice.ongc Historyservice.ongD AskJiminnyAiWAWSBillingManagementu cachew countryDatabaseDatadogDatettimeDeallnsightsN DealRisks1N GlasticSearchM EloquentEncoding• EncryptionDESD Faker• FeatureFlagsD FFMpeg• FileSystem• Gong_ cuzzienutoD KeyPoints• Kiosk_ LanquageDetectionW LOCKS• MathMediapioeline2 MobileSettinas• Model2 Notification• NudgeIM ParagranhBreaker1 PartitionedCookieM PlavbackPade• PlaylistProphetM PronhetAfD ProsperWorksM Auonc© ActivityController.php© AskAnythingPromptService.phpxpip aplionpAskAnythingControlle© AskAnythingPrompt.ph© AutomatedReportsServicec) Automateakeport.pnpC AskAnythingFicelest.php© Search.phpclass AskanythingPromptservicepublic function createl$shareUsers[] = $this->userRepository->findByUuid($userforeach ($shareGroupsUuids as $groupUuid) ($shareGroupsl] = Sthis->groupRepository->findByUuid($gr$prompt = $this->askAnythingRepository->createPrompt($target,$title,$content,$shareUsers,ssharebroups.return new AskAnythingPromptDtoCsprompt->getuu1dosprompt->getlitleosprompt->gettontentor$target,$user->getUuid(),SshareGrouosUuids.$prompt->has reports,* Abaram arrau<string> Ssharelisenslluids* @param array<string> $shareGroupsUuids* @throws InvalidArgumentExceptionpublic function edit(AskAnythingPrompt $prompt,User $user,string $title,string $content,AinnalYchanoll concltttanearray ssharebroupsuu1ds): AskAnythingPromptDto 4...,167public function deletedAskAnvthingPromot SpromotUser SuserLukas Kovalik's No..A Home• No upcoming events7 View allNew page• WorkHubspot API callsS Hubspot© CRMWork KnowledgeE DSK Report 2025E DSK Report 2024€ Transactions@ Report 2023AR 2026ad laterport 2024— New agentWorkspace* Quick NoteWorkKnowledge*e Ideas@ Finance hubE Home views( Integration-appNew chat *dE Work• suppont Dally • In 3n 30m100% 2• lue Ty May 11-22:0/Month v= WorkWork• Jira ticket# Today8a Yesterd:e Date: Todav v° + FilteAa Name( Delete saved searc+ New paqeF SprintAn NameG Sprint 1 Q1@ Sprint 2 Q1Sorint 3p@ Sprint 4 Q1" Sorint 5 011 Sprint 6 Q1"Sorint7 01@ Sprint 8 Q1+ New pageDailyE TableAa Namee This moo00na0June 2026Chloe cross (Parental Leave - 256 days)(Ivelina Hristova (Parental Leave - 184 days)Andrea Zlatanova (Parental Leave - 189 days)Iliyana Netseva (PTO - 2 days)( Laura Zelinkova (PTO - 4 days)Day off for Culture and Literacy .Kara Jones (Unpaid Leave of Absence - 9 days)12 morechioe cross (Parental Leave - 256 days)Ivelina Hristova (Parental Leave - 184 days)Andrea Zlatanova (Parental Leave - 189 davs)Kara Jones (Unpaid Leave of Absence - 9 days)Calum Scott (PTO - 2 days(Nick Yankov (PTO - 1 day)09:45 Daily - Platform15:00 suppor DallyChioe Cross (Parental Leave - 256 days)Ivelina Hristova (Parental Leave - 184 davs)Platform Office Day15:00 Preparation for Refinement15:00 Support Daily16:00 [Platforml Refinement15:00 support DallyChloe Cross (Parental Leave - 256 davs)Andrea Zlatanova (Parental Leave - 189 days)Stoyan Tomov (PTO - 4.5 days)15:00 Preparation for Refinement09:45 Daily - Platform15:00 Support DailyIvelina Hristova (Parental Leave - 184 days)Andros Zlatanovs (Darontal loava- 190 dove)15:00 Preparation for Refinement(James Graham (PTO - 4 days)Platform Office Dav16:00 (Platform] Refinement •2 moreChloe Cross (Parental Leave - 256 days)Ivelina Hristova (Parental Leave - 184 days)Andrea Zlatanova (Parental Leave - 189 days)Mario Georaiev (PTO - 6 davs)09:45 Daily - Platform15:00 Preparation for Refinement3 more15:00 Support DailyWedk(10:00 [Platform] Planning I Sessi.. 09:45 Daily - Platform09:45 Daily - Platform15:00 Support Daily17:00 Al chapter(10:00 [Platform) Planning I Sessi...10:00 Mid Sprint Check-in15:00 suppon Dally16:00 Sprint Review09:45 Daily - Platform15:00 Support Dailv|10:00 [Platforml Plannina I Sessi..2 more09:45 Daily - Platform2 more15:00 support Dail09:45 Daily - Platform15:00 support Dally17:30 Lukas/Stefka 12109:45 Daily - Platform15:00 support Dally09:45 Daily - Platform15:00 Support Dailv17:30 Lukas/Stefka 121Rebecca Butler (PTO - 1 day)09:45 Daily - Platform15:00 Support Daily09:45 Daily - Platform10:00 Jiminny Tech Day10:30 Backend Chapter2 moreStefka Stoyanova (PTO - 1 day)09:45 Daily - PlatformMario Georgiev (PTO - 6 days)Georgi Bayraktarov (PTO - 0.5 d...15:00 Support DailyGeorai Bavraktaroy (PTO - 1.5 dav)09:45 Daily - Platform2 more09:45 Daily - Platform15:00 Support DailySviatok svätého Cyrila a Met...
|
56801
|
NULL
|
NULL
|
NULL
|
|
56732
|
NULL
|
0
|
2026-05-19T08:18:05.253779+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779178685253_m2.jpg...
|
PhpStorm
|
faVsco.js – AskJiminnyReportsController.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20676-delete-report-re Project: faVsco.js, menu
JY-20676-delete-report-related-objects, 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
9
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\API\V2;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Jiminny\Exceptions\InvalidArgumentException;
use Jiminny\Exceptions\ModelNotFoundException;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Response;
use Throwable;
class AskJiminnyReportsController extends Controller
{
public function __construct(
private readonly AutomatedReportsService $automatedReportsService,
private readonly LoggerInterface $logger,
) {
}
private function isNotOwnedByUser(AutomatedReport $report, User $user): bool
{
return $report->getTeamId() !== $user->getTeamId()
|| $report->getAttribute('created_by') !== $user->getId();
}
public function getFormData(Request $request, ?string $uuid = null): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $uuid ? $this->automatedReportsService->getReport($uuid) : null;
return new JsonResponse(
$this->automatedReportsService->getAskJiminnyReportFormData($user, $report)
);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to fetch Ask Jiminny report form data', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to fetch form data'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Create a new Ask Jiminny report.
*/
public function create(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$data = $this->automatedReportsService->createAskJiminnyReport($request->all(), $user);
return new JsonResponse($data);
} catch (InvalidArgumentException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);
} catch (Throwable $e) {
$this->logger->error('Failed to create Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse(
['error' => 'Failed to create report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Update an existing Ask Jiminny report.
*/
public function update(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$data = $this->automatedReportsService->updateAskJiminnyReport($report, $request->all(), $user);
return new JsonResponse($data);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (InvalidArgumentException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);
} catch (Throwable $e) {
$this->logger->error('Failed to update Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to update report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Toggle Ask Jiminny report status (enable/disable).
*/
public function toggleStatus(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$enabled = (bool) $request->input('enabled');
if ($enabled && $report->isAskJiminnyReport()) {
if ($report->getActivitySearchId() === null || $report->getAskAnythingPromptId() === null) {
return new JsonResponse(
['error' => 'Cannot enable report with missing saved search or prompt'],
Response::HTTP_UNPROCESSABLE_ENTITY
);
}
}
$data = $this->automatedReportsService->updateAskJiminnyReportStatus(
$report,
$enabled,
);
return new JsonResponse($data);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to toggle Ask Jiminny report status', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to toggle report status'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* List all Ask Jiminny reports.
*/
public function list(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$sortColumn = $request->input('sort_column', 'created_at');
$sortDirection = $request->input('sort_direction', 'desc');
$data = $this->automatedReportsService->listAskJiminnyReports($user, $sortColumn, $sortDirection);
return new JsonResponse($data);
} catch (Throwable $e) {
$this->logger->error('Failed to list Ask Jiminny reports', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse(
['error' => 'Failed to fetch reports'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Get a single Ask Jiminny report.
*/
public function get(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
return new JsonResponse($this->automatedReportsService->get($uuid));
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to get Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to fetch report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
public function getReportsCount(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$resultsCount = $this->automatedReportsService->getReportResults($report)->count();
return new JsonResponse(['count' => $resultsCount]);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to count report results', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'report_uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to count report results'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Delete an Ask Jiminny report.
*/
public function delete(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
if ($request->boolean('delete_generated_reports')) {
$this->automatedReportsService->deleteReportResults($uuid);
}
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$this->automatedReportsService->delete($uuid);
return new JsonResponse(null, Response::HTTP_NO_CONTENT);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to delete Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to delete report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
public function getFilters(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$filters = $this->automatedReportsService->getAskJiminnyReportFilters($user);
return new JsonResponse(['filters' => $filters]);
} catch (Throwable $e) {
$this->logger->error('Failed to fetch Ask Jiminny report filters', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse(
['error' => 'Failed to fetch filters'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
}...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20676-delete-report-related-objects, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.098071806,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20676-delete-report-related-objects","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":"9","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.007978723,"height":0.0},"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.00731383,"height":0.0},"on_screen":false,"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.27027926,"top":1.0,"width":0.006981383,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Http\\Controllers\\API\\V2;\n\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Controller;\nuse Jiminny\\Exceptions\\InvalidArgumentException;\nuse Jiminny\\Exceptions\\ModelNotFoundException;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Psr\\Log\\LoggerInterface;\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Throwable;\n\nclass AskJiminnyReportsController extends Controller\n{\n public function __construct(\n private readonly AutomatedReportsService $automatedReportsService,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n private function isNotOwnedByUser(AutomatedReport $report, User $user): bool\n {\n return $report->getTeamId() !== $user->getTeamId()\n || $report->getAttribute('created_by') !== $user->getId();\n }\n\n public function getFormData(Request $request, ?string $uuid = null): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $uuid ? $this->automatedReportsService->getReport($uuid) : null;\n\n return new JsonResponse(\n $this->automatedReportsService->getAskJiminnyReportFormData($user, $report)\n );\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to fetch Ask Jiminny report form data', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch form data'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Create a new Ask Jiminny report.\n */\n public function create(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $data = $this->automatedReportsService->createAskJiminnyReport($request->all(), $user);\n\n return new JsonResponse($data);\n } catch (InvalidArgumentException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);\n } catch (Throwable $e) {\n $this->logger->error('Failed to create Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to create report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Update an existing Ask Jiminny report.\n */\n public function update(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $data = $this->automatedReportsService->updateAskJiminnyReport($report, $request->all(), $user);\n\n return new JsonResponse($data);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (InvalidArgumentException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);\n } catch (Throwable $e) {\n $this->logger->error('Failed to update Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to update report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Toggle Ask Jiminny report status (enable/disable).\n */\n public function toggleStatus(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $enabled = (bool) $request->input('enabled');\n\n if ($enabled && $report->isAskJiminnyReport()) {\n if ($report->getActivitySearchId() === null || $report->getAskAnythingPromptId() === null) {\n return new JsonResponse(\n ['error' => 'Cannot enable report with missing saved search or prompt'],\n Response::HTTP_UNPROCESSABLE_ENTITY\n );\n }\n }\n\n $data = $this->automatedReportsService->updateAskJiminnyReportStatus(\n $report,\n $enabled,\n );\n\n return new JsonResponse($data);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to toggle Ask Jiminny report status', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to toggle report status'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * List all Ask Jiminny reports.\n */\n public function list(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $sortColumn = $request->input('sort_column', 'created_at');\n $sortDirection = $request->input('sort_direction', 'desc');\n\n $data = $this->automatedReportsService->listAskJiminnyReports($user, $sortColumn, $sortDirection);\n\n return new JsonResponse($data);\n } catch (Throwable $e) {\n $this->logger->error('Failed to list Ask Jiminny reports', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch reports'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Get a single Ask Jiminny report.\n */\n public function get(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n return new JsonResponse($this->automatedReportsService->get($uuid));\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to get Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n public function getReportsCount(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $resultsCount = $this->automatedReportsService->getReportResults($report)->count();\n\n return new JsonResponse(['count' => $resultsCount]);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to count report results', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'report_uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to count report results'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Delete an Ask Jiminny report.\n */\n public function delete(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n if ($request->boolean('delete_generated_reports')) {\n $this->automatedReportsService->deleteReportResults($uuid);\n }\n\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $this->automatedReportsService->delete($uuid);\n\n return new JsonResponse(null, Response::HTTP_NO_CONTENT);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to delete Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to delete report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n public function getFilters(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $filters = $this->automatedReportsService->getAskJiminnyReportFilters($user);\n\n return new JsonResponse(['filters' => $filters]);\n } catch (Throwable $e) {\n $this->logger->error('Failed to fetch Ask Jiminny report filters', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch filters'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n}","depth":4,"bounds":{"left":0.15990691,"top":0.12210695,"width":0.2945479,"height":0.87789303},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Http\\Controllers\\API\\V2;\n\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Controller;\nuse Jiminny\\Exceptions\\InvalidArgumentException;\nuse Jiminny\\Exceptions\\ModelNotFoundException;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Psr\\Log\\LoggerInterface;\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Throwable;\n\nclass AskJiminnyReportsController extends Controller\n{\n public function __construct(\n private readonly AutomatedReportsService $automatedReportsService,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n private function isNotOwnedByUser(AutomatedReport $report, User $user): bool\n {\n return $report->getTeamId() !== $user->getTeamId()\n || $report->getAttribute('created_by') !== $user->getId();\n }\n\n public function getFormData(Request $request, ?string $uuid = null): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $uuid ? $this->automatedReportsService->getReport($uuid) : null;\n\n return new JsonResponse(\n $this->automatedReportsService->getAskJiminnyReportFormData($user, $report)\n );\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to fetch Ask Jiminny report form data', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch form data'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Create a new Ask Jiminny report.\n */\n public function create(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $data = $this->automatedReportsService->createAskJiminnyReport($request->all(), $user);\n\n return new JsonResponse($data);\n } catch (InvalidArgumentException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);\n } catch (Throwable $e) {\n $this->logger->error('Failed to create Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to create report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Update an existing Ask Jiminny report.\n */\n public function update(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $data = $this->automatedReportsService->updateAskJiminnyReport($report, $request->all(), $user);\n\n return new JsonResponse($data);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (InvalidArgumentException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);\n } catch (Throwable $e) {\n $this->logger->error('Failed to update Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to update report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Toggle Ask Jiminny report status (enable/disable).\n */\n public function toggleStatus(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $enabled = (bool) $request->input('enabled');\n\n if ($enabled && $report->isAskJiminnyReport()) {\n if ($report->getActivitySearchId() === null || $report->getAskAnythingPromptId() === null) {\n return new JsonResponse(\n ['error' => 'Cannot enable report with missing saved search or prompt'],\n Response::HTTP_UNPROCESSABLE_ENTITY\n );\n }\n }\n\n $data = $this->automatedReportsService->updateAskJiminnyReportStatus(\n $report,\n $enabled,\n );\n\n return new JsonResponse($data);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to toggle Ask Jiminny report status', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to toggle report status'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * List all Ask Jiminny reports.\n */\n public function list(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $sortColumn = $request->input('sort_column', 'created_at');\n $sortDirection = $request->input('sort_direction', 'desc');\n\n $data = $this->automatedReportsService->listAskJiminnyReports($user, $sortColumn, $sortDirection);\n\n return new JsonResponse($data);\n } catch (Throwable $e) {\n $this->logger->error('Failed to list Ask Jiminny reports', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch reports'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Get a single Ask Jiminny report.\n */\n public function get(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n return new JsonResponse($this->automatedReportsService->get($uuid));\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to get Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n public function getReportsCount(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $resultsCount = $this->automatedReportsService->getReportResults($report)->count();\n\n return new JsonResponse(['count' => $resultsCount]);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to count report results', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'report_uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to count report results'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Delete an Ask Jiminny report.\n */\n public function delete(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n if ($request->boolean('delete_generated_reports')) {\n $this->automatedReportsService->deleteReportResults($uuid);\n }\n\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $this->automatedReportsService->delete($uuid);\n\n return new JsonResponse(null, Response::HTTP_NO_CONTENT);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to delete Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to delete report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n public function getFilters(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $filters = $this->automatedReportsService->getAskJiminnyReportFilters($user);\n\n return new JsonResponse(['filters' => $filters]);\n } catch (Throwable $e) {\n $this->logger->error('Failed to fetch Ask Jiminny report filters', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch filters'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false}]...
|
8074039287220648480
|
-6985853857695815097
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20676-delete-report-re Project: faVsco.js, menu
JY-20676-delete-report-related-objects, 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
9
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\API\V2;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Jiminny\Exceptions\InvalidArgumentException;
use Jiminny\Exceptions\ModelNotFoundException;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Response;
use Throwable;
class AskJiminnyReportsController extends Controller
{
public function __construct(
private readonly AutomatedReportsService $automatedReportsService,
private readonly LoggerInterface $logger,
) {
}
private function isNotOwnedByUser(AutomatedReport $report, User $user): bool
{
return $report->getTeamId() !== $user->getTeamId()
|| $report->getAttribute('created_by') !== $user->getId();
}
public function getFormData(Request $request, ?string $uuid = null): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $uuid ? $this->automatedReportsService->getReport($uuid) : null;
return new JsonResponse(
$this->automatedReportsService->getAskJiminnyReportFormData($user, $report)
);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to fetch Ask Jiminny report form data', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to fetch form data'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Create a new Ask Jiminny report.
*/
public function create(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$data = $this->automatedReportsService->createAskJiminnyReport($request->all(), $user);
return new JsonResponse($data);
} catch (InvalidArgumentException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);
} catch (Throwable $e) {
$this->logger->error('Failed to create Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse(
['error' => 'Failed to create report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Update an existing Ask Jiminny report.
*/
public function update(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$data = $this->automatedReportsService->updateAskJiminnyReport($report, $request->all(), $user);
return new JsonResponse($data);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (InvalidArgumentException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);
} catch (Throwable $e) {
$this->logger->error('Failed to update Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to update report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Toggle Ask Jiminny report status (enable/disable).
*/
public function toggleStatus(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$enabled = (bool) $request->input('enabled');
if ($enabled && $report->isAskJiminnyReport()) {
if ($report->getActivitySearchId() === null || $report->getAskAnythingPromptId() === null) {
return new JsonResponse(
['error' => 'Cannot enable report with missing saved search or prompt'],
Response::HTTP_UNPROCESSABLE_ENTITY
);
}
}
$data = $this->automatedReportsService->updateAskJiminnyReportStatus(
$report,
$enabled,
);
return new JsonResponse($data);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to toggle Ask Jiminny report status', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to toggle report status'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* List all Ask Jiminny reports.
*/
public function list(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$sortColumn = $request->input('sort_column', 'created_at');
$sortDirection = $request->input('sort_direction', 'desc');
$data = $this->automatedReportsService->listAskJiminnyReports($user, $sortColumn, $sortDirection);
return new JsonResponse($data);
} catch (Throwable $e) {
$this->logger->error('Failed to list Ask Jiminny reports', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse(
['error' => 'Failed to fetch reports'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Get a single Ask Jiminny report.
*/
public function get(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
return new JsonResponse($this->automatedReportsService->get($uuid));
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to get Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to fetch report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
public function getReportsCount(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$resultsCount = $this->automatedReportsService->getReportResults($report)->count();
return new JsonResponse(['count' => $resultsCount]);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to count report results', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'report_uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to count report results'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Delete an Ask Jiminny report.
*/
public function delete(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
if ($request->boolean('delete_generated_reports')) {
$this->automatedReportsService->deleteReportResults($uuid);
}
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$this->automatedReportsService->delete($uuid);
return new JsonResponse(null, Response::HTTP_NO_CONTENT);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to delete Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to delete report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
public function getFilters(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$filters = $this->automatedReportsService->getAskJiminnyReportFilters($user);
return new JsonResponse(['filters' => $filters]);
} catch (Throwable $e) {
$this->logger->error('Failed to fetch Ask Jiminny report filters', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse(
['error' => 'Failed to fetch filters'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
}...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
56731
|
NULL
|
0
|
2026-05-19T08:18:05.253749+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779178685253_m1.jpg...
|
PhpStorm
|
faVsco.js – AskJiminnyReportsController.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20676-delete-report-re Project: faVsco.js, menu
JY-20676-delete-report-related-objects, 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
9
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\API\V2;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Jiminny\Exceptions\InvalidArgumentException;
use Jiminny\Exceptions\ModelNotFoundException;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Response;
use Throwable;
class AskJiminnyReportsController extends Controller
{
public function __construct(
private readonly AutomatedReportsService $automatedReportsService,
private readonly LoggerInterface $logger,
) {
}
private function isNotOwnedByUser(AutomatedReport $report, User $user): bool
{
return $report->getTeamId() !== $user->getTeamId()
|| $report->getAttribute('created_by') !== $user->getId();
}
public function getFormData(Request $request, ?string $uuid = null): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $uuid ? $this->automatedReportsService->getReport($uuid) : null;
return new JsonResponse(
$this->automatedReportsService->getAskJiminnyReportFormData($user, $report)
);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to fetch Ask Jiminny report form data', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to fetch form data'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Create a new Ask Jiminny report.
*/
public function create(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$data = $this->automatedReportsService->createAskJiminnyReport($request->all(), $user);
return new JsonResponse($data);
} catch (InvalidArgumentException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);
} catch (Throwable $e) {
$this->logger->error('Failed to create Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse(
['error' => 'Failed to create report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Update an existing Ask Jiminny report.
*/
public function update(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$data = $this->automatedReportsService->updateAskJiminnyReport($report, $request->all(), $user);
return new JsonResponse($data);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (InvalidArgumentException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);
} catch (Throwable $e) {
$this->logger->error('Failed to update Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to update report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Toggle Ask Jiminny report status (enable/disable).
*/
public function toggleStatus(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$enabled = (bool) $request->input('enabled');
if ($enabled && $report->isAskJiminnyReport()) {
if ($report->getActivitySearchId() === null || $report->getAskAnythingPromptId() === null) {
return new JsonResponse(
['error' => 'Cannot enable report with missing saved search or prompt'],
Response::HTTP_UNPROCESSABLE_ENTITY
);
}
}
$data = $this->automatedReportsService->updateAskJiminnyReportStatus(
$report,
$enabled,
);
return new JsonResponse($data);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to toggle Ask Jiminny report status', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to toggle report status'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* List all Ask Jiminny reports.
*/
public function list(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$sortColumn = $request->input('sort_column', 'created_at');
$sortDirection = $request->input('sort_direction', 'desc');
$data = $this->automatedReportsService->listAskJiminnyReports($user, $sortColumn, $sortDirection);
return new JsonResponse($data);
} catch (Throwable $e) {
$this->logger->error('Failed to list Ask Jiminny reports', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse(
['error' => 'Failed to fetch reports'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Get a single Ask Jiminny report.
*/
public function get(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
return new JsonResponse($this->automatedReportsService->get($uuid));
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to get Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to fetch report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
public function getReportsCount(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$resultsCount = $this->automatedReportsService->getReportResults($report)->count();
return new JsonResponse(['count' => $resultsCount]);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to count report results', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'report_uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to count report results'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Delete an Ask Jiminny report.
*/
public function delete(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
if ($request->boolean('delete_generated_reports')) {
$this->automatedReportsService->deleteReportResults($uuid);
}
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$this->automatedReportsService->delete($uuid);
return new JsonResponse(null, Response::HTTP_NO_CONTENT);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to delete Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to delete report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
public function getFilters(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$filters = $this->automatedReportsService->getAskJiminnyReportFilters($user);
return new JsonResponse(['filters' => $filters]);
} catch (Throwable $e) {
$this->logger->error('Failed to fetch Ask Jiminny report filters', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse(
['error' => 'Failed to fetch filters'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20676-delete-report-related-objects, menu","depth":5,"on_screen":true,"help_text":"Git Branch: JY-20676-delete-report-related-objects","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":"9","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.016666668,"height":0.02111111},"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.025555555},"on_screen":false,"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.0,"top":0.0,"width":0.014583333,"height":0.025555555},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Http\\Controllers\\API\\V2;\n\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Controller;\nuse Jiminny\\Exceptions\\InvalidArgumentException;\nuse Jiminny\\Exceptions\\ModelNotFoundException;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Psr\\Log\\LoggerInterface;\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Throwable;\n\nclass AskJiminnyReportsController extends Controller\n{\n public function __construct(\n private readonly AutomatedReportsService $automatedReportsService,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n private function isNotOwnedByUser(AutomatedReport $report, User $user): bool\n {\n return $report->getTeamId() !== $user->getTeamId()\n || $report->getAttribute('created_by') !== $user->getId();\n }\n\n public function getFormData(Request $request, ?string $uuid = null): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $uuid ? $this->automatedReportsService->getReport($uuid) : null;\n\n return new JsonResponse(\n $this->automatedReportsService->getAskJiminnyReportFormData($user, $report)\n );\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to fetch Ask Jiminny report form data', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch form data'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Create a new Ask Jiminny report.\n */\n public function create(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $data = $this->automatedReportsService->createAskJiminnyReport($request->all(), $user);\n\n return new JsonResponse($data);\n } catch (InvalidArgumentException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);\n } catch (Throwable $e) {\n $this->logger->error('Failed to create Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to create report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Update an existing Ask Jiminny report.\n */\n public function update(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $data = $this->automatedReportsService->updateAskJiminnyReport($report, $request->all(), $user);\n\n return new JsonResponse($data);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (InvalidArgumentException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);\n } catch (Throwable $e) {\n $this->logger->error('Failed to update Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to update report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Toggle Ask Jiminny report status (enable/disable).\n */\n public function toggleStatus(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $enabled = (bool) $request->input('enabled');\n\n if ($enabled && $report->isAskJiminnyReport()) {\n if ($report->getActivitySearchId() === null || $report->getAskAnythingPromptId() === null) {\n return new JsonResponse(\n ['error' => 'Cannot enable report with missing saved search or prompt'],\n Response::HTTP_UNPROCESSABLE_ENTITY\n );\n }\n }\n\n $data = $this->automatedReportsService->updateAskJiminnyReportStatus(\n $report,\n $enabled,\n );\n\n return new JsonResponse($data);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to toggle Ask Jiminny report status', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to toggle report status'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * List all Ask Jiminny reports.\n */\n public function list(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $sortColumn = $request->input('sort_column', 'created_at');\n $sortDirection = $request->input('sort_direction', 'desc');\n\n $data = $this->automatedReportsService->listAskJiminnyReports($user, $sortColumn, $sortDirection);\n\n return new JsonResponse($data);\n } catch (Throwable $e) {\n $this->logger->error('Failed to list Ask Jiminny reports', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch reports'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Get a single Ask Jiminny report.\n */\n public function get(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n return new JsonResponse($this->automatedReportsService->get($uuid));\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to get Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n public function getReportsCount(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $resultsCount = $this->automatedReportsService->getReportResults($report)->count();\n\n return new JsonResponse(['count' => $resultsCount]);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to count report results', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'report_uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to count report results'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Delete an Ask Jiminny report.\n */\n public function delete(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n if ($request->boolean('delete_generated_reports')) {\n $this->automatedReportsService->deleteReportResults($uuid);\n }\n\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $this->automatedReportsService->delete($uuid);\n\n return new JsonResponse(null, Response::HTTP_NO_CONTENT);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to delete Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to delete report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n public function getFilters(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $filters = $this->automatedReportsService->getAskJiminnyReportFilters($user);\n\n return new JsonResponse(['filters' => $filters]);\n } catch (Throwable $e) {\n $this->logger->error('Failed to fetch Ask Jiminny report filters', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch filters'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Http\\Controllers\\API\\V2;\n\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Controller;\nuse Jiminny\\Exceptions\\InvalidArgumentException;\nuse Jiminny\\Exceptions\\ModelNotFoundException;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Psr\\Log\\LoggerInterface;\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Throwable;\n\nclass AskJiminnyReportsController extends Controller\n{\n public function __construct(\n private readonly AutomatedReportsService $automatedReportsService,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n private function isNotOwnedByUser(AutomatedReport $report, User $user): bool\n {\n return $report->getTeamId() !== $user->getTeamId()\n || $report->getAttribute('created_by') !== $user->getId();\n }\n\n public function getFormData(Request $request, ?string $uuid = null): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $uuid ? $this->automatedReportsService->getReport($uuid) : null;\n\n return new JsonResponse(\n $this->automatedReportsService->getAskJiminnyReportFormData($user, $report)\n );\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to fetch Ask Jiminny report form data', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch form data'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Create a new Ask Jiminny report.\n */\n public function create(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $data = $this->automatedReportsService->createAskJiminnyReport($request->all(), $user);\n\n return new JsonResponse($data);\n } catch (InvalidArgumentException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);\n } catch (Throwable $e) {\n $this->logger->error('Failed to create Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to create report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Update an existing Ask Jiminny report.\n */\n public function update(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $data = $this->automatedReportsService->updateAskJiminnyReport($report, $request->all(), $user);\n\n return new JsonResponse($data);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (InvalidArgumentException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);\n } catch (Throwable $e) {\n $this->logger->error('Failed to update Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to update report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Toggle Ask Jiminny report status (enable/disable).\n */\n public function toggleStatus(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $enabled = (bool) $request->input('enabled');\n\n if ($enabled && $report->isAskJiminnyReport()) {\n if ($report->getActivitySearchId() === null || $report->getAskAnythingPromptId() === null) {\n return new JsonResponse(\n ['error' => 'Cannot enable report with missing saved search or prompt'],\n Response::HTTP_UNPROCESSABLE_ENTITY\n );\n }\n }\n\n $data = $this->automatedReportsService->updateAskJiminnyReportStatus(\n $report,\n $enabled,\n );\n\n return new JsonResponse($data);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to toggle Ask Jiminny report status', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to toggle report status'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * List all Ask Jiminny reports.\n */\n public function list(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $sortColumn = $request->input('sort_column', 'created_at');\n $sortDirection = $request->input('sort_direction', 'desc');\n\n $data = $this->automatedReportsService->listAskJiminnyReports($user, $sortColumn, $sortDirection);\n\n return new JsonResponse($data);\n } catch (Throwable $e) {\n $this->logger->error('Failed to list Ask Jiminny reports', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch reports'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Get a single Ask Jiminny report.\n */\n public function get(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n return new JsonResponse($this->automatedReportsService->get($uuid));\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to get Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n public function getReportsCount(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $resultsCount = $this->automatedReportsService->getReportResults($report)->count();\n\n return new JsonResponse(['count' => $resultsCount]);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to count report results', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'report_uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to count report results'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Delete an Ask Jiminny report.\n */\n public function delete(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n if ($request->boolean('delete_generated_reports')) {\n $this->automatedReportsService->deleteReportResults($uuid);\n }\n\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $this->automatedReportsService->delete($uuid);\n\n return new JsonResponse(null, Response::HTTP_NO_CONTENT);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to delete Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to delete report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n public function getFilters(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $filters = $this->automatedReportsService->getAskJiminnyReportFilters($user);\n\n return new JsonResponse(['filters' => $filters]);\n } catch (Throwable $e) {\n $this->logger->error('Failed to fetch Ask Jiminny report filters', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch filters'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-3318323997297636737
|
-6976847208096224411
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20676-delete-report-re Project: faVsco.js, menu
JY-20676-delete-report-related-objects, 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
9
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\API\V2;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Jiminny\Exceptions\InvalidArgumentException;
use Jiminny\Exceptions\ModelNotFoundException;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Response;
use Throwable;
class AskJiminnyReportsController extends Controller
{
public function __construct(
private readonly AutomatedReportsService $automatedReportsService,
private readonly LoggerInterface $logger,
) {
}
private function isNotOwnedByUser(AutomatedReport $report, User $user): bool
{
return $report->getTeamId() !== $user->getTeamId()
|| $report->getAttribute('created_by') !== $user->getId();
}
public function getFormData(Request $request, ?string $uuid = null): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $uuid ? $this->automatedReportsService->getReport($uuid) : null;
return new JsonResponse(
$this->automatedReportsService->getAskJiminnyReportFormData($user, $report)
);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to fetch Ask Jiminny report form data', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to fetch form data'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Create a new Ask Jiminny report.
*/
public function create(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$data = $this->automatedReportsService->createAskJiminnyReport($request->all(), $user);
return new JsonResponse($data);
} catch (InvalidArgumentException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);
} catch (Throwable $e) {
$this->logger->error('Failed to create Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse(
['error' => 'Failed to create report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Update an existing Ask Jiminny report.
*/
public function update(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$data = $this->automatedReportsService->updateAskJiminnyReport($report, $request->all(), $user);
return new JsonResponse($data);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (InvalidArgumentException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);
} catch (Throwable $e) {
$this->logger->error('Failed to update Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to update report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Toggle Ask Jiminny report status (enable/disable).
*/
public function toggleStatus(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$enabled = (bool) $request->input('enabled');
if ($enabled && $report->isAskJiminnyReport()) {
if ($report->getActivitySearchId() === null || $report->getAskAnythingPromptId() === null) {
return new JsonResponse(
['error' => 'Cannot enable report with missing saved search or prompt'],
Response::HTTP_UNPROCESSABLE_ENTITY
);
}
}
$data = $this->automatedReportsService->updateAskJiminnyReportStatus(
$report,
$enabled,
);
return new JsonResponse($data);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to toggle Ask Jiminny report status', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to toggle report status'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* List all Ask Jiminny reports.
*/
public function list(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$sortColumn = $request->input('sort_column', 'created_at');
$sortDirection = $request->input('sort_direction', 'desc');
$data = $this->automatedReportsService->listAskJiminnyReports($user, $sortColumn, $sortDirection);
return new JsonResponse($data);
} catch (Throwable $e) {
$this->logger->error('Failed to list Ask Jiminny reports', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse(
['error' => 'Failed to fetch reports'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Get a single Ask Jiminny report.
*/
public function get(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
return new JsonResponse($this->automatedReportsService->get($uuid));
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to get Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to fetch report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
public function getReportsCount(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$resultsCount = $this->automatedReportsService->getReportResults($report)->count();
return new JsonResponse(['count' => $resultsCount]);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to count report results', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'report_uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to count report results'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Delete an Ask Jiminny report.
*/
public function delete(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
if ($request->boolean('delete_generated_reports')) {
$this->automatedReportsService->deleteReportResults($uuid);
}
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$this->automatedReportsService->delete($uuid);
return new JsonResponse(null, Response::HTTP_NO_CONTENT);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to delete Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to delete report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
public function getFilters(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$filters = $this->automatedReportsService->getAskJiminnyReportFilters($user);
return new JsonResponse(['filters' => $filters]);
} catch (Throwable $e) {
$this->logger->error('Failed to fetch Ask Jiminny report filters', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse(
['error' => 'Failed to fetch filters'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
56588
|
NULL
|
0
|
2026-05-19T08:13:02.762812+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779178382762_m2.jpg...
|
PhpStorm
|
faVsco.js – AskAnythingPromptService.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20676-delete-report-re Project: faVsco.js, menu
JY-20676-delete-report-related-objects, 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
4
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\AskAnything;
use Jiminny\Component\AskAnything\Dtos\AskAnythingPromptDto;
use Jiminny\Contracts\Repositories\GroupRepositoryInterface;
use Jiminny\Exceptions\InvalidArgumentException;
use Jiminny\Models\AskAnything\AskAnythingPrompt;
use Jiminny\Models\AskAnything\AskAnythingPromptTarget;
use Jiminny\Models\AskAnything\UserAskAnythingPrompt;
use Jiminny\Models\Group;
use Jiminny\Models\User;
use Jiminny\Repositories\AskAnythingRepository;
use Jiminny\Repositories\UserRepository;
class AskAnythingPromptService
{
public function __construct(
private readonly AskAnythingRepository $askAnythingRepository,
private readonly UserRepository $userRepository,
private readonly GroupRepositoryInterface $groupRepository,
) {
}
/**
* @return array<AskAnythingPromptDto>
*/
public function get(User $user, AskAnythingPromptTarget $target): array
{
$prompts = $this->askAnythingRepository->findPromptsByUserAndTarget(
$user,
$target
);
$promptDtos = [];
foreach ($prompts as $prompt) {
$ownerUuid = null;
if ($prompt->getOwner() !== null) {
$ownerUuid = $prompt->getOwner()->getUuid();
}
$shareUsers = null;
$shareGroups = null;
// Provide users and groups only if owner of the prompt is current user
if ($prompt->getOwnerId() === $user->getId()) {
[$shareUsers, $shareGroups] = $this->getReceiverUuids($prompt);
}
$promptDtos[] = new AskAnythingPromptDto(
$prompt->getUuid(),
$prompt->getTitle(),
$prompt->getContent(),
$target,
$ownerUuid,
$shareUsers,
$shareGroups,
$prompt->has_reports,
);
}
return $promptDtos;
}
/**
* @param array<string> $shareUsersUuids
* @param array<string> $shareGroupsUuids
*/
public function create(
User $user,
string $title,
string $content,
AskAnythingPromptTarget $target,
array $shareUsersUuids,
array $shareGroupsUuids
): AskAnythingPromptDto {
$shareUsers = $shareGroups = [];
foreach ($shareUsersUuids as $userUuid) {
$shareUsers[] = $this->userRepository->findByUuid($userUuid);
}
foreach ($shareGroupsUuids as $groupUuid) {
$shareGroups[] = $this->groupRepository->findByUuid($groupUuid);
}
$prompt = $this->askAnythingRepository->createPrompt(
$user,
$target,
$title,
$content,
$shareUsers,
$shareGroups,
);
return new AskAnythingPromptDto(
$prompt->getUuid(),
$prompt->getTitle(),
$prompt->getContent(),
$target,
$user->getUuid(),
$shareUsersUuids,
$shareGroupsUuids,
$prompt->has_reports,
);
}
/**
* @param array<string> $shareUsersUuids
* @param array<string> $shareGroupsUuids
*
* @throws InvalidArgumentException
*/
public function edit(
AskAnythingPrompt $prompt,
User $user,
string $title,
string $content,
array $shareUsersUuids,
array $shareGroupsUuids
): AskAnythingPromptDto {
$shareUsers = $shareGroups = [];
foreach ($shareUsersUuids as $userUuid) {
$shareUsers[] = $this->userRepository->findByUuid($userUuid);
}
foreach ($shareGroupsUuids as $groupUuid) {
$shareGroups[] = $this->groupRepository->findByUuid($groupUuid);
}
if ($prompt->isDefaultPrompt()) {
$this->askAnythingRepository->hidePromptForUser($prompt, $user);
$newPrompt = $this->askAnythingRepository->createPrompt(
$user,
$prompt->getTarget(),
$title,
$content,
$shareUsers,
$shareGroups,
);
} elseif ($prompt->getOwnerId() === $user->getId()) {
$newPrompt = $this->askAnythingRepository->editPrompt(
$prompt,
$title,
$content,
$shareUsers,
$shareGroups,
);
} else {
throw new InvalidArgumentException('Edit not allowed for prompt ' . $prompt->getUuid());
}
return new AskAnythingPromptDto(
$newPrompt->getUuid(),
$newPrompt->getTitle(),
$newPrompt->getContent(),
$newPrompt->getTarget(),
$user->getUuid(),
$shareUsersUuids,
$shareGroupsUuids,
$newPrompt->has_reports,
);
}
public function delete(
AskAnythingPrompt $prompt,
User $user
): AskAnythingPrompt {
if ($prompt->isDefaultPrompt()) {
$this->askAnythingRepository->hidePromptForUser($prompt, $user);
} elseif ($prompt->getOwnerId() === $user->getId()) {
$userPrompt = $this->askAnythingRepository->findSharedPromptByUser($prompt->getId(), $user);
$userPrompt?->delete();
// For each relation, re-create the prompt for the receiver as their own
$this->recreatePromptsForEachRelation($prompt);
// Finally, delete the prompt
$this->deletePromptIfNoRelations($prompt);
} else {
$userPrompt = $this->askAnythingRepository->findSharedPromptByUser($prompt->getId(), $user);
$groupPrompt = $this->askAnythingRepository->findSharedPromptByUserGroup($prompt->getId(), $user);
// If the prompt is shared directly with the user, then "unshare" it
if ($userPrompt instanceof UserAskAnythingPrompt && $groupPrompt === null) {
$userPrompt->delete();
$this->deletePromptIfNoRelations($prompt);
} elseif ($groupPrompt instanceof UserAskAnythingPrompt) {
// If the prompt is shared with the user and the group, then hide it for this user
$this->askAnythingRepository->hidePromptForUser($prompt, $user);
} else {
throw new InvalidArgumentException('Unknown delete allowance for prompt ' . $prompt->getUuid());
}
}
return $prompt;
}
public function reorder(
User $user,
array $promptUuids,
): void {
foreach ($promptUuids as $index => $promptUuid) {
$prompt = $this->askAnythingRepository->getPromptByUuid($promptUuid);
$this->askAnythingRepository->orderPromptForUser($prompt, $user, $index + 1);
}
}
/**
* @param AskAnythingPrompt $prompt
*
* @return array[array<string>, array<string>]
*/
private function getReceiverUuids(AskAnythingPrompt $prompt): array
{
$shareUsers = [];
$shareGroups = [];
foreach ($this->askAnythingRepository->findSharedUsersAndGroupsByPromptId($prompt->getId()) as $sharedPrompt) {
$sharedUser = $sharedPrompt->getUser();
if ($sharedUser instanceof User && $sharedUser->isStatusActive()) {
$shareUsers[] = $sharedUser->getUuid();
}
$sharedGroup = $sharedPrompt->getGroup();
if ($sharedGroup instanceof Group) {
$shareGroups[] = $sharedGroup->getUuid();
}
}
return [$shareUsers, $shareGroups];
}
private function deletePromptIfNoRelations(AskAnythingPrompt $prompt): void
{
if ($this->askAnythingRepository->findSharedUsersAndGroupsByPromptId($prompt->getId())->isEmpty()) {
// Disable and orphan any AutomatedReports that use this prompt
$prompt->automatedReports()->withTrashed()->update([
'ask_anything_prompt_id' => null,
'status' => false,
]);
// Delete only if there are no other relations to it.
$this->askAnythingRepository->deletePrompt($prompt);
}
}
private function recreatePromptsForEachRelation(AskAnythingPrompt $prompt): void
{
[$sharedUsersIds, $sharedUsersRemovedIds] = $this->recreatePromptsForUserRelations($prompt);
$this->recreatePromptsForGroupRelations($prompt, $sharedUsersIds, $sharedUsersRemovedIds);
}
private function recreatePromptsForUserRelations(AskAnythingPrompt $prompt): array
{
$sharedUsersIds = [];
$sharedUsersRemovedIds = [];
foreach ($this->askAnythingRepository->findSharedUsersAndGroupsByPromptId($prompt->getId()) as $sharedPrompt) {
$sharedUser = $sharedPrompt->getUser();
if ($sharedPrompt->isRemoved() === true) {
$sharedUsersRemovedIds[] = $sharedUser->getId();
}
if ($sharedPrompt->isRemoved() !== true && $sharedUser instanceof User && $sharedUser->isStatusActive()) {
$sharedUsersIds[] = $sharedUser->getId();
$this->askAnythingRepository->createPrompt(
$sharedUser,
$prompt->getTarget(),
$prompt->getTitle(),
$prompt->getContent(),
[],
[],
);
$sharedPrompt->delete();
}
}
return [$sharedUsersIds, $sharedUsersRemovedIds];
}
private function recreatePromptsForGroupRelations(AskAnythingPrompt $prompt, array $sharedUsersIds, array $sharedUsersRemovedIds): void
{
foreach ($this->askAnythingRepository->findSharedUsersAndGroupsByPromptId($prompt->getId()) as $sharedPrompt) {
$sharedGroup = $sharedPrompt->getGroup();
if ($sharedGroup instanceof Group) {
foreach ($sharedGroup->getMembers() as $member) {
if (! in_array($member->getId(), $sharedUsersIds)
&& ! in_array($member->getId(), $sharedUsersRemovedIds)) {
$sharedUsersIds[] = $member->getId();
$this->askAnythingRepository->createPrompt(
$member,
$prompt->getTarget(),
$prompt->getTitle(),
$prompt->getContent(),
[],
[],
);
}
}
$sharedPrompt->delete();
}
}
}
}...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20676-delete-report-related-objects, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.098071806,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20676-delete-report-related-objects","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":"4","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.007978723,"height":0.0},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.007978723,"height":0.0},"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.00731383,"height":0.0},"on_screen":false,"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.27027926,"top":1.0,"width":0.006981383,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\AskAnything;\n\nuse Jiminny\\Component\\AskAnything\\Dtos\\AskAnythingPromptDto;\nuse Jiminny\\Contracts\\Repositories\\GroupRepositoryInterface;\nuse Jiminny\\Exceptions\\InvalidArgumentException;\nuse Jiminny\\Models\\AskAnything\\AskAnythingPrompt;\nuse Jiminny\\Models\\AskAnything\\AskAnythingPromptTarget;\nuse Jiminny\\Models\\AskAnything\\UserAskAnythingPrompt;\nuse Jiminny\\Models\\Group;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AskAnythingRepository;\nuse Jiminny\\Repositories\\UserRepository;\n\nclass AskAnythingPromptService\n{\n public function __construct(\n private readonly AskAnythingRepository $askAnythingRepository,\n private readonly UserRepository $userRepository,\n private readonly GroupRepositoryInterface $groupRepository,\n ) {\n }\n\n /**\n * @return array<AskAnythingPromptDto>\n */\n public function get(User $user, AskAnythingPromptTarget $target): array\n {\n $prompts = $this->askAnythingRepository->findPromptsByUserAndTarget(\n $user,\n $target\n );\n\n $promptDtos = [];\n foreach ($prompts as $prompt) {\n $ownerUuid = null;\n if ($prompt->getOwner() !== null) {\n $ownerUuid = $prompt->getOwner()->getUuid();\n }\n $shareUsers = null;\n $shareGroups = null;\n\n // Provide users and groups only if owner of the prompt is current user\n if ($prompt->getOwnerId() === $user->getId()) {\n [$shareUsers, $shareGroups] = $this->getReceiverUuids($prompt);\n }\n\n $promptDtos[] = new AskAnythingPromptDto(\n $prompt->getUuid(),\n $prompt->getTitle(),\n $prompt->getContent(),\n $target,\n $ownerUuid,\n $shareUsers,\n $shareGroups,\n $prompt->has_reports,\n );\n }\n\n return $promptDtos;\n }\n\n /**\n * @param array<string> $shareUsersUuids\n * @param array<string> $shareGroupsUuids\n */\n public function create(\n User $user,\n string $title,\n string $content,\n AskAnythingPromptTarget $target,\n array $shareUsersUuids,\n array $shareGroupsUuids\n ): AskAnythingPromptDto {\n\n $shareUsers = $shareGroups = [];\n foreach ($shareUsersUuids as $userUuid) {\n $shareUsers[] = $this->userRepository->findByUuid($userUuid);\n }\n foreach ($shareGroupsUuids as $groupUuid) {\n $shareGroups[] = $this->groupRepository->findByUuid($groupUuid);\n }\n\n $prompt = $this->askAnythingRepository->createPrompt(\n $user,\n $target,\n $title,\n $content,\n $shareUsers,\n $shareGroups,\n );\n\n return new AskAnythingPromptDto(\n $prompt->getUuid(),\n $prompt->getTitle(),\n $prompt->getContent(),\n $target,\n $user->getUuid(),\n $shareUsersUuids,\n $shareGroupsUuids,\n $prompt->has_reports,\n );\n }\n\n /**\n * @param array<string> $shareUsersUuids\n * @param array<string> $shareGroupsUuids\n *\n * @throws InvalidArgumentException\n */\n public function edit(\n AskAnythingPrompt $prompt,\n User $user,\n string $title,\n string $content,\n array $shareUsersUuids,\n array $shareGroupsUuids\n ): AskAnythingPromptDto {\n $shareUsers = $shareGroups = [];\n foreach ($shareUsersUuids as $userUuid) {\n $shareUsers[] = $this->userRepository->findByUuid($userUuid);\n }\n foreach ($shareGroupsUuids as $groupUuid) {\n $shareGroups[] = $this->groupRepository->findByUuid($groupUuid);\n }\n\n if ($prompt->isDefaultPrompt()) {\n $this->askAnythingRepository->hidePromptForUser($prompt, $user);\n\n $newPrompt = $this->askAnythingRepository->createPrompt(\n $user,\n $prompt->getTarget(),\n $title,\n $content,\n $shareUsers,\n $shareGroups,\n );\n } elseif ($prompt->getOwnerId() === $user->getId()) {\n $newPrompt = $this->askAnythingRepository->editPrompt(\n $prompt,\n $title,\n $content,\n $shareUsers,\n $shareGroups,\n );\n } else {\n throw new InvalidArgumentException('Edit not allowed for prompt ' . $prompt->getUuid());\n }\n\n return new AskAnythingPromptDto(\n $newPrompt->getUuid(),\n $newPrompt->getTitle(),\n $newPrompt->getContent(),\n $newPrompt->getTarget(),\n $user->getUuid(),\n $shareUsersUuids,\n $shareGroupsUuids,\n $newPrompt->has_reports,\n );\n }\n\n public function delete(\n AskAnythingPrompt $prompt,\n User $user\n ): AskAnythingPrompt {\n if ($prompt->isDefaultPrompt()) {\n $this->askAnythingRepository->hidePromptForUser($prompt, $user);\n } elseif ($prompt->getOwnerId() === $user->getId()) {\n $userPrompt = $this->askAnythingRepository->findSharedPromptByUser($prompt->getId(), $user);\n $userPrompt?->delete();\n // For each relation, re-create the prompt for the receiver as their own\n $this->recreatePromptsForEachRelation($prompt);\n\n // Finally, delete the prompt\n $this->deletePromptIfNoRelations($prompt);\n } else {\n $userPrompt = $this->askAnythingRepository->findSharedPromptByUser($prompt->getId(), $user);\n $groupPrompt = $this->askAnythingRepository->findSharedPromptByUserGroup($prompt->getId(), $user);\n\n // If the prompt is shared directly with the user, then \"unshare\" it\n if ($userPrompt instanceof UserAskAnythingPrompt && $groupPrompt === null) {\n $userPrompt->delete();\n $this->deletePromptIfNoRelations($prompt);\n } elseif ($groupPrompt instanceof UserAskAnythingPrompt) {\n // If the prompt is shared with the user and the group, then hide it for this user\n $this->askAnythingRepository->hidePromptForUser($prompt, $user);\n } else {\n throw new InvalidArgumentException('Unknown delete allowance for prompt ' . $prompt->getUuid());\n }\n }\n\n return $prompt;\n }\n\n public function reorder(\n User $user,\n array $promptUuids,\n ): void {\n foreach ($promptUuids as $index => $promptUuid) {\n $prompt = $this->askAnythingRepository->getPromptByUuid($promptUuid);\n $this->askAnythingRepository->orderPromptForUser($prompt, $user, $index + 1);\n }\n }\n\n /**\n * @param AskAnythingPrompt $prompt\n *\n * @return array[array<string>, array<string>]\n */\n private function getReceiverUuids(AskAnythingPrompt $prompt): array\n {\n $shareUsers = [];\n $shareGroups = [];\n foreach ($this->askAnythingRepository->findSharedUsersAndGroupsByPromptId($prompt->getId()) as $sharedPrompt) {\n $sharedUser = $sharedPrompt->getUser();\n if ($sharedUser instanceof User && $sharedUser->isStatusActive()) {\n $shareUsers[] = $sharedUser->getUuid();\n }\n $sharedGroup = $sharedPrompt->getGroup();\n if ($sharedGroup instanceof Group) {\n $shareGroups[] = $sharedGroup->getUuid();\n }\n }\n\n return [$shareUsers, $shareGroups];\n }\n\n private function deletePromptIfNoRelations(AskAnythingPrompt $prompt): void\n {\n if ($this->askAnythingRepository->findSharedUsersAndGroupsByPromptId($prompt->getId())->isEmpty()) {\n // Disable and orphan any AutomatedReports that use this prompt\n $prompt->automatedReports()->withTrashed()->update([\n 'ask_anything_prompt_id' => null,\n 'status' => false,\n ]);\n\n // Delete only if there are no other relations to it.\n $this->askAnythingRepository->deletePrompt($prompt);\n }\n }\n\n private function recreatePromptsForEachRelation(AskAnythingPrompt $prompt): void\n {\n [$sharedUsersIds, $sharedUsersRemovedIds] = $this->recreatePromptsForUserRelations($prompt);\n $this->recreatePromptsForGroupRelations($prompt, $sharedUsersIds, $sharedUsersRemovedIds);\n }\n\n private function recreatePromptsForUserRelations(AskAnythingPrompt $prompt): array\n {\n $sharedUsersIds = [];\n $sharedUsersRemovedIds = [];\n foreach ($this->askAnythingRepository->findSharedUsersAndGroupsByPromptId($prompt->getId()) as $sharedPrompt) {\n $sharedUser = $sharedPrompt->getUser();\n if ($sharedPrompt->isRemoved() === true) {\n $sharedUsersRemovedIds[] = $sharedUser->getId();\n }\n if ($sharedPrompt->isRemoved() !== true && $sharedUser instanceof User && $sharedUser->isStatusActive()) {\n $sharedUsersIds[] = $sharedUser->getId();\n $this->askAnythingRepository->createPrompt(\n $sharedUser,\n $prompt->getTarget(),\n $prompt->getTitle(),\n $prompt->getContent(),\n [],\n [],\n );\n $sharedPrompt->delete();\n }\n }\n\n return [$sharedUsersIds, $sharedUsersRemovedIds];\n }\n\n private function recreatePromptsForGroupRelations(AskAnythingPrompt $prompt, array $sharedUsersIds, array $sharedUsersRemovedIds): void\n {\n foreach ($this->askAnythingRepository->findSharedUsersAndGroupsByPromptId($prompt->getId()) as $sharedPrompt) {\n $sharedGroup = $sharedPrompt->getGroup();\n if ($sharedGroup instanceof Group) {\n foreach ($sharedGroup->getMembers() as $member) {\n if (! in_array($member->getId(), $sharedUsersIds)\n && ! in_array($member->getId(), $sharedUsersRemovedIds)) {\n $sharedUsersIds[] = $member->getId();\n $this->askAnythingRepository->createPrompt(\n $member,\n $prompt->getTarget(),\n $prompt->getTitle(),\n $prompt->getContent(),\n [],\n [],\n );\n }\n }\n $sharedPrompt->delete();\n }\n }\n }\n}","depth":4,"bounds":{"left":0.15990691,"top":0.0,"width":0.38098404,"height":1.0},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\AskAnything;\n\nuse Jiminny\\Component\\AskAnything\\Dtos\\AskAnythingPromptDto;\nuse Jiminny\\Contracts\\Repositories\\GroupRepositoryInterface;\nuse Jiminny\\Exceptions\\InvalidArgumentException;\nuse Jiminny\\Models\\AskAnything\\AskAnythingPrompt;\nuse Jiminny\\Models\\AskAnything\\AskAnythingPromptTarget;\nuse Jiminny\\Models\\AskAnything\\UserAskAnythingPrompt;\nuse Jiminny\\Models\\Group;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AskAnythingRepository;\nuse Jiminny\\Repositories\\UserRepository;\n\nclass AskAnythingPromptService\n{\n public function __construct(\n private readonly AskAnythingRepository $askAnythingRepository,\n private readonly UserRepository $userRepository,\n private readonly GroupRepositoryInterface $groupRepository,\n ) {\n }\n\n /**\n * @return array<AskAnythingPromptDto>\n */\n public function get(User $user, AskAnythingPromptTarget $target): array\n {\n $prompts = $this->askAnythingRepository->findPromptsByUserAndTarget(\n $user,\n $target\n );\n\n $promptDtos = [];\n foreach ($prompts as $prompt) {\n $ownerUuid = null;\n if ($prompt->getOwner() !== null) {\n $ownerUuid = $prompt->getOwner()->getUuid();\n }\n $shareUsers = null;\n $shareGroups = null;\n\n // Provide users and groups only if owner of the prompt is current user\n if ($prompt->getOwnerId() === $user->getId()) {\n [$shareUsers, $shareGroups] = $this->getReceiverUuids($prompt);\n }\n\n $promptDtos[] = new AskAnythingPromptDto(\n $prompt->getUuid(),\n $prompt->getTitle(),\n $prompt->getContent(),\n $target,\n $ownerUuid,\n $shareUsers,\n $shareGroups,\n $prompt->has_reports,\n );\n }\n\n return $promptDtos;\n }\n\n /**\n * @param array<string> $shareUsersUuids\n * @param array<string> $shareGroupsUuids\n */\n public function create(\n User $user,\n string $title,\n string $content,\n AskAnythingPromptTarget $target,\n array $shareUsersUuids,\n array $shareGroupsUuids\n ): AskAnythingPromptDto {\n\n $shareUsers = $shareGroups = [];\n foreach ($shareUsersUuids as $userUuid) {\n $shareUsers[] = $this->userRepository->findByUuid($userUuid);\n }\n foreach ($shareGroupsUuids as $groupUuid) {\n $shareGroups[] = $this->groupRepository->findByUuid($groupUuid);\n }\n\n $prompt = $this->askAnythingRepository->createPrompt(\n $user,\n $target,\n $title,\n $content,\n $shareUsers,\n $shareGroups,\n );\n\n return new AskAnythingPromptDto(\n $prompt->getUuid(),\n $prompt->getTitle(),\n $prompt->getContent(),\n $target,\n $user->getUuid(),\n $shareUsersUuids,\n $shareGroupsUuids,\n $prompt->has_reports,\n );\n }\n\n /**\n * @param array<string> $shareUsersUuids\n * @param array<string> $shareGroupsUuids\n *\n * @throws InvalidArgumentException\n */\n public function edit(\n AskAnythingPrompt $prompt,\n User $user,\n string $title,\n string $content,\n array $shareUsersUuids,\n array $shareGroupsUuids\n ): AskAnythingPromptDto {\n $shareUsers = $shareGroups = [];\n foreach ($shareUsersUuids as $userUuid) {\n $shareUsers[] = $this->userRepository->findByUuid($userUuid);\n }\n foreach ($shareGroupsUuids as $groupUuid) {\n $shareGroups[] = $this->groupRepository->findByUuid($groupUuid);\n }\n\n if ($prompt->isDefaultPrompt()) {\n $this->askAnythingRepository->hidePromptForUser($prompt, $user);\n\n $newPrompt = $this->askAnythingRepository->createPrompt(\n $user,\n $prompt->getTarget(),\n $title,\n $content,\n $shareUsers,\n $shareGroups,\n );\n } elseif ($prompt->getOwnerId() === $user->getId()) {\n $newPrompt = $this->askAnythingRepository->editPrompt(\n $prompt,\n $title,\n $content,\n $shareUsers,\n $shareGroups,\n );\n } else {\n throw new InvalidArgumentException('Edit not allowed for prompt ' . $prompt->getUuid());\n }\n\n return new AskAnythingPromptDto(\n $newPrompt->getUuid(),\n $newPrompt->getTitle(),\n $newPrompt->getContent(),\n $newPrompt->getTarget(),\n $user->getUuid(),\n $shareUsersUuids,\n $shareGroupsUuids,\n $newPrompt->has_reports,\n );\n }\n\n public function delete(\n AskAnythingPrompt $prompt,\n User $user\n ): AskAnythingPrompt {\n if ($prompt->isDefaultPrompt()) {\n $this->askAnythingRepository->hidePromptForUser($prompt, $user);\n } elseif ($prompt->getOwnerId() === $user->getId()) {\n $userPrompt = $this->askAnythingRepository->findSharedPromptByUser($prompt->getId(), $user);\n $userPrompt?->delete();\n // For each relation, re-create the prompt for the receiver as their own\n $this->recreatePromptsForEachRelation($prompt);\n\n // Finally, delete the prompt\n $this->deletePromptIfNoRelations($prompt);\n } else {\n $userPrompt = $this->askAnythingRepository->findSharedPromptByUser($prompt->getId(), $user);\n $groupPrompt = $this->askAnythingRepository->findSharedPromptByUserGroup($prompt->getId(), $user);\n\n // If the prompt is shared directly with the user, then \"unshare\" it\n if ($userPrompt instanceof UserAskAnythingPrompt && $groupPrompt === null) {\n $userPrompt->delete();\n $this->deletePromptIfNoRelations($prompt);\n } elseif ($groupPrompt instanceof UserAskAnythingPrompt) {\n // If the prompt is shared with the user and the group, then hide it for this user\n $this->askAnythingRepository->hidePromptForUser($prompt, $user);\n } else {\n throw new InvalidArgumentException('Unknown delete allowance for prompt ' . $prompt->getUuid());\n }\n }\n\n return $prompt;\n }\n\n public function reorder(\n User $user,\n array $promptUuids,\n ): void {\n foreach ($promptUuids as $index => $promptUuid) {\n $prompt = $this->askAnythingRepository->getPromptByUuid($promptUuid);\n $this->askAnythingRepository->orderPromptForUser($prompt, $user, $index + 1);\n }\n }\n\n /**\n * @param AskAnythingPrompt $prompt\n *\n * @return array[array<string>, array<string>]\n */\n private function getReceiverUuids(AskAnythingPrompt $prompt): array\n {\n $shareUsers = [];\n $shareGroups = [];\n foreach ($this->askAnythingRepository->findSharedUsersAndGroupsByPromptId($prompt->getId()) as $sharedPrompt) {\n $sharedUser = $sharedPrompt->getUser();\n if ($sharedUser instanceof User && $sharedUser->isStatusActive()) {\n $shareUsers[] = $sharedUser->getUuid();\n }\n $sharedGroup = $sharedPrompt->getGroup();\n if ($sharedGroup instanceof Group) {\n $shareGroups[] = $sharedGroup->getUuid();\n }\n }\n\n return [$shareUsers, $shareGroups];\n }\n\n private function deletePromptIfNoRelations(AskAnythingPrompt $prompt): void\n {\n if ($this->askAnythingRepository->findSharedUsersAndGroupsByPromptId($prompt->getId())->isEmpty()) {\n // Disable and orphan any AutomatedReports that use this prompt\n $prompt->automatedReports()->withTrashed()->update([\n 'ask_anything_prompt_id' => null,\n 'status' => false,\n ]);\n\n // Delete only if there are no other relations to it.\n $this->askAnythingRepository->deletePrompt($prompt);\n }\n }\n\n private function recreatePromptsForEachRelation(AskAnythingPrompt $prompt): void\n {\n [$sharedUsersIds, $sharedUsersRemovedIds] = $this->recreatePromptsForUserRelations($prompt);\n $this->recreatePromptsForGroupRelations($prompt, $sharedUsersIds, $sharedUsersRemovedIds);\n }\n\n private function recreatePromptsForUserRelations(AskAnythingPrompt $prompt): array\n {\n $sharedUsersIds = [];\n $sharedUsersRemovedIds = [];\n foreach ($this->askAnythingRepository->findSharedUsersAndGroupsByPromptId($prompt->getId()) as $sharedPrompt) {\n $sharedUser = $sharedPrompt->getUser();\n if ($sharedPrompt->isRemoved() === true) {\n $sharedUsersRemovedIds[] = $sharedUser->getId();\n }\n if ($sharedPrompt->isRemoved() !== true && $sharedUser instanceof User && $sharedUser->isStatusActive()) {\n $sharedUsersIds[] = $sharedUser->getId();\n $this->askAnythingRepository->createPrompt(\n $sharedUser,\n $prompt->getTarget(),\n $prompt->getTitle(),\n $prompt->getContent(),\n [],\n [],\n );\n $sharedPrompt->delete();\n }\n }\n\n return [$sharedUsersIds, $sharedUsersRemovedIds];\n }\n\n private function recreatePromptsForGroupRelations(AskAnythingPrompt $prompt, array $sharedUsersIds, array $sharedUsersRemovedIds): void\n {\n foreach ($this->askAnythingRepository->findSharedUsersAndGroupsByPromptId($prompt->getId()) as $sharedPrompt) {\n $sharedGroup = $sharedPrompt->getGroup();\n if ($sharedGroup instanceof Group) {\n foreach ($sharedGroup->getMembers() as $member) {\n if (! in_array($member->getId(), $sharedUsersIds)\n && ! in_array($member->getId(), $sharedUsersRemovedIds)) {\n $sharedUsersIds[] = $member->getId();\n $this->askAnythingRepository->createPrompt(\n $member,\n $prompt->getTarget(),\n $prompt->getTitle(),\n $prompt->getContent(),\n [],\n [],\n );\n }\n }\n $sharedPrompt->delete();\n }\n }\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false}]...
|
-4270432416815645263
|
1126372201043036670
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20676-delete-report-re Project: faVsco.js, menu
JY-20676-delete-report-related-objects, 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
4
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\AskAnything;
use Jiminny\Component\AskAnything\Dtos\AskAnythingPromptDto;
use Jiminny\Contracts\Repositories\GroupRepositoryInterface;
use Jiminny\Exceptions\InvalidArgumentException;
use Jiminny\Models\AskAnything\AskAnythingPrompt;
use Jiminny\Models\AskAnything\AskAnythingPromptTarget;
use Jiminny\Models\AskAnything\UserAskAnythingPrompt;
use Jiminny\Models\Group;
use Jiminny\Models\User;
use Jiminny\Repositories\AskAnythingRepository;
use Jiminny\Repositories\UserRepository;
class AskAnythingPromptService
{
public function __construct(
private readonly AskAnythingRepository $askAnythingRepository,
private readonly UserRepository $userRepository,
private readonly GroupRepositoryInterface $groupRepository,
) {
}
/**
* @return array<AskAnythingPromptDto>
*/
public function get(User $user, AskAnythingPromptTarget $target): array
{
$prompts = $this->askAnythingRepository->findPromptsByUserAndTarget(
$user,
$target
);
$promptDtos = [];
foreach ($prompts as $prompt) {
$ownerUuid = null;
if ($prompt->getOwner() !== null) {
$ownerUuid = $prompt->getOwner()->getUuid();
}
$shareUsers = null;
$shareGroups = null;
// Provide users and groups only if owner of the prompt is current user
if ($prompt->getOwnerId() === $user->getId()) {
[$shareUsers, $shareGroups] = $this->getReceiverUuids($prompt);
}
$promptDtos[] = new AskAnythingPromptDto(
$prompt->getUuid(),
$prompt->getTitle(),
$prompt->getContent(),
$target,
$ownerUuid,
$shareUsers,
$shareGroups,
$prompt->has_reports,
);
}
return $promptDtos;
}
/**
* @param array<string> $shareUsersUuids
* @param array<string> $shareGroupsUuids
*/
public function create(
User $user,
string $title,
string $content,
AskAnythingPromptTarget $target,
array $shareUsersUuids,
array $shareGroupsUuids
): AskAnythingPromptDto {
$shareUsers = $shareGroups = [];
foreach ($shareUsersUuids as $userUuid) {
$shareUsers[] = $this->userRepository->findByUuid($userUuid);
}
foreach ($shareGroupsUuids as $groupUuid) {
$shareGroups[] = $this->groupRepository->findByUuid($groupUuid);
}
$prompt = $this->askAnythingRepository->createPrompt(
$user,
$target,
$title,
$content,
$shareUsers,
$shareGroups,
);
return new AskAnythingPromptDto(
$prompt->getUuid(),
$prompt->getTitle(),
$prompt->getContent(),
$target,
$user->getUuid(),
$shareUsersUuids,
$shareGroupsUuids,
$prompt->has_reports,
);
}
/**
* @param array<string> $shareUsersUuids
* @param array<string> $shareGroupsUuids
*
* @throws InvalidArgumentException
*/
public function edit(
AskAnythingPrompt $prompt,
User $user,
string $title,
string $content,
array $shareUsersUuids,
array $shareGroupsUuids
): AskAnythingPromptDto {
$shareUsers = $shareGroups = [];
foreach ($shareUsersUuids as $userUuid) {
$shareUsers[] = $this->userRepository->findByUuid($userUuid);
}
foreach ($shareGroupsUuids as $groupUuid) {
$shareGroups[] = $this->groupRepository->findByUuid($groupUuid);
}
if ($prompt->isDefaultPrompt()) {
$this->askAnythingRepository->hidePromptForUser($prompt, $user);
$newPrompt = $this->askAnythingRepository->createPrompt(
$user,
$prompt->getTarget(),
$title,
$content,
$shareUsers,
$shareGroups,
);
} elseif ($prompt->getOwnerId() === $user->getId()) {
$newPrompt = $this->askAnythingRepository->editPrompt(
$prompt,
$title,
$content,
$shareUsers,
$shareGroups,
);
} else {
throw new InvalidArgumentException('Edit not allowed for prompt ' . $prompt->getUuid());
}
return new AskAnythingPromptDto(
$newPrompt->getUuid(),
$newPrompt->getTitle(),
$newPrompt->getContent(),
$newPrompt->getTarget(),
$user->getUuid(),
$shareUsersUuids,
$shareGroupsUuids,
$newPrompt->has_reports,
);
}
public function delete(
AskAnythingPrompt $prompt,
User $user
): AskAnythingPrompt {
if ($prompt->isDefaultPrompt()) {
$this->askAnythingRepository->hidePromptForUser($prompt, $user);
} elseif ($prompt->getOwnerId() === $user->getId()) {
$userPrompt = $this->askAnythingRepository->findSharedPromptByUser($prompt->getId(), $user);
$userPrompt?->delete();
// For each relation, re-create the prompt for the receiver as their own
$this->recreatePromptsForEachRelation($prompt);
// Finally, delete the prompt
$this->deletePromptIfNoRelations($prompt);
} else {
$userPrompt = $this->askAnythingRepository->findSharedPromptByUser($prompt->getId(), $user);
$groupPrompt = $this->askAnythingRepository->findSharedPromptByUserGroup($prompt->getId(), $user);
// If the prompt is shared directly with the user, then "unshare" it
if ($userPrompt instanceof UserAskAnythingPrompt && $groupPrompt === null) {
$userPrompt->delete();
$this->deletePromptIfNoRelations($prompt);
} elseif ($groupPrompt instanceof UserAskAnythingPrompt) {
// If the prompt is shared with the user and the group, then hide it for this user
$this->askAnythingRepository->hidePromptForUser($prompt, $user);
} else {
throw new InvalidArgumentException('Unknown delete allowance for prompt ' . $prompt->getUuid());
}
}
return $prompt;
}
public function reorder(
User $user,
array $promptUuids,
): void {
foreach ($promptUuids as $index => $promptUuid) {
$prompt = $this->askAnythingRepository->getPromptByUuid($promptUuid);
$this->askAnythingRepository->orderPromptForUser($prompt, $user, $index + 1);
}
}
/**
* @param AskAnythingPrompt $prompt
*
* @return array[array<string>, array<string>]
*/
private function getReceiverUuids(AskAnythingPrompt $prompt): array
{
$shareUsers = [];
$shareGroups = [];
foreach ($this->askAnythingRepository->findSharedUsersAndGroupsByPromptId($prompt->getId()) as $sharedPrompt) {
$sharedUser = $sharedPrompt->getUser();
if ($sharedUser instanceof User && $sharedUser->isStatusActive()) {
$shareUsers[] = $sharedUser->getUuid();
}
$sharedGroup = $sharedPrompt->getGroup();
if ($sharedGroup instanceof Group) {
$shareGroups[] = $sharedGroup->getUuid();
}
}
return [$shareUsers, $shareGroups];
}
private function deletePromptIfNoRelations(AskAnythingPrompt $prompt): void
{
if ($this->askAnythingRepository->findSharedUsersAndGroupsByPromptId($prompt->getId())->isEmpty()) {
// Disable and orphan any AutomatedReports that use this prompt
$prompt->automatedReports()->withTrashed()->update([
'ask_anything_prompt_id' => null,
'status' => false,
]);
// Delete only if there are no other relations to it.
$this->askAnythingRepository->deletePrompt($prompt);
}
}
private function recreatePromptsForEachRelation(AskAnythingPrompt $prompt): void
{
[$sharedUsersIds, $sharedUsersRemovedIds] = $this->recreatePromptsForUserRelations($prompt);
$this->recreatePromptsForGroupRelations($prompt, $sharedUsersIds, $sharedUsersRemovedIds);
}
private function recreatePromptsForUserRelations(AskAnythingPrompt $prompt): array
{
$sharedUsersIds = [];
$sharedUsersRemovedIds = [];
foreach ($this->askAnythingRepository->findSharedUsersAndGroupsByPromptId($prompt->getId()) as $sharedPrompt) {
$sharedUser = $sharedPrompt->getUser();
if ($sharedPrompt->isRemoved() === true) {
$sharedUsersRemovedIds[] = $sharedUser->getId();
}
if ($sharedPrompt->isRemoved() !== true && $sharedUser instanceof User && $sharedUser->isStatusActive()) {
$sharedUsersIds[] = $sharedUser->getId();
$this->askAnythingRepository->createPrompt(
$sharedUser,
$prompt->getTarget(),
$prompt->getTitle(),
$prompt->getContent(),
[],
[],
);
$sharedPrompt->delete();
}
}
return [$sharedUsersIds, $sharedUsersRemovedIds];
}
private function recreatePromptsForGroupRelations(AskAnythingPrompt $prompt, array $sharedUsersIds, array $sharedUsersRemovedIds): void
{
foreach ($this->askAnythingRepository->findSharedUsersAndGroupsByPromptId($prompt->getId()) as $sharedPrompt) {
$sharedGroup = $sharedPrompt->getGroup();
if ($sharedGroup instanceof Group) {
foreach ($sharedGroup->getMembers() as $member) {
if (! in_array($member->getId(), $sharedUsersIds)
&& ! in_array($member->getId(), $sharedUsersRemovedIds)) {
$sharedUsersIds[] = $member->getId();
$this->askAnythingRepository->createPrompt(
$member,
$prompt->getTarget(),
$prompt->getTitle(),
$prompt->getContent(),
[],
[],
);
}
}
$sharedPrompt->delete();
}
}
}
}...
|
56586
|
NULL
|
NULL
|
NULL
|
|
56587
|
NULL
|
0
|
2026-05-19T08:13:02.749416+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779178382749_m1.jpg...
|
PhpStorm
|
faVsco.js – AskAnythingPromptService.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20676-delete-report-re Project: faVsco.js, menu
JY-20676-delete-report-related-objects, 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
4
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\AskAnything;
use Jiminny\Component\AskAnything\Dtos\AskAnythingPromptDto;
use Jiminny\Contracts\Repositories\GroupRepositoryInterface;
use Jiminny\Exceptions\InvalidArgumentException;
use Jiminny\Models\AskAnything\AskAnythingPrompt;
use Jiminny\Models\AskAnything\AskAnythingPromptTarget;
use Jiminny\Models\AskAnything\UserAskAnythingPrompt;
use Jiminny\Models\Group;
use Jiminny\Models\User;
use Jiminny\Repositories\AskAnythingRepository;
use Jiminny\Repositories\UserRepository;
class AskAnythingPromptService
{
public function __construct(
private readonly AskAnythingRepository $askAnythingRepository,
private readonly UserRepository $userRepository,
private readonly GroupRepositoryInterface $groupRepository,
) {
}
/**
* @return array<AskAnythingPromptDto>
*/
public function get(User $user, AskAnythingPromptTarget $target): array
{
$prompts = $this->askAnythingRepository->findPromptsByUserAndTarget(
$user,
$target
);
$promptDtos = [];
foreach ($prompts as $prompt) {
$ownerUuid = null;
if ($prompt->getOwner() !== null) {
$ownerUuid = $prompt->getOwner()->getUuid();
}
$shareUsers = null;
$shareGroups = null;
// Provide users and groups only if owner of the prompt is current user
if ($prompt->getOwnerId() === $user->getId()) {
[$shareUsers, $shareGroups] = $this->getReceiverUuids($prompt);
}
$promptDtos[] = new AskAnythingPromptDto(
$prompt->getUuid(),
$prompt->getTitle(),
$prompt->getContent(),
$target,
$ownerUuid,
$shareUsers,
$shareGroups,
$prompt->has_reports,
);
}
return $promptDtos;
}
/**
* @param array<string> $shareUsersUuids
* @param array<string> $shareGroupsUuids
*/
public function create(
User $user,
string $title,
string $content,
AskAnythingPromptTarget $target,
array $shareUsersUuids,
array $shareGroupsUuids
): AskAnythingPromptDto {
$shareUsers = $shareGroups = [];
foreach ($shareUsersUuids as $userUuid) {
$shareUsers[] = $this->userRepository->findByUuid($userUuid);
}
foreach ($shareGroupsUuids as $groupUuid) {
$shareGroups[] = $this->groupRepository->findByUuid($groupUuid);
}
$prompt = $this->askAnythingRepository->createPrompt(
$user,
$target,
$title,
$content,
$shareUsers,
$shareGroups,
);
return new AskAnythingPromptDto(
$prompt->getUuid(),
$prompt->getTitle(),
$prompt->getContent(),
$target,
$user->getUuid(),
$shareUsersUuids,
$shareGroupsUuids,
$prompt->has_reports,
);
}
/**
* @param array<string> $shareUsersUuids
* @param array<string> $shareGroupsUuids
*
* @throws InvalidArgumentException
*/
public function edit(
AskAnythingPrompt $prompt,
User $user,
string $title,
string $content,
array $shareUsersUuids,
array $shareGroupsUuids
): AskAnythingPromptDto {
$shareUsers = $shareGroups = [];
foreach ($shareUsersUuids as $userUuid) {
$shareUsers[] = $this->userRepository->findByUuid($userUuid);
}
foreach ($shareGroupsUuids as $groupUuid) {
$shareGroups[] = $this->groupRepository->findByUuid($groupUuid);
}
if ($prompt->isDefaultPrompt()) {
$this->askAnythingRepository->hidePromptForUser($prompt, $user);
$newPrompt = $this->askAnythingRepository->createPrompt(
$user,
$prompt->getTarget(),
$title,
$content,
$shareUsers,
$shareGroups,
);
} elseif ($prompt->getOwnerId() === $user->getId()) {
$newPrompt = $this->askAnythingRepository->editPrompt(
$prompt,
$title,
$content,
$shareUsers,
$shareGroups,
);
} else {
throw new InvalidArgumentException('Edit not allowed for prompt ' . $prompt->getUuid());
}
return new AskAnythingPromptDto(
$newPrompt->getUuid(),
$newPrompt->getTitle(),
$newPrompt->getContent(),
$newPrompt->getTarget(),
$user->getUuid(),
$shareUsersUuids,
$shareGroupsUuids,
$newPrompt->has_reports,
);
}
public function delete(
AskAnythingPrompt $prompt,
User $user
): AskAnythingPrompt {
if ($prompt->isDefaultPrompt()) {
$this->askAnythingRepository->hidePromptForUser($prompt, $user);
} elseif ($prompt->getOwnerId() === $user->getId()) {
$userPrompt = $this->askAnythingRepository->findSharedPromptByUser($prompt->getId(), $user);
$userPrompt?->delete();
// For each relation, re-create the prompt for the receiver as their own
$this->recreatePromptsForEachRelation($prompt);
// Finally, delete the prompt
$this->deletePromptIfNoRelations($prompt);
} else {
$userPrompt = $this->askAnythingRepository->findSharedPromptByUser($prompt->getId(), $user);
$groupPrompt = $this->askAnythingRepository->findSharedPromptByUserGroup($prompt->getId(), $user);
// If the prompt is shared directly with the user, then "unshare" it
if ($userPrompt instanceof UserAskAnythingPrompt && $groupPrompt === null) {
$userPrompt->delete();
$this->deletePromptIfNoRelations($prompt);
} elseif ($groupPrompt instanceof UserAskAnythingPrompt) {
// If the prompt is shared with the user and the group, then hide it for this user
$this->askAnythingRepository->hidePromptForUser($prompt, $user);
} else {
throw new InvalidArgumentException('Unknown delete allowance for prompt ' . $prompt->getUuid());
}
}
return $prompt;
}
public function reorder(
User $user,
array $promptUuids,
): void {
foreach ($promptUuids as $index => $promptUuid) {
$prompt = $this->askAnythingRepository->getPromptByUuid($promptUuid);
$this->askAnythingRepository->orderPromptForUser($prompt, $user, $index + 1);
}
}
/**
* @param AskAnythingPrompt $prompt
*
* @return array[array<string>, array<string>]
*/
private function getReceiverUuids(AskAnythingPrompt $prompt): array
{
$shareUsers = [];
$shareGroups = [];
foreach ($this->askAnythingRepository->findSharedUsersAndGroupsByPromptId($prompt->getId()) as $sharedPrompt) {
$sharedUser = $sharedPrompt->getUser();
if ($sharedUser instanceof User && $sharedUser->isStatusActive()) {
$shareUsers[] = $sharedUser->getUuid();
}
$sharedGroup = $sharedPrompt->getGroup();
if ($sharedGroup instanceof Group) {
$shareGroups[] = $sharedGroup->getUuid();
}
}
return [$shareUsers, $shareGroups];
}
private function deletePromptIfNoRelations(AskAnythingPrompt $prompt): void
{
if ($this->askAnythingRepository->findSharedUsersAndGroupsByPromptId($prompt->getId())->isEmpty()) {
// Disable and orphan any AutomatedReports that use this prompt
$prompt->automatedReports()->withTrashed()->update([
'ask_anything_prompt_id' => null,
'status' => false,
]);
// Delete only if there are no other relations to it.
$this->askAnythingRepository->deletePrompt($prompt);
}
}
private function recreatePromptsForEachRelation(AskAnythingPrompt $prompt): void
{
[$sharedUsersIds, $sharedUsersRemovedIds] = $this->recreatePromptsForUserRelations($prompt);
$this->recreatePromptsForGroupRelations($prompt, $sharedUsersIds, $sharedUsersRemovedIds);
}
private function recreatePromptsForUserRelations(AskAnythingPrompt $prompt): array
{
$sharedUsersIds = [];
$sharedUsersRemovedIds = [];
foreach ($this->askAnythingRepository->findSharedUsersAndGroupsByPromptId($prompt->getId()) as $sharedPrompt) {
$sharedUser = $sharedPrompt->getUser();
if ($sharedPrompt->isRemoved() === true) {
$sharedUsersRemovedIds[] = $sharedUser->getId();
}
if ($sharedPrompt->isRemoved() !== true && $sharedUser instanceof User && $sharedUser->isStatusActive()) {
$sharedUsersIds[] = $sharedUser->getId();
$this->askAnythingRepository->createPrompt(
$sharedUser,
$prompt->getTarget(),
$prompt->getTitle(),
$prompt->getContent(),
[],
[],
);
$sharedPrompt->delete();
}
}
return [$sharedUsersIds, $sharedUsersRemovedIds];
}
private function recreatePromptsForGroupRelations(AskAnythingPrompt $prompt, array $sharedUsersIds, array $sharedUsersRemovedIds): void
{
foreach ($this->askAnythingRepository->findSharedUsersAndGroupsByPromptId($prompt->getId()) as $sharedPrompt) {
$sharedGroup = $sharedPrompt->getGroup();
if ($sharedGroup instanceof Group) {
foreach ($sharedGroup->getMembers() as $member) {
if (! in_array($member->getId(), $sharedUsersIds)
&& ! in_array($member->getId(), $sharedUsersRemovedIds)) {
$sharedUsersIds[] = $member->getId();
$this->askAnythingRepository->createPrompt(
$member,
$prompt->getTarget(),
$prompt->getTitle(),
$prompt->getContent(),
[],
[],
);
}
}
$sharedPrompt->delete();
}
}
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20676-delete-report-related-objects, menu","depth":5,"on_screen":true,"help_text":"Git Branch: JY-20676-delete-report-related-objects","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":"4","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.016666668,"height":0.02111111},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.016666668,"height":0.02111111},"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.025555555},"on_screen":false,"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.0,"top":0.0,"width":0.014583333,"height":0.025555555},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\AskAnything;\n\nuse Jiminny\\Component\\AskAnything\\Dtos\\AskAnythingPromptDto;\nuse Jiminny\\Contracts\\Repositories\\GroupRepositoryInterface;\nuse Jiminny\\Exceptions\\InvalidArgumentException;\nuse Jiminny\\Models\\AskAnything\\AskAnythingPrompt;\nuse Jiminny\\Models\\AskAnything\\AskAnythingPromptTarget;\nuse Jiminny\\Models\\AskAnything\\UserAskAnythingPrompt;\nuse Jiminny\\Models\\Group;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AskAnythingRepository;\nuse Jiminny\\Repositories\\UserRepository;\n\nclass AskAnythingPromptService\n{\n public function __construct(\n private readonly AskAnythingRepository $askAnythingRepository,\n private readonly UserRepository $userRepository,\n private readonly GroupRepositoryInterface $groupRepository,\n ) {\n }\n\n /**\n * @return array<AskAnythingPromptDto>\n */\n public function get(User $user, AskAnythingPromptTarget $target): array\n {\n $prompts = $this->askAnythingRepository->findPromptsByUserAndTarget(\n $user,\n $target\n );\n\n $promptDtos = [];\n foreach ($prompts as $prompt) {\n $ownerUuid = null;\n if ($prompt->getOwner() !== null) {\n $ownerUuid = $prompt->getOwner()->getUuid();\n }\n $shareUsers = null;\n $shareGroups = null;\n\n // Provide users and groups only if owner of the prompt is current user\n if ($prompt->getOwnerId() === $user->getId()) {\n [$shareUsers, $shareGroups] = $this->getReceiverUuids($prompt);\n }\n\n $promptDtos[] = new AskAnythingPromptDto(\n $prompt->getUuid(),\n $prompt->getTitle(),\n $prompt->getContent(),\n $target,\n $ownerUuid,\n $shareUsers,\n $shareGroups,\n $prompt->has_reports,\n );\n }\n\n return $promptDtos;\n }\n\n /**\n * @param array<string> $shareUsersUuids\n * @param array<string> $shareGroupsUuids\n */\n public function create(\n User $user,\n string $title,\n string $content,\n AskAnythingPromptTarget $target,\n array $shareUsersUuids,\n array $shareGroupsUuids\n ): AskAnythingPromptDto {\n\n $shareUsers = $shareGroups = [];\n foreach ($shareUsersUuids as $userUuid) {\n $shareUsers[] = $this->userRepository->findByUuid($userUuid);\n }\n foreach ($shareGroupsUuids as $groupUuid) {\n $shareGroups[] = $this->groupRepository->findByUuid($groupUuid);\n }\n\n $prompt = $this->askAnythingRepository->createPrompt(\n $user,\n $target,\n $title,\n $content,\n $shareUsers,\n $shareGroups,\n );\n\n return new AskAnythingPromptDto(\n $prompt->getUuid(),\n $prompt->getTitle(),\n $prompt->getContent(),\n $target,\n $user->getUuid(),\n $shareUsersUuids,\n $shareGroupsUuids,\n $prompt->has_reports,\n );\n }\n\n /**\n * @param array<string> $shareUsersUuids\n * @param array<string> $shareGroupsUuids\n *\n * @throws InvalidArgumentException\n */\n public function edit(\n AskAnythingPrompt $prompt,\n User $user,\n string $title,\n string $content,\n array $shareUsersUuids,\n array $shareGroupsUuids\n ): AskAnythingPromptDto {\n $shareUsers = $shareGroups = [];\n foreach ($shareUsersUuids as $userUuid) {\n $shareUsers[] = $this->userRepository->findByUuid($userUuid);\n }\n foreach ($shareGroupsUuids as $groupUuid) {\n $shareGroups[] = $this->groupRepository->findByUuid($groupUuid);\n }\n\n if ($prompt->isDefaultPrompt()) {\n $this->askAnythingRepository->hidePromptForUser($prompt, $user);\n\n $newPrompt = $this->askAnythingRepository->createPrompt(\n $user,\n $prompt->getTarget(),\n $title,\n $content,\n $shareUsers,\n $shareGroups,\n );\n } elseif ($prompt->getOwnerId() === $user->getId()) {\n $newPrompt = $this->askAnythingRepository->editPrompt(\n $prompt,\n $title,\n $content,\n $shareUsers,\n $shareGroups,\n );\n } else {\n throw new InvalidArgumentException('Edit not allowed for prompt ' . $prompt->getUuid());\n }\n\n return new AskAnythingPromptDto(\n $newPrompt->getUuid(),\n $newPrompt->getTitle(),\n $newPrompt->getContent(),\n $newPrompt->getTarget(),\n $user->getUuid(),\n $shareUsersUuids,\n $shareGroupsUuids,\n $newPrompt->has_reports,\n );\n }\n\n public function delete(\n AskAnythingPrompt $prompt,\n User $user\n ): AskAnythingPrompt {\n if ($prompt->isDefaultPrompt()) {\n $this->askAnythingRepository->hidePromptForUser($prompt, $user);\n } elseif ($prompt->getOwnerId() === $user->getId()) {\n $userPrompt = $this->askAnythingRepository->findSharedPromptByUser($prompt->getId(), $user);\n $userPrompt?->delete();\n // For each relation, re-create the prompt for the receiver as their own\n $this->recreatePromptsForEachRelation($prompt);\n\n // Finally, delete the prompt\n $this->deletePromptIfNoRelations($prompt);\n } else {\n $userPrompt = $this->askAnythingRepository->findSharedPromptByUser($prompt->getId(), $user);\n $groupPrompt = $this->askAnythingRepository->findSharedPromptByUserGroup($prompt->getId(), $user);\n\n // If the prompt is shared directly with the user, then \"unshare\" it\n if ($userPrompt instanceof UserAskAnythingPrompt && $groupPrompt === null) {\n $userPrompt->delete();\n $this->deletePromptIfNoRelations($prompt);\n } elseif ($groupPrompt instanceof UserAskAnythingPrompt) {\n // If the prompt is shared with the user and the group, then hide it for this user\n $this->askAnythingRepository->hidePromptForUser($prompt, $user);\n } else {\n throw new InvalidArgumentException('Unknown delete allowance for prompt ' . $prompt->getUuid());\n }\n }\n\n return $prompt;\n }\n\n public function reorder(\n User $user,\n array $promptUuids,\n ): void {\n foreach ($promptUuids as $index => $promptUuid) {\n $prompt = $this->askAnythingRepository->getPromptByUuid($promptUuid);\n $this->askAnythingRepository->orderPromptForUser($prompt, $user, $index + 1);\n }\n }\n\n /**\n * @param AskAnythingPrompt $prompt\n *\n * @return array[array<string>, array<string>]\n */\n private function getReceiverUuids(AskAnythingPrompt $prompt): array\n {\n $shareUsers = [];\n $shareGroups = [];\n foreach ($this->askAnythingRepository->findSharedUsersAndGroupsByPromptId($prompt->getId()) as $sharedPrompt) {\n $sharedUser = $sharedPrompt->getUser();\n if ($sharedUser instanceof User && $sharedUser->isStatusActive()) {\n $shareUsers[] = $sharedUser->getUuid();\n }\n $sharedGroup = $sharedPrompt->getGroup();\n if ($sharedGroup instanceof Group) {\n $shareGroups[] = $sharedGroup->getUuid();\n }\n }\n\n return [$shareUsers, $shareGroups];\n }\n\n private function deletePromptIfNoRelations(AskAnythingPrompt $prompt): void\n {\n if ($this->askAnythingRepository->findSharedUsersAndGroupsByPromptId($prompt->getId())->isEmpty()) {\n // Disable and orphan any AutomatedReports that use this prompt\n $prompt->automatedReports()->withTrashed()->update([\n 'ask_anything_prompt_id' => null,\n 'status' => false,\n ]);\n\n // Delete only if there are no other relations to it.\n $this->askAnythingRepository->deletePrompt($prompt);\n }\n }\n\n private function recreatePromptsForEachRelation(AskAnythingPrompt $prompt): void\n {\n [$sharedUsersIds, $sharedUsersRemovedIds] = $this->recreatePromptsForUserRelations($prompt);\n $this->recreatePromptsForGroupRelations($prompt, $sharedUsersIds, $sharedUsersRemovedIds);\n }\n\n private function recreatePromptsForUserRelations(AskAnythingPrompt $prompt): array\n {\n $sharedUsersIds = [];\n $sharedUsersRemovedIds = [];\n foreach ($this->askAnythingRepository->findSharedUsersAndGroupsByPromptId($prompt->getId()) as $sharedPrompt) {\n $sharedUser = $sharedPrompt->getUser();\n if ($sharedPrompt->isRemoved() === true) {\n $sharedUsersRemovedIds[] = $sharedUser->getId();\n }\n if ($sharedPrompt->isRemoved() !== true && $sharedUser instanceof User && $sharedUser->isStatusActive()) {\n $sharedUsersIds[] = $sharedUser->getId();\n $this->askAnythingRepository->createPrompt(\n $sharedUser,\n $prompt->getTarget(),\n $prompt->getTitle(),\n $prompt->getContent(),\n [],\n [],\n );\n $sharedPrompt->delete();\n }\n }\n\n return [$sharedUsersIds, $sharedUsersRemovedIds];\n }\n\n private function recreatePromptsForGroupRelations(AskAnythingPrompt $prompt, array $sharedUsersIds, array $sharedUsersRemovedIds): void\n {\n foreach ($this->askAnythingRepository->findSharedUsersAndGroupsByPromptId($prompt->getId()) as $sharedPrompt) {\n $sharedGroup = $sharedPrompt->getGroup();\n if ($sharedGroup instanceof Group) {\n foreach ($sharedGroup->getMembers() as $member) {\n if (! in_array($member->getId(), $sharedUsersIds)\n && ! in_array($member->getId(), $sharedUsersRemovedIds)) {\n $sharedUsersIds[] = $member->getId();\n $this->askAnythingRepository->createPrompt(\n $member,\n $prompt->getTarget(),\n $prompt->getTitle(),\n $prompt->getContent(),\n [],\n [],\n );\n }\n }\n $sharedPrompt->delete();\n }\n }\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\AskAnything;\n\nuse Jiminny\\Component\\AskAnything\\Dtos\\AskAnythingPromptDto;\nuse Jiminny\\Contracts\\Repositories\\GroupRepositoryInterface;\nuse Jiminny\\Exceptions\\InvalidArgumentException;\nuse Jiminny\\Models\\AskAnything\\AskAnythingPrompt;\nuse Jiminny\\Models\\AskAnything\\AskAnythingPromptTarget;\nuse Jiminny\\Models\\AskAnything\\UserAskAnythingPrompt;\nuse Jiminny\\Models\\Group;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AskAnythingRepository;\nuse Jiminny\\Repositories\\UserRepository;\n\nclass AskAnythingPromptService\n{\n public function __construct(\n private readonly AskAnythingRepository $askAnythingRepository,\n private readonly UserRepository $userRepository,\n private readonly GroupRepositoryInterface $groupRepository,\n ) {\n }\n\n /**\n * @return array<AskAnythingPromptDto>\n */\n public function get(User $user, AskAnythingPromptTarget $target): array\n {\n $prompts = $this->askAnythingRepository->findPromptsByUserAndTarget(\n $user,\n $target\n );\n\n $promptDtos = [];\n foreach ($prompts as $prompt) {\n $ownerUuid = null;\n if ($prompt->getOwner() !== null) {\n $ownerUuid = $prompt->getOwner()->getUuid();\n }\n $shareUsers = null;\n $shareGroups = null;\n\n // Provide users and groups only if owner of the prompt is current user\n if ($prompt->getOwnerId() === $user->getId()) {\n [$shareUsers, $shareGroups] = $this->getReceiverUuids($prompt);\n }\n\n $promptDtos[] = new AskAnythingPromptDto(\n $prompt->getUuid(),\n $prompt->getTitle(),\n $prompt->getContent(),\n $target,\n $ownerUuid,\n $shareUsers,\n $shareGroups,\n $prompt->has_reports,\n );\n }\n\n return $promptDtos;\n }\n\n /**\n * @param array<string> $shareUsersUuids\n * @param array<string> $shareGroupsUuids\n */\n public function create(\n User $user,\n string $title,\n string $content,\n AskAnythingPromptTarget $target,\n array $shareUsersUuids,\n array $shareGroupsUuids\n ): AskAnythingPromptDto {\n\n $shareUsers = $shareGroups = [];\n foreach ($shareUsersUuids as $userUuid) {\n $shareUsers[] = $this->userRepository->findByUuid($userUuid);\n }\n foreach ($shareGroupsUuids as $groupUuid) {\n $shareGroups[] = $this->groupRepository->findByUuid($groupUuid);\n }\n\n $prompt = $this->askAnythingRepository->createPrompt(\n $user,\n $target,\n $title,\n $content,\n $shareUsers,\n $shareGroups,\n );\n\n return new AskAnythingPromptDto(\n $prompt->getUuid(),\n $prompt->getTitle(),\n $prompt->getContent(),\n $target,\n $user->getUuid(),\n $shareUsersUuids,\n $shareGroupsUuids,\n $prompt->has_reports,\n );\n }\n\n /**\n * @param array<string> $shareUsersUuids\n * @param array<string> $shareGroupsUuids\n *\n * @throws InvalidArgumentException\n */\n public function edit(\n AskAnythingPrompt $prompt,\n User $user,\n string $title,\n string $content,\n array $shareUsersUuids,\n array $shareGroupsUuids\n ): AskAnythingPromptDto {\n $shareUsers = $shareGroups = [];\n foreach ($shareUsersUuids as $userUuid) {\n $shareUsers[] = $this->userRepository->findByUuid($userUuid);\n }\n foreach ($shareGroupsUuids as $groupUuid) {\n $shareGroups[] = $this->groupRepository->findByUuid($groupUuid);\n }\n\n if ($prompt->isDefaultPrompt()) {\n $this->askAnythingRepository->hidePromptForUser($prompt, $user);\n\n $newPrompt = $this->askAnythingRepository->createPrompt(\n $user,\n $prompt->getTarget(),\n $title,\n $content,\n $shareUsers,\n $shareGroups,\n );\n } elseif ($prompt->getOwnerId() === $user->getId()) {\n $newPrompt = $this->askAnythingRepository->editPrompt(\n $prompt,\n $title,\n $content,\n $shareUsers,\n $shareGroups,\n );\n } else {\n throw new InvalidArgumentException('Edit not allowed for prompt ' . $prompt->getUuid());\n }\n\n return new AskAnythingPromptDto(\n $newPrompt->getUuid(),\n $newPrompt->getTitle(),\n $newPrompt->getContent(),\n $newPrompt->getTarget(),\n $user->getUuid(),\n $shareUsersUuids,\n $shareGroupsUuids,\n $newPrompt->has_reports,\n );\n }\n\n public function delete(\n AskAnythingPrompt $prompt,\n User $user\n ): AskAnythingPrompt {\n if ($prompt->isDefaultPrompt()) {\n $this->askAnythingRepository->hidePromptForUser($prompt, $user);\n } elseif ($prompt->getOwnerId() === $user->getId()) {\n $userPrompt = $this->askAnythingRepository->findSharedPromptByUser($prompt->getId(), $user);\n $userPrompt?->delete();\n // For each relation, re-create the prompt for the receiver as their own\n $this->recreatePromptsForEachRelation($prompt);\n\n // Finally, delete the prompt\n $this->deletePromptIfNoRelations($prompt);\n } else {\n $userPrompt = $this->askAnythingRepository->findSharedPromptByUser($prompt->getId(), $user);\n $groupPrompt = $this->askAnythingRepository->findSharedPromptByUserGroup($prompt->getId(), $user);\n\n // If the prompt is shared directly with the user, then \"unshare\" it\n if ($userPrompt instanceof UserAskAnythingPrompt && $groupPrompt === null) {\n $userPrompt->delete();\n $this->deletePromptIfNoRelations($prompt);\n } elseif ($groupPrompt instanceof UserAskAnythingPrompt) {\n // If the prompt is shared with the user and the group, then hide it for this user\n $this->askAnythingRepository->hidePromptForUser($prompt, $user);\n } else {\n throw new InvalidArgumentException('Unknown delete allowance for prompt ' . $prompt->getUuid());\n }\n }\n\n return $prompt;\n }\n\n public function reorder(\n User $user,\n array $promptUuids,\n ): void {\n foreach ($promptUuids as $index => $promptUuid) {\n $prompt = $this->askAnythingRepository->getPromptByUuid($promptUuid);\n $this->askAnythingRepository->orderPromptForUser($prompt, $user, $index + 1);\n }\n }\n\n /**\n * @param AskAnythingPrompt $prompt\n *\n * @return array[array<string>, array<string>]\n */\n private function getReceiverUuids(AskAnythingPrompt $prompt): array\n {\n $shareUsers = [];\n $shareGroups = [];\n foreach ($this->askAnythingRepository->findSharedUsersAndGroupsByPromptId($prompt->getId()) as $sharedPrompt) {\n $sharedUser = $sharedPrompt->getUser();\n if ($sharedUser instanceof User && $sharedUser->isStatusActive()) {\n $shareUsers[] = $sharedUser->getUuid();\n }\n $sharedGroup = $sharedPrompt->getGroup();\n if ($sharedGroup instanceof Group) {\n $shareGroups[] = $sharedGroup->getUuid();\n }\n }\n\n return [$shareUsers, $shareGroups];\n }\n\n private function deletePromptIfNoRelations(AskAnythingPrompt $prompt): void\n {\n if ($this->askAnythingRepository->findSharedUsersAndGroupsByPromptId($prompt->getId())->isEmpty()) {\n // Disable and orphan any AutomatedReports that use this prompt\n $prompt->automatedReports()->withTrashed()->update([\n 'ask_anything_prompt_id' => null,\n 'status' => false,\n ]);\n\n // Delete only if there are no other relations to it.\n $this->askAnythingRepository->deletePrompt($prompt);\n }\n }\n\n private function recreatePromptsForEachRelation(AskAnythingPrompt $prompt): void\n {\n [$sharedUsersIds, $sharedUsersRemovedIds] = $this->recreatePromptsForUserRelations($prompt);\n $this->recreatePromptsForGroupRelations($prompt, $sharedUsersIds, $sharedUsersRemovedIds);\n }\n\n private function recreatePromptsForUserRelations(AskAnythingPrompt $prompt): array\n {\n $sharedUsersIds = [];\n $sharedUsersRemovedIds = [];\n foreach ($this->askAnythingRepository->findSharedUsersAndGroupsByPromptId($prompt->getId()) as $sharedPrompt) {\n $sharedUser = $sharedPrompt->getUser();\n if ($sharedPrompt->isRemoved() === true) {\n $sharedUsersRemovedIds[] = $sharedUser->getId();\n }\n if ($sharedPrompt->isRemoved() !== true && $sharedUser instanceof User && $sharedUser->isStatusActive()) {\n $sharedUsersIds[] = $sharedUser->getId();\n $this->askAnythingRepository->createPrompt(\n $sharedUser,\n $prompt->getTarget(),\n $prompt->getTitle(),\n $prompt->getContent(),\n [],\n [],\n );\n $sharedPrompt->delete();\n }\n }\n\n return [$sharedUsersIds, $sharedUsersRemovedIds];\n }\n\n private function recreatePromptsForGroupRelations(AskAnythingPrompt $prompt, array $sharedUsersIds, array $sharedUsersRemovedIds): void\n {\n foreach ($this->askAnythingRepository->findSharedUsersAndGroupsByPromptId($prompt->getId()) as $sharedPrompt) {\n $sharedGroup = $sharedPrompt->getGroup();\n if ($sharedGroup instanceof Group) {\n foreach ($sharedGroup->getMembers() as $member) {\n if (! in_array($member->getId(), $sharedUsersIds)\n && ! in_array($member->getId(), $sharedUsersRemovedIds)) {\n $sharedUsersIds[] = $member->getId();\n $this->askAnythingRepository->createPrompt(\n $member,\n $prompt->getTarget(),\n $prompt->getTitle(),\n $prompt->getContent(),\n [],\n [],\n );\n }\n }\n $sharedPrompt->delete();\n }\n }\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-1166252302841591546
|
1126354607917402622
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20676-delete-report-re Project: faVsco.js, menu
JY-20676-delete-report-related-objects, 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
4
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\AskAnything;
use Jiminny\Component\AskAnything\Dtos\AskAnythingPromptDto;
use Jiminny\Contracts\Repositories\GroupRepositoryInterface;
use Jiminny\Exceptions\InvalidArgumentException;
use Jiminny\Models\AskAnything\AskAnythingPrompt;
use Jiminny\Models\AskAnything\AskAnythingPromptTarget;
use Jiminny\Models\AskAnything\UserAskAnythingPrompt;
use Jiminny\Models\Group;
use Jiminny\Models\User;
use Jiminny\Repositories\AskAnythingRepository;
use Jiminny\Repositories\UserRepository;
class AskAnythingPromptService
{
public function __construct(
private readonly AskAnythingRepository $askAnythingRepository,
private readonly UserRepository $userRepository,
private readonly GroupRepositoryInterface $groupRepository,
) {
}
/**
* @return array<AskAnythingPromptDto>
*/
public function get(User $user, AskAnythingPromptTarget $target): array
{
$prompts = $this->askAnythingRepository->findPromptsByUserAndTarget(
$user,
$target
);
$promptDtos = [];
foreach ($prompts as $prompt) {
$ownerUuid = null;
if ($prompt->getOwner() !== null) {
$ownerUuid = $prompt->getOwner()->getUuid();
}
$shareUsers = null;
$shareGroups = null;
// Provide users and groups only if owner of the prompt is current user
if ($prompt->getOwnerId() === $user->getId()) {
[$shareUsers, $shareGroups] = $this->getReceiverUuids($prompt);
}
$promptDtos[] = new AskAnythingPromptDto(
$prompt->getUuid(),
$prompt->getTitle(),
$prompt->getContent(),
$target,
$ownerUuid,
$shareUsers,
$shareGroups,
$prompt->has_reports,
);
}
return $promptDtos;
}
/**
* @param array<string> $shareUsersUuids
* @param array<string> $shareGroupsUuids
*/
public function create(
User $user,
string $title,
string $content,
AskAnythingPromptTarget $target,
array $shareUsersUuids,
array $shareGroupsUuids
): AskAnythingPromptDto {
$shareUsers = $shareGroups = [];
foreach ($shareUsersUuids as $userUuid) {
$shareUsers[] = $this->userRepository->findByUuid($userUuid);
}
foreach ($shareGroupsUuids as $groupUuid) {
$shareGroups[] = $this->groupRepository->findByUuid($groupUuid);
}
$prompt = $this->askAnythingRepository->createPrompt(
$user,
$target,
$title,
$content,
$shareUsers,
$shareGroups,
);
return new AskAnythingPromptDto(
$prompt->getUuid(),
$prompt->getTitle(),
$prompt->getContent(),
$target,
$user->getUuid(),
$shareUsersUuids,
$shareGroupsUuids,
$prompt->has_reports,
);
}
/**
* @param array<string> $shareUsersUuids
* @param array<string> $shareGroupsUuids
*
* @throws InvalidArgumentException
*/
public function edit(
AskAnythingPrompt $prompt,
User $user,
string $title,
string $content,
array $shareUsersUuids,
array $shareGroupsUuids
): AskAnythingPromptDto {
$shareUsers = $shareGroups = [];
foreach ($shareUsersUuids as $userUuid) {
$shareUsers[] = $this->userRepository->findByUuid($userUuid);
}
foreach ($shareGroupsUuids as $groupUuid) {
$shareGroups[] = $this->groupRepository->findByUuid($groupUuid);
}
if ($prompt->isDefaultPrompt()) {
$this->askAnythingRepository->hidePromptForUser($prompt, $user);
$newPrompt = $this->askAnythingRepository->createPrompt(
$user,
$prompt->getTarget(),
$title,
$content,
$shareUsers,
$shareGroups,
);
} elseif ($prompt->getOwnerId() === $user->getId()) {
$newPrompt = $this->askAnythingRepository->editPrompt(
$prompt,
$title,
$content,
$shareUsers,
$shareGroups,
);
} else {
throw new InvalidArgumentException('Edit not allowed for prompt ' . $prompt->getUuid());
}
return new AskAnythingPromptDto(
$newPrompt->getUuid(),
$newPrompt->getTitle(),
$newPrompt->getContent(),
$newPrompt->getTarget(),
$user->getUuid(),
$shareUsersUuids,
$shareGroupsUuids,
$newPrompt->has_reports,
);
}
public function delete(
AskAnythingPrompt $prompt,
User $user
): AskAnythingPrompt {
if ($prompt->isDefaultPrompt()) {
$this->askAnythingRepository->hidePromptForUser($prompt, $user);
} elseif ($prompt->getOwnerId() === $user->getId()) {
$userPrompt = $this->askAnythingRepository->findSharedPromptByUser($prompt->getId(), $user);
$userPrompt?->delete();
// For each relation, re-create the prompt for the receiver as their own
$this->recreatePromptsForEachRelation($prompt);
// Finally, delete the prompt
$this->deletePromptIfNoRelations($prompt);
} else {
$userPrompt = $this->askAnythingRepository->findSharedPromptByUser($prompt->getId(), $user);
$groupPrompt = $this->askAnythingRepository->findSharedPromptByUserGroup($prompt->getId(), $user);
// If the prompt is shared directly with the user, then "unshare" it
if ($userPrompt instanceof UserAskAnythingPrompt && $groupPrompt === null) {
$userPrompt->delete();
$this->deletePromptIfNoRelations($prompt);
} elseif ($groupPrompt instanceof UserAskAnythingPrompt) {
// If the prompt is shared with the user and the group, then hide it for this user
$this->askAnythingRepository->hidePromptForUser($prompt, $user);
} else {
throw new InvalidArgumentException('Unknown delete allowance for prompt ' . $prompt->getUuid());
}
}
return $prompt;
}
public function reorder(
User $user,
array $promptUuids,
): void {
foreach ($promptUuids as $index => $promptUuid) {
$prompt = $this->askAnythingRepository->getPromptByUuid($promptUuid);
$this->askAnythingRepository->orderPromptForUser($prompt, $user, $index + 1);
}
}
/**
* @param AskAnythingPrompt $prompt
*
* @return array[array<string>, array<string>]
*/
private function getReceiverUuids(AskAnythingPrompt $prompt): array
{
$shareUsers = [];
$shareGroups = [];
foreach ($this->askAnythingRepository->findSharedUsersAndGroupsByPromptId($prompt->getId()) as $sharedPrompt) {
$sharedUser = $sharedPrompt->getUser();
if ($sharedUser instanceof User && $sharedUser->isStatusActive()) {
$shareUsers[] = $sharedUser->getUuid();
}
$sharedGroup = $sharedPrompt->getGroup();
if ($sharedGroup instanceof Group) {
$shareGroups[] = $sharedGroup->getUuid();
}
}
return [$shareUsers, $shareGroups];
}
private function deletePromptIfNoRelations(AskAnythingPrompt $prompt): void
{
if ($this->askAnythingRepository->findSharedUsersAndGroupsByPromptId($prompt->getId())->isEmpty()) {
// Disable and orphan any AutomatedReports that use this prompt
$prompt->automatedReports()->withTrashed()->update([
'ask_anything_prompt_id' => null,
'status' => false,
]);
// Delete only if there are no other relations to it.
$this->askAnythingRepository->deletePrompt($prompt);
}
}
private function recreatePromptsForEachRelation(AskAnythingPrompt $prompt): void
{
[$sharedUsersIds, $sharedUsersRemovedIds] = $this->recreatePromptsForUserRelations($prompt);
$this->recreatePromptsForGroupRelations($prompt, $sharedUsersIds, $sharedUsersRemovedIds);
}
private function recreatePromptsForUserRelations(AskAnythingPrompt $prompt): array
{
$sharedUsersIds = [];
$sharedUsersRemovedIds = [];
foreach ($this->askAnythingRepository->findSharedUsersAndGroupsByPromptId($prompt->getId()) as $sharedPrompt) {
$sharedUser = $sharedPrompt->getUser();
if ($sharedPrompt->isRemoved() === true) {
$sharedUsersRemovedIds[] = $sharedUser->getId();
}
if ($sharedPrompt->isRemoved() !== true && $sharedUser instanceof User && $sharedUser->isStatusActive()) {
$sharedUsersIds[] = $sharedUser->getId();
$this->askAnythingRepository->createPrompt(
$sharedUser,
$prompt->getTarget(),
$prompt->getTitle(),
$prompt->getContent(),
[],
[],
);
$sharedPrompt->delete();
}
}
return [$sharedUsersIds, $sharedUsersRemovedIds];
}
private function recreatePromptsForGroupRelations(AskAnythingPrompt $prompt, array $sharedUsersIds, array $sharedUsersRemovedIds): void
{
foreach ($this->askAnythingRepository->findSharedUsersAndGroupsByPromptId($prompt->getId()) as $sharedPrompt) {
$sharedGroup = $sharedPrompt->getGroup();
if ($sharedGroup instanceof Group) {
foreach ($sharedGroup->getMembers() as $member) {
if (! in_array($member->getId(), $sharedUsersIds)
&& ! in_array($member->getId(), $sharedUsersRemovedIds)) {
$sharedUsersIds[] = $member->getId();
$this->askAnythingRepository->createPrompt(
$member,
$prompt->getTarget(),
$prompt->getTitle(),
$prompt->getContent(),
[],
[],
);
}
}
$sharedPrompt->delete();
}
}
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}...
|
56584
|
NULL
|
NULL
|
NULL
|
|
56490
|
NULL
|
0
|
2026-05-19T08:07:55.646791+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779178075646_m2.jpg...
|
Firefox
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PnostormFV faVsco.js°9 JY-20676-delete-report-rela PnostormFV faVsco.js°9 JY-20676-delete-report-related-objectsProiect© ConferenceService.php© InsightSeatService.php©Instantmeeuingservice.ongC lpapiclient.onp© IpapiService.phpcParuicioantsnareservice.onoPlaybackVideoOnlvService.phpC) PlavbookCategorvService.pho@ PlaylistGeneratorinterface.phpC) ResolveTeamermconnection.oh(c) SimolehrottleService.ono(C) SlackService.oho(C) SocialAccountService.oho(C) SoftPhoneService.oho© TeamDeactivatedService.php© TeamOwnerService.php© TeamService.php© TranscodeParameterResolver.php©UserService.php© Uuid.php> D Traits> D UseCases> D UserD Utils> CJ Validation> Ovophp helpers.php0 InitialFrontendState.php© Jiminny.php© Plan.php© Serializer.phpc)TeamscimDetalls.ono> M bootstrap>O builda contid>O contrib.> database>M docs>M front-endi> C langMnode modules librarv rooti>D phpstanM nublic> O resourcesv Mroutesphp api.phpphp api_v2.phppnp console.ono© AskAnythingPromptServiceTest.php84310/2AskJiminnyReportActivityServiceTest vAskJiminnykeporscontroller.pnp© AskAnythingPromptDto.phpA25V3 V16 A* API routes.* osee Jaminnu Providens RouteServzceprovzden* @var Router Srouteruse...// mcp.audit MUST stay outermost so its Snext(Srequest) call wraps the auth// and tier guards. Otherwise 401 (auth:api) and 403 (mcp.tier) rejections// short-circuit before McpAuditMiddleware::handle ever runs and we lose// audit rows for exactly the requests the security log most needs to capture.// McpAuditMiddleware::writeAuditRow null-checks Srequest->user, so writing// pre-auth is safeMcp: :web( route: '/mcp', serverClass: JiminnyServer::class)->middleware(['mcp.audit''mcp.tier']);29 Ф >34 0 >45 đ >> Srouter->group([ 'middleware' => ['auth:api']]static function (Router Srouter): void {...}):118Srouter->group([ 'middleware' => ['auth:api']].static function (Router Srouter): void {...}):> Srouter->group(['middleware' => ['api']], static function (Router Srouter): void {...}):- 131Srouter->aroup(['prefix' => 'user']. static function (Router Srouter): void {...}).1156 07> Srouter->qroup(T'middleware' => ['authrani'], 'prefix' => 'sms']. static function (Router Srouter): vol146 G>Srouter->aroupdi 'middleware' => 'auth:aoi', static function Router Srouter): void «...).151 CSrouter->aroundi'nrefix' = "nagel, "middlewarel => T'ant', lauthran'l static function O use Srou$router->group(['prefix' => 'partners', 'middleware' => 'auth:partner-api'], static function () use ($› Srouter->group(['prefix' => 'activity', 'middleware' => 'api'], static function ( use ($router): void› Srouter->group(['middleware' => ['auth:api']], static function @ use (Srouter) {...});> $router->group(['middleware' => ['auth:api']], static function (Router Srouter): void {...});Srouter->group(finnofivt =s Ilonnontuni+v/Sonnontunitvlt'middleware' => ['api']].static tunction (Router srouter: vo1d ...= custom.log= laravel.log« SF jiminny@localhost]4 HS_local [jiminny@localhost]& console [PROD]# console [euyA console [STAGING]© CoachingFeedbackCoachUserln.php Xstohedeclare(scrict_cypes=l)nnamespace Jiminny Component Activ1tySearch Filterder1n1t1on:final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface1usadeorivate const int No GROUP 10 = 999orivate UserRenository SuserRenository:public function __construct(UserRepository $userRepository)f...hpublic function shouldApplyQueries: boolf...}public function getQueries: FilterDefinitionQueryCollection{...}public function toArray@: array{...hprivate function getOptions(): array{...}public function getValue®: array{...}private function getDefaultValue: array{...}public function aetValidationRules(2strina Sorefix = null): arrav{...}public function aetSortOrder@: intf...}public function shouldBeIncluded(Team $team): bool{...}CascadeAsk Jiminny Report M100% 152• lue Ty May 11•0/:04+O •Per vour rules (no unit tests for controllers, no factories), the controller test file | created isn't ideal-AutomatedReport andiAskAnythingPrompt don't have factories and the rule says not to write tests for controllers. Let me remove that file° iusers/Lukas/ 1miny/app/tests/Feature/Htp/Control1ers/APL/VZ/Ask3ininyReperes contrel1etest" SavedSearchcRUdFeatureTest.ono7 7 tasks doneAll tasks comoleteSummaryChanges Made1. has_reports flag on listing endpointsSearch.php - Added has reports to sappends and a gethasReportsAttribute accessor returning whether any relatedAutomatedReport exists. The saved-search list endpoint now includes has_reports.AskAnvthinaPromot.oho - Added has renorts to saopends anda getHasReportsAttribute@ accessonAskAnythingPromptDto.php - Added bool ShasReports = false constructor argument and emitted has reports in toArray ().AskAnythingPromptService.php - Pass Sprompt->has reports into all three DTO constructions (get, create, edit).2. Disable related reports on deletionActivitvController.ohn: 1116-1131 - deleteActivitvSearch() now undates related renorts with f'activitv search iAskAnythingPromptService.php -deletePromptIfNoRelations() now updates related reports with ['ask anything promot id' = null. 'status' => falsel.3. Toaale validationAskJiminnyReportsController.php:126-169 - In toggleStatus(), when enabled=true and the report is an Ask Jiminnyreport, returns 422 if either activity_search_id or ask_anything_prompt_id is null . Disabling is always allowed.#. TectsAskAnythingPromptServiceTest.php - Updated two existing update() mock expectations to match the new payload (1'ask anvthina promot id' = null."status' = falsel))Per your rules I did not add unit tests for the controller. The existing SavedSearchCRUDFeatureTest covers the searchdelete flow. backend cervice tect covers nromnt delete navloadiG..l..* Reiect allAccent alliAsk anvthina (884-L)<> Code Claude Qnus 1.7 MediumW Windsurf TeamPo 4 spac...
|
NULL
|
4740595667023737903
|
NULL
|
click
|
ocr
|
NULL
|
PnostormFV faVsco.js°9 JY-20676-delete-report-rela PnostormFV faVsco.js°9 JY-20676-delete-report-related-objectsProiect© ConferenceService.php© InsightSeatService.php©Instantmeeuingservice.ongC lpapiclient.onp© IpapiService.phpcParuicioantsnareservice.onoPlaybackVideoOnlvService.phpC) PlavbookCategorvService.pho@ PlaylistGeneratorinterface.phpC) ResolveTeamermconnection.oh(c) SimolehrottleService.ono(C) SlackService.oho(C) SocialAccountService.oho(C) SoftPhoneService.oho© TeamDeactivatedService.php© TeamOwnerService.php© TeamService.php© TranscodeParameterResolver.php©UserService.php© Uuid.php> D Traits> D UseCases> D UserD Utils> CJ Validation> Ovophp helpers.php0 InitialFrontendState.php© Jiminny.php© Plan.php© Serializer.phpc)TeamscimDetalls.ono> M bootstrap>O builda contid>O contrib.> database>M docs>M front-endi> C langMnode modules librarv rooti>D phpstanM nublic> O resourcesv Mroutesphp api.phpphp api_v2.phppnp console.ono© AskAnythingPromptServiceTest.php84310/2AskJiminnyReportActivityServiceTest vAskJiminnykeporscontroller.pnp© AskAnythingPromptDto.phpA25V3 V16 A* API routes.* osee Jaminnu Providens RouteServzceprovzden* @var Router Srouteruse...// mcp.audit MUST stay outermost so its Snext(Srequest) call wraps the auth// and tier guards. Otherwise 401 (auth:api) and 403 (mcp.tier) rejections// short-circuit before McpAuditMiddleware::handle ever runs and we lose// audit rows for exactly the requests the security log most needs to capture.// McpAuditMiddleware::writeAuditRow null-checks Srequest->user, so writing// pre-auth is safeMcp: :web( route: '/mcp', serverClass: JiminnyServer::class)->middleware(['mcp.audit''mcp.tier']);29 Ф >34 0 >45 đ >> Srouter->group([ 'middleware' => ['auth:api']]static function (Router Srouter): void {...}):118Srouter->group([ 'middleware' => ['auth:api']].static function (Router Srouter): void {...}):> Srouter->group(['middleware' => ['api']], static function (Router Srouter): void {...}):- 131Srouter->aroup(['prefix' => 'user']. static function (Router Srouter): void {...}).1156 07> Srouter->qroup(T'middleware' => ['authrani'], 'prefix' => 'sms']. static function (Router Srouter): vol146 G>Srouter->aroupdi 'middleware' => 'auth:aoi', static function Router Srouter): void «...).151 CSrouter->aroundi'nrefix' = "nagel, "middlewarel => T'ant', lauthran'l static function O use Srou$router->group(['prefix' => 'partners', 'middleware' => 'auth:partner-api'], static function () use ($› Srouter->group(['prefix' => 'activity', 'middleware' => 'api'], static function ( use ($router): void› Srouter->group(['middleware' => ['auth:api']], static function @ use (Srouter) {...});> $router->group(['middleware' => ['auth:api']], static function (Router Srouter): void {...});Srouter->group(finnofivt =s Ilonnontuni+v/Sonnontunitvlt'middleware' => ['api']].static tunction (Router srouter: vo1d ...= custom.log= laravel.log« SF jiminny@localhost]4 HS_local [jiminny@localhost]& console [PROD]# console [euyA console [STAGING]© CoachingFeedbackCoachUserln.php Xstohedeclare(scrict_cypes=l)nnamespace Jiminny Component Activ1tySearch Filterder1n1t1on:final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface1usadeorivate const int No GROUP 10 = 999orivate UserRenository SuserRenository:public function __construct(UserRepository $userRepository)f...hpublic function shouldApplyQueries: boolf...}public function getQueries: FilterDefinitionQueryCollection{...}public function toArray@: array{...hprivate function getOptions(): array{...}public function getValue®: array{...}private function getDefaultValue: array{...}public function aetValidationRules(2strina Sorefix = null): arrav{...}public function aetSortOrder@: intf...}public function shouldBeIncluded(Team $team): bool{...}CascadeAsk Jiminny Report M100% 152• lue Ty May 11•0/:04+O •Per vour rules (no unit tests for controllers, no factories), the controller test file | created isn't ideal-AutomatedReport andiAskAnythingPrompt don't have factories and the rule says not to write tests for controllers. Let me remove that file° iusers/Lukas/ 1miny/app/tests/Feature/Htp/Control1ers/APL/VZ/Ask3ininyReperes contrel1etest" SavedSearchcRUdFeatureTest.ono7 7 tasks doneAll tasks comoleteSummaryChanges Made1. has_reports flag on listing endpointsSearch.php - Added has reports to sappends and a gethasReportsAttribute accessor returning whether any relatedAutomatedReport exists. The saved-search list endpoint now includes has_reports.AskAnvthinaPromot.oho - Added has renorts to saopends anda getHasReportsAttribute@ accessonAskAnythingPromptDto.php - Added bool ShasReports = false constructor argument and emitted has reports in toArray ().AskAnythingPromptService.php - Pass Sprompt->has reports into all three DTO constructions (get, create, edit).2. Disable related reports on deletionActivitvController.ohn: 1116-1131 - deleteActivitvSearch() now undates related renorts with f'activitv search iAskAnythingPromptService.php -deletePromptIfNoRelations() now updates related reports with ['ask anything promot id' = null. 'status' => falsel.3. Toaale validationAskJiminnyReportsController.php:126-169 - In toggleStatus(), when enabled=true and the report is an Ask Jiminnyreport, returns 422 if either activity_search_id or ask_anything_prompt_id is null . Disabling is always allowed.#. TectsAskAnythingPromptServiceTest.php - Updated two existing update() mock expectations to match the new payload (1'ask anvthina promot id' = null."status' = falsel))Per your rules I did not add unit tests for the controller. The existing SavedSearchCRUDFeatureTest covers the searchdelete flow. backend cervice tect covers nromnt delete navloadiG..l..* Reiect allAccent alliAsk anvthina (884-L)<> Code Claude Qnus 1.7 MediumW Windsurf TeamPo 4 spac...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
56489
|
NULL
|
0
|
2026-05-19T08:07:55.630753+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779178075630_m1.jpg...
|
Firefox
|
NULL
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpAPPDOCKERO ₴1D SlackFileEditViewGoHistoryWindowHelpAPPDOCKERO ₴1DEV (-zsh)₴82app/Jobs/Crm/MatchActivityCrmData.phpapp/Jobs/Middleware/HandleHubspotRateLimit.phpAPP (-zsl47++++++*42++++++*app/Mcp/Servers/JiminnyServer.phpapp/Mcp/Tools/GetMeTool.php157++++++app/Models/Feature/FeatureEnum.phpapp/Services/Activity/HubSpot/ProviderResolver.php+-app/Services/Activity/HubSpot/ProviderResolverInterface.phpapp/Services/Activity/HubSpot/Providers/Provider.phpapp/Services/Activity/HubSpot/Providers/ProviderKixie.php+-app/Services/Activity/HubSpot/Providers/Provider0rum.phpapp/Services/Activity/HubSpot/Providers/ProviderTwilio.phpapp/Services/Activity/HubSpot/Providers/ProviderTwilioFlex.phpapp/Services/Activity/HubSpot/Service.phpapp/Services/Crm/Hubspot/Client.phpapp/Services/Crm/Hubspot/HubspotClientInterface.phpapp/Services/Crm/Hubspot/Pagination/HubspotPaginationService.phpapp/Services/Crm/Hubspot/Pagination/PaginationState.phpdatabase/migrations/2026_05_13_124153_create_mcp_feature_flag.phptests/Feature/Mcp/GetMeToolFeatureTest.phptests/Feature/Mcp/ListCallsToolFeatureTest.phptests/Feature/Mcp/McpTestHelpersTrait.phptests/Unit/Component/ES/ChunkSizeTest.phptests/Unit/Component/ES/Processor/DT0s/SelectionListTest.phptests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.phptests/Unit/Component/MeetingBot/Service/ParticipantMatcherTest.phptests/Unit/Exceptions/RateLimitExceptionTest.php97++++++-132++++++•15++++++21++++-2+-25++++++-140++++++-+-19++++++50++++++27++++++=39++++++-6856++++++-tests/Unit/Jobs/Crm/MatchActivityCrmDataTest.phptests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.phptests/Unit/Services/Activity/HubSpot/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ClientTest.phptests/Unit/Services/Crm/Hubspot/Pagination/HubspotPaginationServiceTest.php151++++++-109++++++-250++++++283++++++37 files changed, 1587 insertions(+), 344 deletions(-)create mode 100644 app/Component/ES/ChunkSize.phpcreate mode 100644 app/Jobs/Middleware/HandleHubspotRateLimit.phpcreate mode 100644 app/Mcp/Tools/GetMeTool.phpcreate mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.phpcreate mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.phpcreate mode 100644 tests/Unit/Component/ES/ChunkSizeTest.phpcreate mode 100644 tests/Unit/Exceptions/RateLimitExceptionTest.phpAlready up to date.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20676-delete-reSwitched to a new branch 'JY-20676-delete-report-related-objects'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20676-delete-report-related-obHomeDMsActivityFilesLaterMoreED→Jiminny ...# jminny-Dg# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi...• Direct messages€. Vasil Vasilev8. Nikolay Yankov. Galya Dimitrova. Aneliya Angelovaã. Stefka Stoyanova. Stoyan Tomovd Todor Stamatov "Kdi. Mario GeorgievNikolay Ivanovdo James Graham2 Stoyan TanevRo Steliyan GeorgievLukas Kovalik y…..AppsJira CloudToastSupport Daily - in 3h 53 m100% (8• Tue 19 May 11:07:55Describe what you are looking forNikolay Yankov6 0MessagesAdd canvasO Files+Nikolay YankovYesterday ~имаше ли нещь . y...Lukas Kovalik 2:28 PMтрябва да си вързан към SF да работиNikolay Yankov 2:28 PMaxaaaNikolay Yankov 2:41 PMимаме approve на PRда го даваме за QA?Lukas Kovalik 2:42 PMдаNikolay Yankov 3:02 PMтестове фейлватрьннах го 2 пътиToday ~Nikolay Yankov 10:05 AM/api/v2/user/ask-anything-prompts?target=on_demandhas_reports/api/v2/user/ask-anything-prompts/3381a35f-f1a3-431d-9510-bd079cd80ed6DELETEV10:10/api/v1/activity/saved-searchMessage Nikolay Yankov+Aa...
|
NULL
|
-9153448785374662746
|
NULL
|
click
|
ocr
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpAPPDOCKERO ₴1D SlackFileEditViewGoHistoryWindowHelpAPPDOCKERO ₴1DEV (-zsh)₴82app/Jobs/Crm/MatchActivityCrmData.phpapp/Jobs/Middleware/HandleHubspotRateLimit.phpAPP (-zsl47++++++*42++++++*app/Mcp/Servers/JiminnyServer.phpapp/Mcp/Tools/GetMeTool.php157++++++app/Models/Feature/FeatureEnum.phpapp/Services/Activity/HubSpot/ProviderResolver.php+-app/Services/Activity/HubSpot/ProviderResolverInterface.phpapp/Services/Activity/HubSpot/Providers/Provider.phpapp/Services/Activity/HubSpot/Providers/ProviderKixie.php+-app/Services/Activity/HubSpot/Providers/Provider0rum.phpapp/Services/Activity/HubSpot/Providers/ProviderTwilio.phpapp/Services/Activity/HubSpot/Providers/ProviderTwilioFlex.phpapp/Services/Activity/HubSpot/Service.phpapp/Services/Crm/Hubspot/Client.phpapp/Services/Crm/Hubspot/HubspotClientInterface.phpapp/Services/Crm/Hubspot/Pagination/HubspotPaginationService.phpapp/Services/Crm/Hubspot/Pagination/PaginationState.phpdatabase/migrations/2026_05_13_124153_create_mcp_feature_flag.phptests/Feature/Mcp/GetMeToolFeatureTest.phptests/Feature/Mcp/ListCallsToolFeatureTest.phptests/Feature/Mcp/McpTestHelpersTrait.phptests/Unit/Component/ES/ChunkSizeTest.phptests/Unit/Component/ES/Processor/DT0s/SelectionListTest.phptests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.phptests/Unit/Component/MeetingBot/Service/ParticipantMatcherTest.phptests/Unit/Exceptions/RateLimitExceptionTest.php97++++++-132++++++•15++++++21++++-2+-25++++++-140++++++-+-19++++++50++++++27++++++=39++++++-6856++++++-tests/Unit/Jobs/Crm/MatchActivityCrmDataTest.phptests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.phptests/Unit/Services/Activity/HubSpot/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ClientTest.phptests/Unit/Services/Crm/Hubspot/Pagination/HubspotPaginationServiceTest.php151++++++-109++++++-250++++++283++++++37 files changed, 1587 insertions(+), 344 deletions(-)create mode 100644 app/Component/ES/ChunkSize.phpcreate mode 100644 app/Jobs/Middleware/HandleHubspotRateLimit.phpcreate mode 100644 app/Mcp/Tools/GetMeTool.phpcreate mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.phpcreate mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.phpcreate mode 100644 tests/Unit/Component/ES/ChunkSizeTest.phpcreate mode 100644 tests/Unit/Exceptions/RateLimitExceptionTest.phpAlready up to date.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20676-delete-reSwitched to a new branch 'JY-20676-delete-report-related-objects'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20676-delete-report-related-obHomeDMsActivityFilesLaterMoreED→Jiminny ...# jminny-Dg# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi...• Direct messages€. Vasil Vasilev8. Nikolay Yankov. Galya Dimitrova. Aneliya Angelovaã. Stefka Stoyanova. Stoyan Tomovd Todor Stamatov "Kdi. Mario GeorgievNikolay Ivanovdo James Graham2 Stoyan TanevRo Steliyan GeorgievLukas Kovalik y…..AppsJira CloudToastSupport Daily - in 3h 53 m100% (8• Tue 19 May 11:07:55Describe what you are looking forNikolay Yankov6 0MessagesAdd canvasO Files+Nikolay YankovYesterday ~имаше ли нещь . y...Lukas Kovalik 2:28 PMтрябва да си вързан към SF да работиNikolay Yankov 2:28 PMaxaaaNikolay Yankov 2:41 PMимаме approve на PRда го даваме за QA?Lukas Kovalik 2:42 PMдаNikolay Yankov 3:02 PMтестове фейлватрьннах го 2 пътиToday ~Nikolay Yankov 10:05 AM/api/v2/user/ask-anything-prompts?target=on_demandhas_reports/api/v2/user/ask-anything-prompts/3381a35f-f1a3-431d-9510-bd079cd80ed6DELETEV10:10/api/v1/activity/saved-searchMessage Nikolay Yankov+Aa...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
56377
|
NULL
|
0
|
2026-05-19T08:02:52.098831+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779177772098_m1.jpg...
|
Firefox
|
NULL
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpAPPDOCKERO ₴1D SlackFileEditViewGoHistoryWindowHelpAPPDOCKERO ₴1DEV (-zsh)₴82app/Jobs/Crm/MatchActivityCrmData.phpapp/Jobs/Middleware/HandleHubspotRateLimit.phpAPP (-zsl47++++++p42++++++*app/Mcp/Servers/JiminnyServer.phpapp/Mcp/Tools/GetMeTool.php157++++++•app/Models/Feature/FeatureEnum.phpapp/Services/Activity/HubSpot/ProviderResolver.php+-app/Services/Activity/HubSpot/ProviderResolverInterface.phpapp/Services/Activity/HubSpot/Providers/Provider.phpapp/Services/Activity/HubSpot/Providers/ProviderKixie.php+-app/Services/Activity/HubSpot/Providers/Provider0rum.phpapp/Services/Activity/HubSpot/Providers/ProviderTwilio.phpapp/Services/Activity/HubSpot/Providers/ProviderTwilioFlex.phpapp/Services/Activity/HubSpot/Service.phpapp/Services/Crm/Hubspot/Client.phpapp/Services/Crm/Hubspot/HubspotClientInterface.phpapp/Services/Crm/Hubspot/Pagination/HubspotPaginationService.phpapp/Services/Crm/Hubspot/Pagination/PaginationState.phpdatabase/migrations/2026_05_13_124153_create_mcp_feature_flag.phptests/Feature/Mcp/GetMeToolFeatureTest.phptests/Feature/Mcp/ListCallsToolFeatureTest.phptests/Feature/Mcp/McpTestHelpersTrait.phptests/Unit/Component/ES/ChunkSizeTest.phptests/Unit/Component/ES/Processor/DT0s/SelectionListTest.phptests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.phptests/Unit/Component/MeetingBot/Service/ParticipantMatcherTest.phptests/Unit/Exceptions/RateLimitExceptionTest.php97++++++-132++++++•15++++++21++++--2+-25++++++.140++++++•2+-19++++++50++++++27++++++39++++++6856++++++•tests/Unit/Jobs/Crm/MatchActivityCrmDataTest.phptests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.phptests/Unit/Services/Activity/HubSpot/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ClientTest.phptests/Unit/Services/Crm/Hubspot/Pagination/HubspotPaginationServiceTest.php151++++++-109++++++-250++++++283++++++.37 files changed, 1587 insertions(+), 344 deletions(-)create mode 100644 app/Component/ES/ChunkSize.phpcreate mode 100644 app/Jobs/Middleware/HandleHubspotRateLimit.phpcreate mode 100644 app/Mcp/Tools/GetMeTool.phpcreate mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.phpcreate mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.phpcreate mode 100644 tests/Unit/Component/ES/ChunkSizeTest.phpcreate mode 100644 tests/Unit/Exceptions/RateLimitExceptionTest.phpcreate mode 100644 tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.phplukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pullAlready up to date.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20676-delete-reSwitched to a new branch 'JY-20676-delete-report-related-objects'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20676-delete-report-related-ob•HomeDMsActivityFilesLaterMoreSupport Daily - in 3h 58 m100% C78•Tue 19 May 11:02:51ED→QDescribe what you are looking forJiminny ...# bugs# confusion-clinic# curiosity_lab# engineering# general# jiminny-bg# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi...Direct messages8. Vasil Vasilevo Nikolay YankovP. Galya Dimitrova®. Aneliya Angelovad. Stefka Stoyanova. Stoyan Tomovd Todor Stamatov "KM. Mario GeorgievNikolay IvanovJames GrahamStoyan TanevUnread mentions# the_people_of jimi...426 0• MessagesC Files+NewTodayHStefka Stoy¿Hi J team,I wanted to share that our Lead Developer IlianKyuchukov has decided to move on from Jiminny topursue a new opportunity. While we're really sad tosee them go, we're also excited for him and thisnext chapter in his professional journey.Ilian's last working day will be 14 July, so we stillhave some time together before then. Over thecoming weeks, please make the most of hisknowledge, experience, and context so we canensure a smooth transition across the team.It's hard to overstate the impact llian has had here- from shaping the product and solving toughproblems to supporting teammates and helpingbuild the product we have today. We're incrediblygrateful for everything he contributed over this 2years he was with engineering team.Just wanted to share the news openly witheveryone and say a huge thanks to llian foreverything so far. You Please join me in wishing himall the very best for what comes next.We start looking for a Full-Stack Software Engineer,so if you know anyone you believe will fit, pleasecontact me or Mira directly AMessage #the_people_of_jiminny+Aa...
|
NULL
|
-6924353142476997904
|
NULL
|
visual_change
|
ocr
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpAPPDOCKERO ₴1D SlackFileEditViewGoHistoryWindowHelpAPPDOCKERO ₴1DEV (-zsh)₴82app/Jobs/Crm/MatchActivityCrmData.phpapp/Jobs/Middleware/HandleHubspotRateLimit.phpAPP (-zsl47++++++p42++++++*app/Mcp/Servers/JiminnyServer.phpapp/Mcp/Tools/GetMeTool.php157++++++•app/Models/Feature/FeatureEnum.phpapp/Services/Activity/HubSpot/ProviderResolver.php+-app/Services/Activity/HubSpot/ProviderResolverInterface.phpapp/Services/Activity/HubSpot/Providers/Provider.phpapp/Services/Activity/HubSpot/Providers/ProviderKixie.php+-app/Services/Activity/HubSpot/Providers/Provider0rum.phpapp/Services/Activity/HubSpot/Providers/ProviderTwilio.phpapp/Services/Activity/HubSpot/Providers/ProviderTwilioFlex.phpapp/Services/Activity/HubSpot/Service.phpapp/Services/Crm/Hubspot/Client.phpapp/Services/Crm/Hubspot/HubspotClientInterface.phpapp/Services/Crm/Hubspot/Pagination/HubspotPaginationService.phpapp/Services/Crm/Hubspot/Pagination/PaginationState.phpdatabase/migrations/2026_05_13_124153_create_mcp_feature_flag.phptests/Feature/Mcp/GetMeToolFeatureTest.phptests/Feature/Mcp/ListCallsToolFeatureTest.phptests/Feature/Mcp/McpTestHelpersTrait.phptests/Unit/Component/ES/ChunkSizeTest.phptests/Unit/Component/ES/Processor/DT0s/SelectionListTest.phptests/Unit/Component/ES/Processor/TargetEntitiesSelectorTest.phptests/Unit/Component/MeetingBot/Service/ParticipantMatcherTest.phptests/Unit/Exceptions/RateLimitExceptionTest.php97++++++-132++++++•15++++++21++++--2+-25++++++.140++++++•2+-19++++++50++++++27++++++39++++++6856++++++•tests/Unit/Jobs/Crm/MatchActivityCrmDataTest.phptests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.phptests/Unit/Services/Activity/HubSpot/ServiceTest.phptests/Unit/Services/Crm/Hubspot/ClientTest.phptests/Unit/Services/Crm/Hubspot/Pagination/HubspotPaginationServiceTest.php151++++++-109++++++-250++++++283++++++.37 files changed, 1587 insertions(+), 344 deletions(-)create mode 100644 app/Component/ES/ChunkSize.phpcreate mode 100644 app/Jobs/Middleware/HandleHubspotRateLimit.phpcreate mode 100644 app/Mcp/Tools/GetMeTool.phpcreate mode 100644 database/migrations/2026_05_13_124153_create_mcp_feature_flag.phpcreate mode 100644 tests/Feature/Mcp/GetMeToolFeatureTest.phpcreate mode 100644 tests/Unit/Component/ES/ChunkSizeTest.phpcreate mode 100644 tests/Unit/Exceptions/RateLimitExceptionTest.phpcreate mode 100644 tests/Unit/Jobs/Middleware/HandleHubspotRateLimitTest.phplukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ git pullAlready up to date.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (master) $ co -b JY-20676-delete-reSwitched to a new branch 'JY-20676-delete-report-related-objects'lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-20676-delete-report-related-ob•HomeDMsActivityFilesLaterMoreSupport Daily - in 3h 58 m100% C78•Tue 19 May 11:02:51ED→QDescribe what you are looking forJiminny ...# bugs# confusion-clinic# curiosity_lab# engineering# general# jiminny-bg# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi...Direct messages8. Vasil Vasilevo Nikolay YankovP. Galya Dimitrova®. Aneliya Angelovad. Stefka Stoyanova. Stoyan Tomovd Todor Stamatov "KM. Mario GeorgievNikolay IvanovJames GrahamStoyan TanevUnread mentions# the_people_of jimi...426 0• MessagesC Files+NewTodayHStefka Stoy¿Hi J team,I wanted to share that our Lead Developer IlianKyuchukov has decided to move on from Jiminny topursue a new opportunity. While we're really sad tosee them go, we're also excited for him and thisnext chapter in his professional journey.Ilian's last working day will be 14 July, so we stillhave some time together before then. Over thecoming weeks, please make the most of hisknowledge, experience, and context so we canensure a smooth transition across the team.It's hard to overstate the impact llian has had here- from shaping the product and solving toughproblems to supporting teammates and helpingbuild the product we have today. We're incrediblygrateful for everything he contributed over this 2years he was with engineering team.Just wanted to share the news openly witheveryone and say a huge thanks to llian foreverything so far. You Please join me in wishing himall the very best for what comes next.We start looking for a Full-Stack Software Engineer,so if you know anyone you believe will fit, pleasecontact me or Mira directly AMessage #the_people_of_jiminny+Aa...
|
56376
|
NULL
|
NULL
|
NULL
|
|
56372
|
NULL
|
0
|
2026-05-19T08:02:37.650120+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779177757650_m2.jpg...
|
Firefox
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
slackFV faVsco.js°9 JY-20676-delete-report-related slackFV faVsco.js°9 JY-20676-delete-report-related-objectsProiect(C) AutomatedReport.onp© AskAnythingPromptServiceTest.php© Serializer.php© TeamScimDetails.php> D bootstrap>D build>D config>@ contrib> @ database>@ docs> C front-end>C lanc>@ node_modules library root> @ phpstan> C publicAskJiminnyReportsControllerTest.php X© Search.php© AskAnythingPrompt.php© ActivityController.phgbaseservice.pnp)constants.pngC) RoleAttr.phpcscimProvisionina.pno) RoleAttrTest.phpListenerRoleCannotHaveAdminOrManagerPermissionRule.php(C)Activity/Close/Service.php(C) Activity/RinqCentral/Service.phpC) SyncActivity.php(C) Crm/Close/Service.pho(C) TextMessaqingService.phpfinal class AskJiminnvReoortsControllerTest extends Testcase22 D >public function testToggleStatusPreventsEnablingReportWithNullSearchId: void{...}72 D >public function testToggleStatusPreventsEnablingReportWithNullPromptId: void{...}>D resourcesv O routesphp api.oho120 D ›public function testTogqleStatusAllowsEnablingReportWithValidReferencesO: voidk...}168 D >public function testTogqleStatusAllowsDisablingReportWithNul1ReferencesO: voidk...}php api_v2.phpphp console.ohophp customer abi.ohophp embedded.phpLocal ChandesConsole XLooXChanges 17 file=.env.local app© ActivityController.php app/Http/Controllers/API© AskAnythingPrompt.php app/Models/AskAnythingc) ASKAnvihinaPromotbto,ono apo/comoonent/AskAnvihino/Dros© AskAnvthinaPromptService.php app/Component/AskAnvthina@ AskAnvthinaPromptServiceTest.php tests/Unit/Component/AskAnvthina© Ask.JiminnvReportsController.pho app/Htto/Controllers/APIV2Side-by-side viewerDo not ignoreHighlight words 158 5604af40 .env.locaSECIRTTY HSANEP CISTOM CCP=OR_CONNECTTON=mvsall= DR HOST=127 A A.1.C) Constants.ono apo/Comoonent/SClMI© CoreUser.php app/DTO/SCIM/AAD/ResponseC) CoreUserRequest.ono ano/DTO/SCIMIAAD/[EMAIL] apn/Console/Commande-nR PORT-73A6- DB_DATABASE=jiminny-DB_USERNAME=rootne pAccwnon-czunz+.ephp loadina.nho confial@ SavedSearchCRUDFeatureTest.nho tests/Feature/SavedSearchesJB CUNNECILUN UHLU=0N10C) ScimProvisionina.ohnann/Comnonent/SCIMDB HOST_OHI0=host.docker.internal© Search.php app/Models/ActivitySoftPhoneManager.php app/Component/Twilio/Conference/ConferenceManagDB PORT 0HL0=/652DB DATABASE_OHI0=jiminny© TextMessagingService.php app/Services/Telephony) Uinvercionod Siloc 11 filacDB USERNAME OHIDEB PASSWORD OHTO=DB CONMECIOION IRELANDETre LandIDB HOST TRELANDehost docker internalDB PORT TRELAND=7532DB DATABASE RELANdeTiminnv.3 PASSWORD TRELANDEnR CONNECTTON STACTNG=staginalDB_HOST_STAGING=host.docker.internalout affectina the dictionarios for other lanquades (todav 10-001= custom.log= laravel.log4 SF jiminny@localhost]4 HS_local [jiminny@localhost]& console [PROD]& console [EU]A console [STAGING]© CoachingFeedbackCoachUserln.php Xfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefini~pubLic tunccion conscruccuserkeposicory suserkeposicorvor...r29 6tpublic function shouldApplyQueries(): boolf...}34 ot>public function getQueries: FilterDefinitionQueryCollection{...}45 6tpubLic function toArray): arrayl...л1 usageprivate function getOptions: arrayt...118f119.public function getValue: arrayt...lusageprivate function getDefaultValue: arrayt...136 >public function getValidationRules(?string $prefix = null): array{...}Current versionSECIRTTY HEANER CISTOM CCP=DB_CONNECTION=mysqlDB_HOST=mariadb#DB_HOST=mariadbnR PORT-7304DB_DATABASE=jiminnyDB_USERNAME=jmnyadminDB_PASSWORD=[PASSWORD] ADMIN_ USERNAME=imnyadmin#DB_ [ENV_SECRET] Models User#CASHIER_MODELEJ1minny Models UserhubsBROADCAST DRMErenuSherCACHE_DRIVER=redisCACHE PRESIXe-imnySESSTON DRIVER=redisQUEUE CONNECTIONeredisGITHUB TOKEN=nu11RENTS CITENT=nhnnedisREnTS HOST=nedis100% 5• lue 1y May 11*02•3.CascadeO ASk Jiminny Report+0 ..searcned ask_jminny_reponts.toggle and pertormed & oter querlesASKAnychingPrompt don't nave tactorles and the fule says notto write tests for controllers. Let me remove that tlle° Fusers/tukas/31m/ny/app/tests/Feature/Http/Controllers/APZ/V2/A5KJ1m/nnyßeportsControLlertes.PRun &~ Skip* Reject allAccept allQ files 4200 -7 >Ask anvthina (4D14 @s Codo Chudo Onuc 17 Modium48 ditterencesPo 4 spaces...
|
NULL
|
-7657350687453221516
|
NULL
|
visual_change
|
ocr
|
NULL
|
slackFV faVsco.js°9 JY-20676-delete-report-related slackFV faVsco.js°9 JY-20676-delete-report-related-objectsProiect(C) AutomatedReport.onp© AskAnythingPromptServiceTest.php© Serializer.php© TeamScimDetails.php> D bootstrap>D build>D config>@ contrib> @ database>@ docs> C front-end>C lanc>@ node_modules library root> @ phpstan> C publicAskJiminnyReportsControllerTest.php X© Search.php© AskAnythingPrompt.php© ActivityController.phgbaseservice.pnp)constants.pngC) RoleAttr.phpcscimProvisionina.pno) RoleAttrTest.phpListenerRoleCannotHaveAdminOrManagerPermissionRule.php(C)Activity/Close/Service.php(C) Activity/RinqCentral/Service.phpC) SyncActivity.php(C) Crm/Close/Service.pho(C) TextMessaqingService.phpfinal class AskJiminnvReoortsControllerTest extends Testcase22 D >public function testToggleStatusPreventsEnablingReportWithNullSearchId: void{...}72 D >public function testToggleStatusPreventsEnablingReportWithNullPromptId: void{...}>D resourcesv O routesphp api.oho120 D ›public function testTogqleStatusAllowsEnablingReportWithValidReferencesO: voidk...}168 D >public function testTogqleStatusAllowsDisablingReportWithNul1ReferencesO: voidk...}php api_v2.phpphp console.ohophp customer abi.ohophp embedded.phpLocal ChandesConsole XLooXChanges 17 file=.env.local app© ActivityController.php app/Http/Controllers/API© AskAnythingPrompt.php app/Models/AskAnythingc) ASKAnvihinaPromotbto,ono apo/comoonent/AskAnvihino/Dros© AskAnvthinaPromptService.php app/Component/AskAnvthina@ AskAnvthinaPromptServiceTest.php tests/Unit/Component/AskAnvthina© Ask.JiminnvReportsController.pho app/Htto/Controllers/APIV2Side-by-side viewerDo not ignoreHighlight words 158 5604af40 .env.locaSECIRTTY HSANEP CISTOM CCP=OR_CONNECTTON=mvsall= DR HOST=127 A A.1.C) Constants.ono apo/Comoonent/SClMI© CoreUser.php app/DTO/SCIM/AAD/ResponseC) CoreUserRequest.ono ano/DTO/SCIMIAAD/[EMAIL] apn/Console/Commande-nR PORT-73A6- DB_DATABASE=jiminny-DB_USERNAME=rootne pAccwnon-czunz+.ephp loadina.nho confial@ SavedSearchCRUDFeatureTest.nho tests/Feature/SavedSearchesJB CUNNECILUN UHLU=0N10C) ScimProvisionina.ohnann/Comnonent/SCIMDB HOST_OHI0=host.docker.internal© Search.php app/Models/ActivitySoftPhoneManager.php app/Component/Twilio/Conference/ConferenceManagDB PORT 0HL0=/652DB DATABASE_OHI0=jiminny© TextMessagingService.php app/Services/Telephony) Uinvercionod Siloc 11 filacDB USERNAME OHIDEB PASSWORD OHTO=DB CONMECIOION IRELANDETre LandIDB HOST TRELANDehost docker internalDB PORT TRELAND=7532DB DATABASE RELANdeTiminnv.3 PASSWORD TRELANDEnR CONNECTTON STACTNG=staginalDB_HOST_STAGING=host.docker.internalout affectina the dictionarios for other lanquades (todav 10-001= custom.log= laravel.log4 SF jiminny@localhost]4 HS_local [jiminny@localhost]& console [PROD]& console [EU]A console [STAGING]© CoachingFeedbackCoachUserln.php Xfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefini~pubLic tunccion conscruccuserkeposicory suserkeposicorvor...r29 6tpublic function shouldApplyQueries(): boolf...}34 ot>public function getQueries: FilterDefinitionQueryCollection{...}45 6tpubLic function toArray): arrayl...л1 usageprivate function getOptions: arrayt...118f119.public function getValue: arrayt...lusageprivate function getDefaultValue: arrayt...136 >public function getValidationRules(?string $prefix = null): array{...}Current versionSECIRTTY HEANER CISTOM CCP=DB_CONNECTION=mysqlDB_HOST=mariadb#DB_HOST=mariadbnR PORT-7304DB_DATABASE=jiminnyDB_USERNAME=jmnyadminDB_PASSWORD=[PASSWORD] ADMIN_ USERNAME=imnyadmin#DB_ [ENV_SECRET] Models User#CASHIER_MODELEJ1minny Models UserhubsBROADCAST DRMErenuSherCACHE_DRIVER=redisCACHE PRESIXe-imnySESSTON DRIVER=redisQUEUE CONNECTIONeredisGITHUB TOKEN=nu11RENTS CITENT=nhnnedisREnTS HOST=nedis100% 5• lue 1y May 11*02•3.CascadeO ASk Jiminny Report+0 ..searcned ask_jminny_reponts.toggle and pertormed & oter querlesASKAnychingPrompt don't nave tactorles and the fule says notto write tests for controllers. Let me remove that tlle° Fusers/tukas/31m/ny/app/tests/Feature/Http/Controllers/APZ/V2/A5KJ1m/nnyßeportsControLlertes.PRun &~ Skip* Reject allAccept allQ files 4200 -7 >Ask anvthina (4D14 @s Codo Chudo Onuc 17 Modium48 ditterencesPo 4 spaces...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
56338
|
NULL
|
0
|
2026-05-19T07:57:36.943314+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779177456943_m2.jpg...
|
PhpStorm
|
faVsco.js – AskJiminnyReportsController.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20676-delete-report-re Project: faVsco.js, menu
JY-20676-delete-report-related-objects, 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
9
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\API\V2;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Jiminny\Exceptions\InvalidArgumentException;
use Jiminny\Exceptions\ModelNotFoundException;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Response;
use Throwable;
class AskJiminnyReportsController extends Controller
{
public function __construct(
private readonly AutomatedReportsService $automatedReportsService,
private readonly LoggerInterface $logger,
) {
}
private function isNotOwnedByUser(AutomatedReport $report, User $user): bool
{
return $report->getTeamId() !== $user->getTeamId()
|| $report->getAttribute('created_by') !== $user->getId();
}
public function getFormData(Request $request, ?string $uuid = null): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $uuid ? $this->automatedReportsService->getReport($uuid) : null;
return new JsonResponse(
$this->automatedReportsService->getAskJiminnyReportFormData($user, $report)
);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to fetch Ask Jiminny report form data', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to fetch form data'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Create a new Ask Jiminny report.
*/
public function create(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$data = $this->automatedReportsService->createAskJiminnyReport($request->all(), $user);
return new JsonResponse($data);
} catch (InvalidArgumentException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);
} catch (Throwable $e) {
$this->logger->error('Failed to create Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse(
['error' => 'Failed to create report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Update an existing Ask Jiminny report.
*/
public function update(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$data = $this->automatedReportsService->updateAskJiminnyReport($report, $request->all(), $user);
return new JsonResponse($data);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (InvalidArgumentException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);
} catch (Throwable $e) {
$this->logger->error('Failed to update Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to update report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Toggle Ask Jiminny report status (enable/disable).
*/
public function toggleStatus(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$data = $this->automatedReportsService->updateAskJiminnyReportStatus(
$report,
(bool) $request->input('enabled'),
);
return new JsonResponse($data);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to toggle Ask Jiminny report status', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to toggle report status'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* List all Ask Jiminny reports.
*/
public function list(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$sortColumn = $request->input('sort_column', 'created_at');
$sortDirection = $request->input('sort_direction', 'desc');
$data = $this->automatedReportsService->listAskJiminnyReports($user, $sortColumn, $sortDirection);
return new JsonResponse($data);
} catch (Throwable $e) {
$this->logger->error('Failed to list Ask Jiminny reports', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse(
['error' => 'Failed to fetch reports'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Get a single Ask Jiminny report.
*/
public function get(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
return new JsonResponse($this->automatedReportsService->get($uuid));
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to get Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to fetch report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
public function getReportsCount(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$resultsCount = $this->automatedReportsService->getReportResults($report)->count();
return new JsonResponse(['count' => $resultsCount]);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to count report results', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'report_uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to count report results'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Delete an Ask Jiminny report.
*/
public function delete(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
if ($request->boolean('delete_generated_reports')) {
$this->automatedReportsService->deleteReportResults($uuid);
}
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$this->automatedReportsService->delete($uuid);
return new JsonResponse(null, Response::HTTP_NO_CONTENT);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to delete Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to delete report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
public function getFilters(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$filters = $this->automatedReportsService->getAskJiminnyReportFilters($user);
return new JsonResponse(['filters' => $filters]);
} catch (Throwable $e) {
$this->logger->error('Failed to fetch Ask Jiminny report filters', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse(
['error' => 'Failed to fetch filters'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20676-delete-report-related-objects, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.098071806,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: JY-20676-delete-report-related-objects","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":"9","depth":4,"bounds":{"left":0.40226063,"top":0.17478053,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.4119016,"top":0.17318435,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.4192154,"top":0.17318435,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Http\\Controllers\\API\\V2;\n\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Controller;\nuse Jiminny\\Exceptions\\InvalidArgumentException;\nuse Jiminny\\Exceptions\\ModelNotFoundException;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Psr\\Log\\LoggerInterface;\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Throwable;\n\nclass AskJiminnyReportsController extends Controller\n{\n public function __construct(\n private readonly AutomatedReportsService $automatedReportsService,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n private function isNotOwnedByUser(AutomatedReport $report, User $user): bool\n {\n return $report->getTeamId() !== $user->getTeamId()\n || $report->getAttribute('created_by') !== $user->getId();\n }\n\n public function getFormData(Request $request, ?string $uuid = null): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $uuid ? $this->automatedReportsService->getReport($uuid) : null;\n\n return new JsonResponse(\n $this->automatedReportsService->getAskJiminnyReportFormData($user, $report)\n );\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to fetch Ask Jiminny report form data', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch form data'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Create a new Ask Jiminny report.\n */\n public function create(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $data = $this->automatedReportsService->createAskJiminnyReport($request->all(), $user);\n\n return new JsonResponse($data);\n } catch (InvalidArgumentException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);\n } catch (Throwable $e) {\n $this->logger->error('Failed to create Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to create report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Update an existing Ask Jiminny report.\n */\n public function update(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $data = $this->automatedReportsService->updateAskJiminnyReport($report, $request->all(), $user);\n\n return new JsonResponse($data);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (InvalidArgumentException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);\n } catch (Throwable $e) {\n $this->logger->error('Failed to update Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to update report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Toggle Ask Jiminny report status (enable/disable).\n */\n public function toggleStatus(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $data = $this->automatedReportsService->updateAskJiminnyReportStatus(\n $report,\n (bool) $request->input('enabled'),\n );\n\n return new JsonResponse($data);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to toggle Ask Jiminny report status', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to toggle report status'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * List all Ask Jiminny reports.\n */\n public function list(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $sortColumn = $request->input('sort_column', 'created_at');\n $sortDirection = $request->input('sort_direction', 'desc');\n\n $data = $this->automatedReportsService->listAskJiminnyReports($user, $sortColumn, $sortDirection);\n\n return new JsonResponse($data);\n } catch (Throwable $e) {\n $this->logger->error('Failed to list Ask Jiminny reports', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch reports'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Get a single Ask Jiminny report.\n */\n public function get(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n return new JsonResponse($this->automatedReportsService->get($uuid));\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to get Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n public function getReportsCount(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $resultsCount = $this->automatedReportsService->getReportResults($report)->count();\n\n return new JsonResponse(['count' => $resultsCount]);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to count report results', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'report_uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to count report results'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Delete an Ask Jiminny report.\n */\n public function delete(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n if ($request->boolean('delete_generated_reports')) {\n $this->automatedReportsService->deleteReportResults($uuid);\n }\n\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $this->automatedReportsService->delete($uuid);\n\n return new JsonResponse(null, Response::HTTP_NO_CONTENT);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to delete Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to delete report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n public function getFilters(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $filters = $this->automatedReportsService->getAskJiminnyReportFilters($user);\n\n return new JsonResponse(['filters' => $filters]);\n } catch (Throwable $e) {\n $this->logger->error('Failed to fetch Ask Jiminny report filters', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch filters'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Http\\Controllers\\API\\V2;\n\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Controller;\nuse Jiminny\\Exceptions\\InvalidArgumentException;\nuse Jiminny\\Exceptions\\ModelNotFoundException;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Psr\\Log\\LoggerInterface;\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Throwable;\n\nclass AskJiminnyReportsController extends Controller\n{\n public function __construct(\n private readonly AutomatedReportsService $automatedReportsService,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n private function isNotOwnedByUser(AutomatedReport $report, User $user): bool\n {\n return $report->getTeamId() !== $user->getTeamId()\n || $report->getAttribute('created_by') !== $user->getId();\n }\n\n public function getFormData(Request $request, ?string $uuid = null): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $uuid ? $this->automatedReportsService->getReport($uuid) : null;\n\n return new JsonResponse(\n $this->automatedReportsService->getAskJiminnyReportFormData($user, $report)\n );\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to fetch Ask Jiminny report form data', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch form data'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Create a new Ask Jiminny report.\n */\n public function create(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $data = $this->automatedReportsService->createAskJiminnyReport($request->all(), $user);\n\n return new JsonResponse($data);\n } catch (InvalidArgumentException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);\n } catch (Throwable $e) {\n $this->logger->error('Failed to create Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to create report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Update an existing Ask Jiminny report.\n */\n public function update(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $data = $this->automatedReportsService->updateAskJiminnyReport($report, $request->all(), $user);\n\n return new JsonResponse($data);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (InvalidArgumentException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);\n } catch (Throwable $e) {\n $this->logger->error('Failed to update Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to update report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Toggle Ask Jiminny report status (enable/disable).\n */\n public function toggleStatus(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $data = $this->automatedReportsService->updateAskJiminnyReportStatus(\n $report,\n (bool) $request->input('enabled'),\n );\n\n return new JsonResponse($data);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to toggle Ask Jiminny report status', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to toggle report status'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * List all Ask Jiminny reports.\n */\n public function list(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $sortColumn = $request->input('sort_column', 'created_at');\n $sortDirection = $request->input('sort_direction', 'desc');\n\n $data = $this->automatedReportsService->listAskJiminnyReports($user, $sortColumn, $sortDirection);\n\n return new JsonResponse($data);\n } catch (Throwable $e) {\n $this->logger->error('Failed to list Ask Jiminny reports', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch reports'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Get a single Ask Jiminny report.\n */\n public function get(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n return new JsonResponse($this->automatedReportsService->get($uuid));\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to get Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n public function getReportsCount(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $resultsCount = $this->automatedReportsService->getReportResults($report)->count();\n\n return new JsonResponse(['count' => $resultsCount]);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to count report results', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'report_uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to count report results'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Delete an Ask Jiminny report.\n */\n public function delete(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n if ($request->boolean('delete_generated_reports')) {\n $this->automatedReportsService->deleteReportResults($uuid);\n }\n\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $this->automatedReportsService->delete($uuid);\n\n return new JsonResponse(null, Response::HTTP_NO_CONTENT);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to delete Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to delete report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n public function getFilters(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $filters = $this->automatedReportsService->getAskJiminnyReportFilters($user);\n\n return new JsonResponse(['filters' => $filters]);\n } catch (Throwable $e) {\n $this->logger->error('Failed to fetch Ask Jiminny report filters', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch filters'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.7124335,"top":0.10055866,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.72140956,"top":0.09896249,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.7287234,"top":0.09896249,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","depth":4,"bounds":{"left":0.4481383,"top":0.09736632,"width":0.29288563,"height":0.8818835},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-9066378505773698050
|
-7048904802100598171
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20676-delete-report-re Project: faVsco.js, menu
JY-20676-delete-report-related-objects, 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
9
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\API\V2;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Jiminny\Exceptions\InvalidArgumentException;
use Jiminny\Exceptions\ModelNotFoundException;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Response;
use Throwable;
class AskJiminnyReportsController extends Controller
{
public function __construct(
private readonly AutomatedReportsService $automatedReportsService,
private readonly LoggerInterface $logger,
) {
}
private function isNotOwnedByUser(AutomatedReport $report, User $user): bool
{
return $report->getTeamId() !== $user->getTeamId()
|| $report->getAttribute('created_by') !== $user->getId();
}
public function getFormData(Request $request, ?string $uuid = null): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $uuid ? $this->automatedReportsService->getReport($uuid) : null;
return new JsonResponse(
$this->automatedReportsService->getAskJiminnyReportFormData($user, $report)
);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to fetch Ask Jiminny report form data', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to fetch form data'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Create a new Ask Jiminny report.
*/
public function create(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$data = $this->automatedReportsService->createAskJiminnyReport($request->all(), $user);
return new JsonResponse($data);
} catch (InvalidArgumentException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);
} catch (Throwable $e) {
$this->logger->error('Failed to create Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse(
['error' => 'Failed to create report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Update an existing Ask Jiminny report.
*/
public function update(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$data = $this->automatedReportsService->updateAskJiminnyReport($report, $request->all(), $user);
return new JsonResponse($data);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (InvalidArgumentException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);
} catch (Throwable $e) {
$this->logger->error('Failed to update Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to update report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Toggle Ask Jiminny report status (enable/disable).
*/
public function toggleStatus(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$data = $this->automatedReportsService->updateAskJiminnyReportStatus(
$report,
(bool) $request->input('enabled'),
);
return new JsonResponse($data);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to toggle Ask Jiminny report status', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to toggle report status'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* List all Ask Jiminny reports.
*/
public function list(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$sortColumn = $request->input('sort_column', 'created_at');
$sortDirection = $request->input('sort_direction', 'desc');
$data = $this->automatedReportsService->listAskJiminnyReports($user, $sortColumn, $sortDirection);
return new JsonResponse($data);
} catch (Throwable $e) {
$this->logger->error('Failed to list Ask Jiminny reports', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse(
['error' => 'Failed to fetch reports'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Get a single Ask Jiminny report.
*/
public function get(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
return new JsonResponse($this->automatedReportsService->get($uuid));
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to get Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to fetch report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
public function getReportsCount(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$resultsCount = $this->automatedReportsService->getReportResults($report)->count();
return new JsonResponse(['count' => $resultsCount]);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to count report results', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'report_uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to count report results'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Delete an Ask Jiminny report.
*/
public function delete(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
if ($request->boolean('delete_generated_reports')) {
$this->automatedReportsService->deleteReportResults($uuid);
}
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$this->automatedReportsService->delete($uuid);
return new JsonResponse(null, Response::HTTP_NO_CONTENT);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to delete Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to delete report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
public function getFilters(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$filters = $this->automatedReportsService->getAskJiminnyReportFilters($user);
return new JsonResponse(['filters' => $filters]);
} catch (Throwable $e) {
$this->logger->error('Failed to fetch Ask Jiminny report filters', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse(
['error' => 'Failed to fetch filters'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
56330
|
NULL
|
NULL
|
NULL
|
|
56337
|
NULL
|
0
|
2026-05-19T07:57:36.788681+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779177456788_m1.jpg...
|
PhpStorm
|
faVsco.js – AskJiminnyReportsController.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20676-delete-report-re Project: faVsco.js, menu
JY-20676-delete-report-related-objects, 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
9
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\API\V2;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Jiminny\Exceptions\InvalidArgumentException;
use Jiminny\Exceptions\ModelNotFoundException;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Response;
use Throwable;
class AskJiminnyReportsController extends Controller
{
public function __construct(
private readonly AutomatedReportsService $automatedReportsService,
private readonly LoggerInterface $logger,
) {
}
private function isNotOwnedByUser(AutomatedReport $report, User $user): bool
{
return $report->getTeamId() !== $user->getTeamId()
|| $report->getAttribute('created_by') !== $user->getId();
}
public function getFormData(Request $request, ?string $uuid = null): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $uuid ? $this->automatedReportsService->getReport($uuid) : null;
return new JsonResponse(
$this->automatedReportsService->getAskJiminnyReportFormData($user, $report)
);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to fetch Ask Jiminny report form data', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to fetch form data'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Create a new Ask Jiminny report.
*/
public function create(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$data = $this->automatedReportsService->createAskJiminnyReport($request->all(), $user);
return new JsonResponse($data);
} catch (InvalidArgumentException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);
} catch (Throwable $e) {
$this->logger->error('Failed to create Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse(
['error' => 'Failed to create report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Update an existing Ask Jiminny report.
*/
public function update(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$data = $this->automatedReportsService->updateAskJiminnyReport($report, $request->all(), $user);
return new JsonResponse($data);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (InvalidArgumentException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);
} catch (Throwable $e) {
$this->logger->error('Failed to update Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to update report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Toggle Ask Jiminny report status (enable/disable).
*/
public function toggleStatus(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$data = $this->automatedReportsService->updateAskJiminnyReportStatus(
$report,
(bool) $request->input('enabled'),
);
return new JsonResponse($data);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to toggle Ask Jiminny report status', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to toggle report status'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* List all Ask Jiminny reports.
*/
public function list(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$sortColumn = $request->input('sort_column', 'created_at');
$sortDirection = $request->input('sort_direction', 'desc');
$data = $this->automatedReportsService->listAskJiminnyReports($user, $sortColumn, $sortDirection);
return new JsonResponse($data);
} catch (Throwable $e) {
$this->logger->error('Failed to list Ask Jiminny reports', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse(
['error' => 'Failed to fetch reports'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Get a single Ask Jiminny report.
*/
public function get(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
return new JsonResponse($this->automatedReportsService->get($uuid));
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to get Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to fetch report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
public function getReportsCount(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$resultsCount = $this->automatedReportsService->getReportResults($report)->count();
return new JsonResponse(['count' => $resultsCount]);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to count report results', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'report_uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to count report results'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Delete an Ask Jiminny report.
*/
public function delete(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
if ($request->boolean('delete_generated_reports')) {
$this->automatedReportsService->deleteReportResults($uuid);
}
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$this->automatedReportsService->delete($uuid);
return new JsonResponse(null, Response::HTTP_NO_CONTENT);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to delete Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to delete report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
public function getFilters(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$filters = $this->automatedReportsService->getAskJiminnyReportFilters($user);
return new JsonResponse(['filters' => $filters]);
} catch (Throwable $e) {
$this->logger->error('Failed to fetch Ask Jiminny report filters', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse(
['error' => 'Failed to fetch filters'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20676-delete-report-related-objects, menu","depth":5,"on_screen":true,"help_text":"Git Branch: JY-20676-delete-report-related-objects","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":"9","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Http\\Controllers\\API\\V2;\n\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Controller;\nuse Jiminny\\Exceptions\\InvalidArgumentException;\nuse Jiminny\\Exceptions\\ModelNotFoundException;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Psr\\Log\\LoggerInterface;\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Throwable;\n\nclass AskJiminnyReportsController extends Controller\n{\n public function __construct(\n private readonly AutomatedReportsService $automatedReportsService,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n private function isNotOwnedByUser(AutomatedReport $report, User $user): bool\n {\n return $report->getTeamId() !== $user->getTeamId()\n || $report->getAttribute('created_by') !== $user->getId();\n }\n\n public function getFormData(Request $request, ?string $uuid = null): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $uuid ? $this->automatedReportsService->getReport($uuid) : null;\n\n return new JsonResponse(\n $this->automatedReportsService->getAskJiminnyReportFormData($user, $report)\n );\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to fetch Ask Jiminny report form data', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch form data'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Create a new Ask Jiminny report.\n */\n public function create(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $data = $this->automatedReportsService->createAskJiminnyReport($request->all(), $user);\n\n return new JsonResponse($data);\n } catch (InvalidArgumentException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);\n } catch (Throwable $e) {\n $this->logger->error('Failed to create Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to create report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Update an existing Ask Jiminny report.\n */\n public function update(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $data = $this->automatedReportsService->updateAskJiminnyReport($report, $request->all(), $user);\n\n return new JsonResponse($data);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (InvalidArgumentException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);\n } catch (Throwable $e) {\n $this->logger->error('Failed to update Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to update report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Toggle Ask Jiminny report status (enable/disable).\n */\n public function toggleStatus(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $data = $this->automatedReportsService->updateAskJiminnyReportStatus(\n $report,\n (bool) $request->input('enabled'),\n );\n\n return new JsonResponse($data);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to toggle Ask Jiminny report status', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to toggle report status'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * List all Ask Jiminny reports.\n */\n public function list(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $sortColumn = $request->input('sort_column', 'created_at');\n $sortDirection = $request->input('sort_direction', 'desc');\n\n $data = $this->automatedReportsService->listAskJiminnyReports($user, $sortColumn, $sortDirection);\n\n return new JsonResponse($data);\n } catch (Throwable $e) {\n $this->logger->error('Failed to list Ask Jiminny reports', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch reports'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Get a single Ask Jiminny report.\n */\n public function get(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n return new JsonResponse($this->automatedReportsService->get($uuid));\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to get Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n public function getReportsCount(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $resultsCount = $this->automatedReportsService->getReportResults($report)->count();\n\n return new JsonResponse(['count' => $resultsCount]);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to count report results', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'report_uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to count report results'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Delete an Ask Jiminny report.\n */\n public function delete(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n if ($request->boolean('delete_generated_reports')) {\n $this->automatedReportsService->deleteReportResults($uuid);\n }\n\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $this->automatedReportsService->delete($uuid);\n\n return new JsonResponse(null, Response::HTTP_NO_CONTENT);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to delete Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to delete report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n public function getFilters(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $filters = $this->automatedReportsService->getAskJiminnyReportFilters($user);\n\n return new JsonResponse(['filters' => $filters]);\n } catch (Throwable $e) {\n $this->logger->error('Failed to fetch Ask Jiminny report filters', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch filters'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Http\\Controllers\\API\\V2;\n\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Controller;\nuse Jiminny\\Exceptions\\InvalidArgumentException;\nuse Jiminny\\Exceptions\\ModelNotFoundException;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Psr\\Log\\LoggerInterface;\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Throwable;\n\nclass AskJiminnyReportsController extends Controller\n{\n public function __construct(\n private readonly AutomatedReportsService $automatedReportsService,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n private function isNotOwnedByUser(AutomatedReport $report, User $user): bool\n {\n return $report->getTeamId() !== $user->getTeamId()\n || $report->getAttribute('created_by') !== $user->getId();\n }\n\n public function getFormData(Request $request, ?string $uuid = null): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $uuid ? $this->automatedReportsService->getReport($uuid) : null;\n\n return new JsonResponse(\n $this->automatedReportsService->getAskJiminnyReportFormData($user, $report)\n );\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to fetch Ask Jiminny report form data', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch form data'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Create a new Ask Jiminny report.\n */\n public function create(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $data = $this->automatedReportsService->createAskJiminnyReport($request->all(), $user);\n\n return new JsonResponse($data);\n } catch (InvalidArgumentException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);\n } catch (Throwable $e) {\n $this->logger->error('Failed to create Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to create report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Update an existing Ask Jiminny report.\n */\n public function update(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $data = $this->automatedReportsService->updateAskJiminnyReport($report, $request->all(), $user);\n\n return new JsonResponse($data);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (InvalidArgumentException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);\n } catch (Throwable $e) {\n $this->logger->error('Failed to update Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to update report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Toggle Ask Jiminny report status (enable/disable).\n */\n public function toggleStatus(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $data = $this->automatedReportsService->updateAskJiminnyReportStatus(\n $report,\n (bool) $request->input('enabled'),\n );\n\n return new JsonResponse($data);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to toggle Ask Jiminny report status', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to toggle report status'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * List all Ask Jiminny reports.\n */\n public function list(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $sortColumn = $request->input('sort_column', 'created_at');\n $sortDirection = $request->input('sort_direction', 'desc');\n\n $data = $this->automatedReportsService->listAskJiminnyReports($user, $sortColumn, $sortDirection);\n\n return new JsonResponse($data);\n } catch (Throwable $e) {\n $this->logger->error('Failed to list Ask Jiminny reports', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch reports'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Get a single Ask Jiminny report.\n */\n public function get(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n return new JsonResponse($this->automatedReportsService->get($uuid));\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to get Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n public function getReportsCount(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $resultsCount = $this->automatedReportsService->getReportResults($report)->count();\n\n return new JsonResponse(['count' => $resultsCount]);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to count report results', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'report_uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to count report results'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n /**\n * Delete an Ask Jiminny report.\n */\n public function delete(Request $request, string $uuid): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n if ($request->boolean('delete_generated_reports')) {\n $this->automatedReportsService->deleteReportResults($uuid);\n }\n\n $report = $this->automatedReportsService->getReport($uuid);\n\n if ($this->isNotOwnedByUser($report, $user)) {\n return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);\n }\n\n $this->automatedReportsService->delete($uuid);\n\n return new JsonResponse(null, Response::HTTP_NO_CONTENT);\n } catch (ModelNotFoundException $e) {\n return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);\n } catch (Throwable $e) {\n $this->logger->error('Failed to delete Ask Jiminny report', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n 'uuid' => $uuid,\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to delete report'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n\n public function getFilters(Request $request): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n try {\n $filters = $this->automatedReportsService->getAskJiminnyReportFilters($user);\n\n return new JsonResponse(['filters' => $filters]);\n } catch (Throwable $e) {\n $this->logger->error('Failed to fetch Ask Jiminny report filters', [\n 'error' => $e->getMessage(),\n 'user_id' => $user->getId(),\n ]);\n\n return new JsonResponse(\n ['error' => 'Failed to fetch filters'],\n Response::HTTP_INTERNAL_SERVER_ERROR\n );\n }\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-9066378505773698050
|
-7048904802100598171
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20676-delete-report-re Project: faVsco.js, menu
JY-20676-delete-report-related-objects, 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
9
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Http\Controllers\API\V2;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Jiminny\Exceptions\InvalidArgumentException;
use Jiminny\Exceptions\ModelNotFoundException;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Response;
use Throwable;
class AskJiminnyReportsController extends Controller
{
public function __construct(
private readonly AutomatedReportsService $automatedReportsService,
private readonly LoggerInterface $logger,
) {
}
private function isNotOwnedByUser(AutomatedReport $report, User $user): bool
{
return $report->getTeamId() !== $user->getTeamId()
|| $report->getAttribute('created_by') !== $user->getId();
}
public function getFormData(Request $request, ?string $uuid = null): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $uuid ? $this->automatedReportsService->getReport($uuid) : null;
return new JsonResponse(
$this->automatedReportsService->getAskJiminnyReportFormData($user, $report)
);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to fetch Ask Jiminny report form data', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to fetch form data'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Create a new Ask Jiminny report.
*/
public function create(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$data = $this->automatedReportsService->createAskJiminnyReport($request->all(), $user);
return new JsonResponse($data);
} catch (InvalidArgumentException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);
} catch (Throwable $e) {
$this->logger->error('Failed to create Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse(
['error' => 'Failed to create report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Update an existing Ask Jiminny report.
*/
public function update(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$data = $this->automatedReportsService->updateAskJiminnyReport($report, $request->all(), $user);
return new JsonResponse($data);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (InvalidArgumentException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_UNPROCESSABLE_ENTITY);
} catch (Throwable $e) {
$this->logger->error('Failed to update Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to update report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Toggle Ask Jiminny report status (enable/disable).
*/
public function toggleStatus(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$data = $this->automatedReportsService->updateAskJiminnyReportStatus(
$report,
(bool) $request->input('enabled'),
);
return new JsonResponse($data);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to toggle Ask Jiminny report status', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to toggle report status'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* List all Ask Jiminny reports.
*/
public function list(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$sortColumn = $request->input('sort_column', 'created_at');
$sortDirection = $request->input('sort_direction', 'desc');
$data = $this->automatedReportsService->listAskJiminnyReports($user, $sortColumn, $sortDirection);
return new JsonResponse($data);
} catch (Throwable $e) {
$this->logger->error('Failed to list Ask Jiminny reports', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse(
['error' => 'Failed to fetch reports'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Get a single Ask Jiminny report.
*/
public function get(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
return new JsonResponse($this->automatedReportsService->get($uuid));
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to get Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to fetch report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
public function getReportsCount(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$resultsCount = $this->automatedReportsService->getReportResults($report)->count();
return new JsonResponse(['count' => $resultsCount]);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to count report results', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'report_uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to count report results'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* Delete an Ask Jiminny report.
*/
public function delete(Request $request, string $uuid): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
if ($request->boolean('delete_generated_reports')) {
$this->automatedReportsService->deleteReportResults($uuid);
}
$report = $this->automatedReportsService->getReport($uuid);
if ($this->isNotOwnedByUser($report, $user)) {
return new JsonResponse(['error' => 'Report not found'], Response::HTTP_NOT_FOUND);
}
$this->automatedReportsService->delete($uuid);
return new JsonResponse(null, Response::HTTP_NO_CONTENT);
} catch (ModelNotFoundException $e) {
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
} catch (Throwable $e) {
$this->logger->error('Failed to delete Ask Jiminny report', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
'uuid' => $uuid,
]);
return new JsonResponse(
['error' => 'Failed to delete report'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
public function getFilters(Request $request): JsonResponse
{
/** @var User $user */
$user = $request->user();
try {
$filters = $this->automatedReportsService->getAskJiminnyReportFilters($user);
return new JsonResponse(['filters' => $filters]);
} catch (Throwable $e) {
$this->logger->error('Failed to fetch Ask Jiminny report filters', [
'error' => $e->getMessage(),
'user_id' => $user->getId(),
]);
return new JsonResponse(
['error' => 'Failed to fetch filters'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
56333
|
NULL
|
NULL
|
NULL
|
|
56298
|
NULL
|
0
|
2026-05-19T07:52:43.415863+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-19/1779 /Users/lukas/.screenpipe/data/data/2026-05-19/1779177163415_m1.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReport.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20676-delete-report-re Project: faVsco.js, menu
JY-20676-delete-report-related-objects, 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
6
1
6
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Carbon;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\AskAnything\AskAnythingPrompt;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Traits\RequiresUUID;
/**
* Jiminny\Models\AutomatedReport
*
* @property int $id
* @property string $uuid
* @property int $team_id
* @property string $type
* @property bool $status
* @property string $frequency
* @property Carbon|null $from
* @property Carbon|null $to
* @property int|null $deal_value_min
* @property int|null $deal_value_max
* @property array $call_types
* @property array $media_types
* @property int|null $call_duration_min
* @property int|null $call_duration_max
* @property array|null $groups
* @property array|null $playbook_categories
* @property array|null $deal_at_call_stages
* @property array|null $current_deal_stages
* @property array $recipients
* @property string|null $additional_prompt_input
* @property string|null $custom_name
* @property int|null $activity_search_id
* @property int|null $ask_anything_prompt_id
* @property Carbon|null $expires_at
* @property Carbon|null $created_at
* @property Carbon|null $updated_at
* @property Carbon|null $deleted_at
* @property-read \Jiminny\Models\Team $team
* @property-read \Jiminny\Models\Activity\Search|null $savedSearch
* @property-read \Jiminny\Models\AskAnything\AskAnythingPrompt|null $askAnythingPrompt
*/
class AutomatedReport extends Model
{
use RequiresUUID;
use SoftDeletes;
protected $table = 'automated_reports';
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'team_id',
'type',
'status',
'frequency',
'from',
'to',
'deal_value_min',
'deal_value_max',
'call_types',
'media_types',
'call_duration_min',
'call_duration_max',
'groups',
'playbook_categories',
'deal_at_call_stages',
'current_deal_stages',
'recipients',
'jiminny_recipients',
'additional_prompt_input',
'custom_name',
'created_by',
'activity_search_id',
'ask_anything_prompt_id',
'expires_at',
];
protected $hidden = ['uuid'];
/**
* Get the attributes that should be cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'status' => 'boolean',
'from' => 'datetime',
'to' => 'datetime',
'call_types' => 'array',
'media_types' => 'array',
'groups' => 'array',
'playbook_categories' => 'array',
'deal_at_call_stages' => 'array',
'current_deal_stages' => 'array',
'recipients' => 'array',
'jiminny_recipients' => 'array',
'expires_at' => 'date',
'deleted_at' => 'datetime',
];
}
/**
* Get the team that owns the automated report.
*/
public function team()
{
return $this->belongsTo(Team::class);
}
/**
*
* Get the user who created the report.
*/
public function creator(): BelongsTo
{
return $this->belongsTo(User::class, 'created_by');
}
public function savedSearch(): BelongsTo
{
return $this->belongsTo(Search::class, 'activity_search_id');
}
public function askAnythingPrompt(): BelongsTo
{
return $this->belongsTo(AskAnythingPrompt::class, 'ask_anything_prompt_id');
}
public function isAskJiminnyReport(): bool
{
return $this->getType() === AutomatedReportsService::TYPE_ASK_JIMINNY;
}
public function isExpired(): bool
{
$expiresAt = $this->getExpiresAt();
return $expiresAt !== null && $expiresAt->isPast();
}
public function canExecute(): bool
{
if ($this->isAskJiminnyReport()) {
return $this->getActivitySearchId() !== null
&& $this->getAskAnythingPromptId() !== null;
}
return true;
}
public function getActivitySearchId(): ?int
{
return $this->getAttribute('activity_search_id');
}
public function getAskAnythingPromptId(): ?int
{
return $this->getAttribute('ask_anything_prompt_id');
}
public function getExpiresAt(): ?Carbon
{
return $this->getAttribute('expires_at');
}
public function getSavedSearch(): ?Search
{
return $this->getAttribute('savedSearch');
}
public function getAskAnythingPrompt(): ?AskAnythingPrompt
{
return $this->getAttribute('askAnythingPrompt');
}
/**
* Get the ID of the automated report.
*
* @return int
*/
public function getId(): int
{
return $this->getAttribute('id');
}
/**
* Get the UUID of the automated report.
*
* @return string
*/
public function getUuid(): string
{
return $this->getAttribute('id_string');
}
/**
* Get the team ID of the automated report.
*
* @return int
*/
public function getTeamId(): int
{
return $this->getAttribute('team_id');
}
/**
* Get the type of the automated report.
*
* @return string
*/
public function getType(): string
{
return $this->getAttribute('type');
}
/**
* Get the status of the automated report.
* True means active, false means inactive.
*
* @return bool
*/
public function getStatus(): bool
{
return $this->getAttribute('status');
}
/**
* Get the frequency of the automated report.
*
* @return string
*/
public function getFrequency(): string
{
return $this->getAttribute('frequency');
}
/**
* Get the from date of the automated report.
*
* @return Carbon|null
*/
public function getFrom(): ?Carbon
{
return $this->getAttribute('from');
}
/**
* Get the to date of the automated report.
*
* @return Carbon|null
*/
public function getTo(): ?Carbon
{
return $this->getAttribute('to');
}
/**
* Get the minimum deal value of the automated report.
*
* @return int|null
*/
public function getDealValueMin(): ?int
{
return $this->getAttribute('deal_value_min');
}
/**
* Get the maximum deal value of the automated report.
*
* @return int|null
*/
public function getDealValueMax(): ?int
{
return $this->getAttribute('deal_value_max');
}
/**
* Get the call types of the automated report.
*
* @return array
*/
public function getCallTypes(): array
{
return $this->getAttribute('call_types') ?? [];
}
public function getMediaTypes(): array
{
return $this->getAttribute('media_types') ?? [];
}
/**
* Get the minimum call duration of the automated report.
*
* @return int|null
*/
public function getCallDurationMin(): ?int
{
return $this->getAttribute('call_duration_min');
}
/**
* Get the maximum call duration of the automated report.
*
* @return int|null
*/
public function getCallDurationMax(): ?int
{
return $this->getAttribute('call_duration_max');
}
/**
* Get the groups of the automated report.
*
* @return array
*/
public function getGroups(): array
{
return $this->getAttribute('groups') ?? [];
}
/**
* Get the playbook categories of the automated report.
*
* @return array
*/
public function getPlaybookCategories(): array
{
return $this->getAttribute('playbook_categories') ?? [];
}
/**
* Get the deal at call stages of the automated report.
*
* @return array
*/
public function getDealAtCallStages(): array
{
return $this->getAttribute('deal_at_call_stages') ?? [];
}
/**
* Get the current deal stages of the automated report.
*
* @return array
*/
public function getCurrentDealStages(): array
{
return $this->getAttribute('current_deal_stages') ?? [];
}
/**
* Get the recipients of the automated report.
*
* @return array
*/
public function getRecipients(): array
{
return $this->getAttribute('recipients') ?? [];
}
/**
* Get the Jiminny's recipients of the automated report.
*
* @return array
*/
public function getJiminnyRecipients(): array
{
return $this->getAttribute('jiminny_recipients') ?? [];
}
/**
* Get the additional prompt input of the automated report.
*
* @return string|null
*/
public function getAdditionalPromptInput(): ?string
{
return $this->getAttribute('additional_prompt_input');
}
public function getCustomName(): ?string
{
return $this->getAttribute('custom_name');
}
/**
* Get the created at date of the automated report.
*
* @return Carbon
*/
public function getCreatedAt(): Carbon
{
return $this->getAttribute('created_at');
}
/**
* Get the updated at date of the automated report.
*
* @return Carbon
*/
public function getUpdatedAt(): Carbon
{
return $this->getAttribute('updated_at');
}
/**
* Get the deleted at date of the automated report.
*
* @return Carbon|null
*/
public function getDeletedAt(): ?Carbon
{
return $this->getAttribute('deleted_at');
}
public function getTeam(): Team
{
return $this->getAttribute('team');
}
public function getCreator(): ?User
{
return $this->getAttribute('creator');
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20676-delete-report-related-objects, menu","depth":5,"on_screen":true,"help_text":"Git Branch: JY-20676-delete-report-related-objects","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":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"6","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Models;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Support\\Carbon;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\AskAnything\\AskAnythingPrompt;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Traits\\RequiresUUID;\n\n/**\n * Jiminny\\Models\\AutomatedReport\n *\n * @property int $id\n * @property string $uuid\n * @property int $team_id\n * @property string $type\n * @property bool $status\n * @property string $frequency\n * @property Carbon|null $from\n * @property Carbon|null $to\n * @property int|null $deal_value_min\n * @property int|null $deal_value_max\n * @property array $call_types\n * @property array $media_types\n * @property int|null $call_duration_min\n * @property int|null $call_duration_max\n * @property array|null $groups\n * @property array|null $playbook_categories\n * @property array|null $deal_at_call_stages\n * @property array|null $current_deal_stages\n * @property array $recipients\n * @property string|null $additional_prompt_input\n * @property string|null $custom_name\n * @property int|null $activity_search_id\n * @property int|null $ask_anything_prompt_id\n * @property Carbon|null $expires_at\n * @property Carbon|null $created_at\n * @property Carbon|null $updated_at\n * @property Carbon|null $deleted_at\n * @property-read \\Jiminny\\Models\\Team $team\n * @property-read \\Jiminny\\Models\\Activity\\Search|null $savedSearch\n * @property-read \\Jiminny\\Models\\AskAnything\\AskAnythingPrompt|null $askAnythingPrompt\n */\nclass AutomatedReport extends Model\n{\n use RequiresUUID;\n use SoftDeletes;\n\n protected $table = 'automated_reports';\n\n /**\n * The attributes that are mass assignable.\n *\n * @var array<int, string>\n */\n protected $fillable = [\n 'team_id',\n 'type',\n 'status',\n 'frequency',\n 'from',\n 'to',\n 'deal_value_min',\n 'deal_value_max',\n 'call_types',\n 'media_types',\n 'call_duration_min',\n 'call_duration_max',\n 'groups',\n 'playbook_categories',\n 'deal_at_call_stages',\n 'current_deal_stages',\n 'recipients',\n 'jiminny_recipients',\n 'additional_prompt_input',\n 'custom_name',\n 'created_by',\n 'activity_search_id',\n 'ask_anything_prompt_id',\n 'expires_at',\n ];\n\n protected $hidden = ['uuid'];\n\n /**\n * Get the attributes that should be cast.\n *\n * @return array<string, string>\n */\n protected function casts(): array\n {\n return [\n 'status' => 'boolean',\n 'from' => 'datetime',\n 'to' => 'datetime',\n 'call_types' => 'array',\n 'media_types' => 'array',\n 'groups' => 'array',\n 'playbook_categories' => 'array',\n 'deal_at_call_stages' => 'array',\n 'current_deal_stages' => 'array',\n 'recipients' => 'array',\n 'jiminny_recipients' => 'array',\n 'expires_at' => 'date',\n 'deleted_at' => 'datetime',\n ];\n }\n\n /**\n * Get the team that owns the automated report.\n */\n public function team()\n {\n return $this->belongsTo(Team::class);\n }\n\n /**\n *\n * Get the user who created the report.\n */\n public function creator(): BelongsTo\n {\n return $this->belongsTo(User::class, 'created_by');\n }\n\n public function savedSearch(): BelongsTo\n {\n return $this->belongsTo(Search::class, 'activity_search_id');\n }\n\n public function askAnythingPrompt(): BelongsTo\n {\n return $this->belongsTo(AskAnythingPrompt::class, 'ask_anything_prompt_id');\n }\n\n public function isAskJiminnyReport(): bool\n {\n return $this->getType() === AutomatedReportsService::TYPE_ASK_JIMINNY;\n }\n\n public function isExpired(): bool\n {\n $expiresAt = $this->getExpiresAt();\n\n return $expiresAt !== null && $expiresAt->isPast();\n }\n\n public function canExecute(): bool\n {\n if ($this->isAskJiminnyReport()) {\n return $this->getActivitySearchId() !== null\n && $this->getAskAnythingPromptId() !== null;\n }\n\n return true;\n }\n\n public function getActivitySearchId(): ?int\n {\n return $this->getAttribute('activity_search_id');\n }\n\n public function getAskAnythingPromptId(): ?int\n {\n return $this->getAttribute('ask_anything_prompt_id');\n }\n\n public function getExpiresAt(): ?Carbon\n {\n return $this->getAttribute('expires_at');\n }\n\n public function getSavedSearch(): ?Search\n {\n return $this->getAttribute('savedSearch');\n }\n\n public function getAskAnythingPrompt(): ?AskAnythingPrompt\n {\n return $this->getAttribute('askAnythingPrompt');\n }\n\n /**\n * Get the ID of the automated report.\n *\n * @return int\n */\n public function getId(): int\n {\n return $this->getAttribute('id');\n }\n\n /**\n * Get the UUID of the automated report.\n *\n * @return string\n */\n public function getUuid(): string\n {\n return $this->getAttribute('id_string');\n }\n\n /**\n * Get the team ID of the automated report.\n *\n * @return int\n */\n public function getTeamId(): int\n {\n return $this->getAttribute('team_id');\n }\n\n /**\n * Get the type of the automated report.\n *\n * @return string\n */\n public function getType(): string\n {\n return $this->getAttribute('type');\n }\n\n /**\n * Get the status of the automated report.\n * True means active, false means inactive.\n *\n * @return bool\n */\n public function getStatus(): bool\n {\n return $this->getAttribute('status');\n }\n\n /**\n * Get the frequency of the automated report.\n *\n * @return string\n */\n public function getFrequency(): string\n {\n return $this->getAttribute('frequency');\n }\n\n /**\n * Get the from date of the automated report.\n *\n * @return Carbon|null\n */\n public function getFrom(): ?Carbon\n {\n return $this->getAttribute('from');\n }\n\n /**\n * Get the to date of the automated report.\n *\n * @return Carbon|null\n */\n public function getTo(): ?Carbon\n {\n return $this->getAttribute('to');\n }\n\n /**\n * Get the minimum deal value of the automated report.\n *\n * @return int|null\n */\n public function getDealValueMin(): ?int\n {\n return $this->getAttribute('deal_value_min');\n }\n\n /**\n * Get the maximum deal value of the automated report.\n *\n * @return int|null\n */\n public function getDealValueMax(): ?int\n {\n return $this->getAttribute('deal_value_max');\n }\n\n /**\n * Get the call types of the automated report.\n *\n * @return array\n */\n public function getCallTypes(): array\n {\n return $this->getAttribute('call_types') ?? [];\n }\n\n public function getMediaTypes(): array\n {\n return $this->getAttribute('media_types') ?? [];\n }\n\n /**\n * Get the minimum call duration of the automated report.\n *\n * @return int|null\n */\n public function getCallDurationMin(): ?int\n {\n return $this->getAttribute('call_duration_min');\n }\n\n /**\n * Get the maximum call duration of the automated report.\n *\n * @return int|null\n */\n public function getCallDurationMax(): ?int\n {\n return $this->getAttribute('call_duration_max');\n }\n\n /**\n * Get the groups of the automated report.\n *\n * @return array\n */\n public function getGroups(): array\n {\n return $this->getAttribute('groups') ?? [];\n }\n\n /**\n * Get the playbook categories of the automated report.\n *\n * @return array\n */\n public function getPlaybookCategories(): array\n {\n return $this->getAttribute('playbook_categories') ?? [];\n }\n\n /**\n * Get the deal at call stages of the automated report.\n *\n * @return array\n */\n public function getDealAtCallStages(): array\n {\n return $this->getAttribute('deal_at_call_stages') ?? [];\n }\n\n /**\n * Get the current deal stages of the automated report.\n *\n * @return array\n */\n public function getCurrentDealStages(): array\n {\n return $this->getAttribute('current_deal_stages') ?? [];\n }\n\n /**\n * Get the recipients of the automated report.\n *\n * @return array\n */\n public function getRecipients(): array\n {\n return $this->getAttribute('recipients') ?? [];\n }\n\n /**\n * Get the Jiminny's recipients of the automated report.\n *\n * @return array\n */\n public function getJiminnyRecipients(): array\n {\n return $this->getAttribute('jiminny_recipients') ?? [];\n }\n\n /**\n * Get the additional prompt input of the automated report.\n *\n * @return string|null\n */\n public function getAdditionalPromptInput(): ?string\n {\n return $this->getAttribute('additional_prompt_input');\n }\n\n public function getCustomName(): ?string\n {\n return $this->getAttribute('custom_name');\n }\n\n /**\n * Get the created at date of the automated report.\n *\n * @return Carbon\n */\n public function getCreatedAt(): Carbon\n {\n return $this->getAttribute('created_at');\n }\n\n /**\n * Get the updated at date of the automated report.\n *\n * @return Carbon\n */\n public function getUpdatedAt(): Carbon\n {\n return $this->getAttribute('updated_at');\n }\n\n /**\n * Get the deleted at date of the automated report.\n *\n * @return Carbon|null\n */\n public function getDeletedAt(): ?Carbon\n {\n return $this->getAttribute('deleted_at');\n }\n\n public function getTeam(): Team\n {\n return $this->getAttribute('team');\n }\n\n public function getCreator(): ?User\n {\n return $this->getAttribute('creator');\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Models;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Support\\Carbon;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\AskAnything\\AskAnythingPrompt;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Traits\\RequiresUUID;\n\n/**\n * Jiminny\\Models\\AutomatedReport\n *\n * @property int $id\n * @property string $uuid\n * @property int $team_id\n * @property string $type\n * @property bool $status\n * @property string $frequency\n * @property Carbon|null $from\n * @property Carbon|null $to\n * @property int|null $deal_value_min\n * @property int|null $deal_value_max\n * @property array $call_types\n * @property array $media_types\n * @property int|null $call_duration_min\n * @property int|null $call_duration_max\n * @property array|null $groups\n * @property array|null $playbook_categories\n * @property array|null $deal_at_call_stages\n * @property array|null $current_deal_stages\n * @property array $recipients\n * @property string|null $additional_prompt_input\n * @property string|null $custom_name\n * @property int|null $activity_search_id\n * @property int|null $ask_anything_prompt_id\n * @property Carbon|null $expires_at\n * @property Carbon|null $created_at\n * @property Carbon|null $updated_at\n * @property Carbon|null $deleted_at\n * @property-read \\Jiminny\\Models\\Team $team\n * @property-read \\Jiminny\\Models\\Activity\\Search|null $savedSearch\n * @property-read \\Jiminny\\Models\\AskAnything\\AskAnythingPrompt|null $askAnythingPrompt\n */\nclass AutomatedReport extends Model\n{\n use RequiresUUID;\n use SoftDeletes;\n\n protected $table = 'automated_reports';\n\n /**\n * The attributes that are mass assignable.\n *\n * @var array<int, string>\n */\n protected $fillable = [\n 'team_id',\n 'type',\n 'status',\n 'frequency',\n 'from',\n 'to',\n 'deal_value_min',\n 'deal_value_max',\n 'call_types',\n 'media_types',\n 'call_duration_min',\n 'call_duration_max',\n 'groups',\n 'playbook_categories',\n 'deal_at_call_stages',\n 'current_deal_stages',\n 'recipients',\n 'jiminny_recipients',\n 'additional_prompt_input',\n 'custom_name',\n 'created_by',\n 'activity_search_id',\n 'ask_anything_prompt_id',\n 'expires_at',\n ];\n\n protected $hidden = ['uuid'];\n\n /**\n * Get the attributes that should be cast.\n *\n * @return array<string, string>\n */\n protected function casts(): array\n {\n return [\n 'status' => 'boolean',\n 'from' => 'datetime',\n 'to' => 'datetime',\n 'call_types' => 'array',\n 'media_types' => 'array',\n 'groups' => 'array',\n 'playbook_categories' => 'array',\n 'deal_at_call_stages' => 'array',\n 'current_deal_stages' => 'array',\n 'recipients' => 'array',\n 'jiminny_recipients' => 'array',\n 'expires_at' => 'date',\n 'deleted_at' => 'datetime',\n ];\n }\n\n /**\n * Get the team that owns the automated report.\n */\n public function team()\n {\n return $this->belongsTo(Team::class);\n }\n\n /**\n *\n * Get the user who created the report.\n */\n public function creator(): BelongsTo\n {\n return $this->belongsTo(User::class, 'created_by');\n }\n\n public function savedSearch(): BelongsTo\n {\n return $this->belongsTo(Search::class, 'activity_search_id');\n }\n\n public function askAnythingPrompt(): BelongsTo\n {\n return $this->belongsTo(AskAnythingPrompt::class, 'ask_anything_prompt_id');\n }\n\n public function isAskJiminnyReport(): bool\n {\n return $this->getType() === AutomatedReportsService::TYPE_ASK_JIMINNY;\n }\n\n public function isExpired(): bool\n {\n $expiresAt = $this->getExpiresAt();\n\n return $expiresAt !== null && $expiresAt->isPast();\n }\n\n public function canExecute(): bool\n {\n if ($this->isAskJiminnyReport()) {\n return $this->getActivitySearchId() !== null\n && $this->getAskAnythingPromptId() !== null;\n }\n\n return true;\n }\n\n public function getActivitySearchId(): ?int\n {\n return $this->getAttribute('activity_search_id');\n }\n\n public function getAskAnythingPromptId(): ?int\n {\n return $this->getAttribute('ask_anything_prompt_id');\n }\n\n public function getExpiresAt(): ?Carbon\n {\n return $this->getAttribute('expires_at');\n }\n\n public function getSavedSearch(): ?Search\n {\n return $this->getAttribute('savedSearch');\n }\n\n public function getAskAnythingPrompt(): ?AskAnythingPrompt\n {\n return $this->getAttribute('askAnythingPrompt');\n }\n\n /**\n * Get the ID of the automated report.\n *\n * @return int\n */\n public function getId(): int\n {\n return $this->getAttribute('id');\n }\n\n /**\n * Get the UUID of the automated report.\n *\n * @return string\n */\n public function getUuid(): string\n {\n return $this->getAttribute('id_string');\n }\n\n /**\n * Get the team ID of the automated report.\n *\n * @return int\n */\n public function getTeamId(): int\n {\n return $this->getAttribute('team_id');\n }\n\n /**\n * Get the type of the automated report.\n *\n * @return string\n */\n public function getType(): string\n {\n return $this->getAttribute('type');\n }\n\n /**\n * Get the status of the automated report.\n * True means active, false means inactive.\n *\n * @return bool\n */\n public function getStatus(): bool\n {\n return $this->getAttribute('status');\n }\n\n /**\n * Get the frequency of the automated report.\n *\n * @return string\n */\n public function getFrequency(): string\n {\n return $this->getAttribute('frequency');\n }\n\n /**\n * Get the from date of the automated report.\n *\n * @return Carbon|null\n */\n public function getFrom(): ?Carbon\n {\n return $this->getAttribute('from');\n }\n\n /**\n * Get the to date of the automated report.\n *\n * @return Carbon|null\n */\n public function getTo(): ?Carbon\n {\n return $this->getAttribute('to');\n }\n\n /**\n * Get the minimum deal value of the automated report.\n *\n * @return int|null\n */\n public function getDealValueMin(): ?int\n {\n return $this->getAttribute('deal_value_min');\n }\n\n /**\n * Get the maximum deal value of the automated report.\n *\n * @return int|null\n */\n public function getDealValueMax(): ?int\n {\n return $this->getAttribute('deal_value_max');\n }\n\n /**\n * Get the call types of the automated report.\n *\n * @return array\n */\n public function getCallTypes(): array\n {\n return $this->getAttribute('call_types') ?? [];\n }\n\n public function getMediaTypes(): array\n {\n return $this->getAttribute('media_types') ?? [];\n }\n\n /**\n * Get the minimum call duration of the automated report.\n *\n * @return int|null\n */\n public function getCallDurationMin(): ?int\n {\n return $this->getAttribute('call_duration_min');\n }\n\n /**\n * Get the maximum call duration of the automated report.\n *\n * @return int|null\n */\n public function getCallDurationMax(): ?int\n {\n return $this->getAttribute('call_duration_max');\n }\n\n /**\n * Get the groups of the automated report.\n *\n * @return array\n */\n public function getGroups(): array\n {\n return $this->getAttribute('groups') ?? [];\n }\n\n /**\n * Get the playbook categories of the automated report.\n *\n * @return array\n */\n public function getPlaybookCategories(): array\n {\n return $this->getAttribute('playbook_categories') ?? [];\n }\n\n /**\n * Get the deal at call stages of the automated report.\n *\n * @return array\n */\n public function getDealAtCallStages(): array\n {\n return $this->getAttribute('deal_at_call_stages') ?? [];\n }\n\n /**\n * Get the current deal stages of the automated report.\n *\n * @return array\n */\n public function getCurrentDealStages(): array\n {\n return $this->getAttribute('current_deal_stages') ?? [];\n }\n\n /**\n * Get the recipients of the automated report.\n *\n * @return array\n */\n public function getRecipients(): array\n {\n return $this->getAttribute('recipients') ?? [];\n }\n\n /**\n * Get the Jiminny's recipients of the automated report.\n *\n * @return array\n */\n public function getJiminnyRecipients(): array\n {\n return $this->getAttribute('jiminny_recipients') ?? [];\n }\n\n /**\n * Get the additional prompt input of the automated report.\n *\n * @return string|null\n */\n public function getAdditionalPromptInput(): ?string\n {\n return $this->getAttribute('additional_prompt_input');\n }\n\n public function getCustomName(): ?string\n {\n return $this->getAttribute('custom_name');\n }\n\n /**\n * Get the created at date of the automated report.\n *\n * @return Carbon\n */\n public function getCreatedAt(): Carbon\n {\n return $this->getAttribute('created_at');\n }\n\n /**\n * Get the updated at date of the automated report.\n *\n * @return Carbon\n */\n public function getUpdatedAt(): Carbon\n {\n return $this->getAttribute('updated_at');\n }\n\n /**\n * Get the deleted at date of the automated report.\n *\n * @return Carbon|null\n */\n public function getDeletedAt(): ?Carbon\n {\n return $this->getAttribute('deleted_at');\n }\n\n public function getTeam(): Team\n {\n return $this->getAttribute('team');\n }\n\n public function getCreator(): ?User\n {\n return $this->getAttribute('creator');\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\ActivitySearch\\FilterDefinition;\n\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQuery;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionQueryCollection;\nuse Jiminny\\Contracts\\ActivitySearch\\ValidatedFilterDefinitionInterface;\nuse Jiminny\\Contracts\\Repositories\\UserRepository;\nuse Jiminny\\Models;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Elastica\\Query;\n\nfinal class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface\n{\n private const int NO_GROUP_ID = 999;\n private UserRepository $userRepository;\n\n public function __construct(UserRepository $userRepository)\n {\n $this->userRepository = $userRepository;\n }\n\n public function shouldApplyQueries(): bool\n {\n return count($this->getValue()) > 0;\n }\n\n public function getQueries(): FilterDefinitionQueryCollection\n {\n $userIds = $this->getValue();\n\n return FilterDefinitionQueryCollection::make([\n FilterDefinitionQuery::instance()\n ->setQuery(new Query\\Terms('coachingFeedbacks.coach.id_string', $userIds))\n ->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),\n ]);\n }\n\n public function toArray(): array\n {\n return [\n 'id' => 'coaching-feedback-user-filter',\n 'label' => 'Coach',\n 'helpText' => 'The person who completed the Coaching Framework',\n 'placeholder' => 'Search coaches',\n 'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,\n 'queryParam' => 'coaching_feedback_coach_id',\n 'options' => $this->getOptions(),\n 'groupLabelKey' => 'label',\n 'groupValuesKey' => 'users',\n 'optionLabelKey' => 'name',\n 'optionValueKey' => 'id',\n 'value' => $this->getValue(),\n ];\n }\n\n private function getOptions(): array\n {\n $user = $this->executedBy;\n $query = $user\n ->getTeam()\n ->users()\n ->whereNotIn(\n 'uuid',\n $this->userRepository->findInaccessibleDeactivatedUserUuids($user)\n ->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))\n ->all(),\n )\n ->orderBy('name');\n\n $users = $query\n ->with('group')\n ->get()\n ->reduce(\n static function (array $carry, Models\\User $user): array {\n $group = $user->getGroup();\n $groupId = $group !== null\n ? $group->getUuid()\n : self::NO_GROUP_ID;\n $groupName = $group !== null\n ? $group->getName()\n : '(NON-GROUPED)';\n\n if (! array_key_exists($groupId, $carry)) {\n $carry[$groupId] = [\n 'label' => $groupName,\n 'users' => [],\n ];\n }\n\n $carry[$groupId]['users'][] = [\n 'id' => $user->getUuid(),\n 'name' => sprintf(\n '%s%s',\n $user->getName(),\n ! $user->isStatusActive()\n ? ' (Inactive)'\n : ''\n ),\n ];\n\n return $carry;\n },\n []\n );\n\n return Collection::make($users)\n ->sortBy('label')\n ->values()\n ->toArray();\n }\n\n public function getValue(): array\n {\n if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {\n return $this->getDefaultValue();\n }\n\n return array_diff(\n $this->criteria->getCoachingFeedbackCoachUserId(),\n $this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),\n );\n }\n\n private function getDefaultValue(): array\n {\n return [];\n }\n\n public function getValidationRules(?string $prefix = null): array\n {\n $team = $this->executedBy->getTeam();\n\n return [\n $prefix . 'coaching_feedback_coach_id' => 'array',\n $prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),\n ];\n }\n\n public function getSortOrder(): int\n {\n return 86;\n }\n\n public function shouldBeIncluded(Team $team): bool\n {\n return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
7602850585725000454
|
-741603152122655068
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20676-delete-report-re Project: faVsco.js, menu
JY-20676-delete-report-related-objects, 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
6
1
6
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Carbon;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\AskAnything\AskAnythingPrompt;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Traits\RequiresUUID;
/**
* Jiminny\Models\AutomatedReport
*
* @property int $id
* @property string $uuid
* @property int $team_id
* @property string $type
* @property bool $status
* @property string $frequency
* @property Carbon|null $from
* @property Carbon|null $to
* @property int|null $deal_value_min
* @property int|null $deal_value_max
* @property array $call_types
* @property array $media_types
* @property int|null $call_duration_min
* @property int|null $call_duration_max
* @property array|null $groups
* @property array|null $playbook_categories
* @property array|null $deal_at_call_stages
* @property array|null $current_deal_stages
* @property array $recipients
* @property string|null $additional_prompt_input
* @property string|null $custom_name
* @property int|null $activity_search_id
* @property int|null $ask_anything_prompt_id
* @property Carbon|null $expires_at
* @property Carbon|null $created_at
* @property Carbon|null $updated_at
* @property Carbon|null $deleted_at
* @property-read \Jiminny\Models\Team $team
* @property-read \Jiminny\Models\Activity\Search|null $savedSearch
* @property-read \Jiminny\Models\AskAnything\AskAnythingPrompt|null $askAnythingPrompt
*/
class AutomatedReport extends Model
{
use RequiresUUID;
use SoftDeletes;
protected $table = 'automated_reports';
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'team_id',
'type',
'status',
'frequency',
'from',
'to',
'deal_value_min',
'deal_value_max',
'call_types',
'media_types',
'call_duration_min',
'call_duration_max',
'groups',
'playbook_categories',
'deal_at_call_stages',
'current_deal_stages',
'recipients',
'jiminny_recipients',
'additional_prompt_input',
'custom_name',
'created_by',
'activity_search_id',
'ask_anything_prompt_id',
'expires_at',
];
protected $hidden = ['uuid'];
/**
* Get the attributes that should be cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'status' => 'boolean',
'from' => 'datetime',
'to' => 'datetime',
'call_types' => 'array',
'media_types' => 'array',
'groups' => 'array',
'playbook_categories' => 'array',
'deal_at_call_stages' => 'array',
'current_deal_stages' => 'array',
'recipients' => 'array',
'jiminny_recipients' => 'array',
'expires_at' => 'date',
'deleted_at' => 'datetime',
];
}
/**
* Get the team that owns the automated report.
*/
public function team()
{
return $this->belongsTo(Team::class);
}
/**
*
* Get the user who created the report.
*/
public function creator(): BelongsTo
{
return $this->belongsTo(User::class, 'created_by');
}
public function savedSearch(): BelongsTo
{
return $this->belongsTo(Search::class, 'activity_search_id');
}
public function askAnythingPrompt(): BelongsTo
{
return $this->belongsTo(AskAnythingPrompt::class, 'ask_anything_prompt_id');
}
public function isAskJiminnyReport(): bool
{
return $this->getType() === AutomatedReportsService::TYPE_ASK_JIMINNY;
}
public function isExpired(): bool
{
$expiresAt = $this->getExpiresAt();
return $expiresAt !== null && $expiresAt->isPast();
}
public function canExecute(): bool
{
if ($this->isAskJiminnyReport()) {
return $this->getActivitySearchId() !== null
&& $this->getAskAnythingPromptId() !== null;
}
return true;
}
public function getActivitySearchId(): ?int
{
return $this->getAttribute('activity_search_id');
}
public function getAskAnythingPromptId(): ?int
{
return $this->getAttribute('ask_anything_prompt_id');
}
public function getExpiresAt(): ?Carbon
{
return $this->getAttribute('expires_at');
}
public function getSavedSearch(): ?Search
{
return $this->getAttribute('savedSearch');
}
public function getAskAnythingPrompt(): ?AskAnythingPrompt
{
return $this->getAttribute('askAnythingPrompt');
}
/**
* Get the ID of the automated report.
*
* @return int
*/
public function getId(): int
{
return $this->getAttribute('id');
}
/**
* Get the UUID of the automated report.
*
* @return string
*/
public function getUuid(): string
{
return $this->getAttribute('id_string');
}
/**
* Get the team ID of the automated report.
*
* @return int
*/
public function getTeamId(): int
{
return $this->getAttribute('team_id');
}
/**
* Get the type of the automated report.
*
* @return string
*/
public function getType(): string
{
return $this->getAttribute('type');
}
/**
* Get the status of the automated report.
* True means active, false means inactive.
*
* @return bool
*/
public function getStatus(): bool
{
return $this->getAttribute('status');
}
/**
* Get the frequency of the automated report.
*
* @return string
*/
public function getFrequency(): string
{
return $this->getAttribute('frequency');
}
/**
* Get the from date of the automated report.
*
* @return Carbon|null
*/
public function getFrom(): ?Carbon
{
return $this->getAttribute('from');
}
/**
* Get the to date of the automated report.
*
* @return Carbon|null
*/
public function getTo(): ?Carbon
{
return $this->getAttribute('to');
}
/**
* Get the minimum deal value of the automated report.
*
* @return int|null
*/
public function getDealValueMin(): ?int
{
return $this->getAttribute('deal_value_min');
}
/**
* Get the maximum deal value of the automated report.
*
* @return int|null
*/
public function getDealValueMax(): ?int
{
return $this->getAttribute('deal_value_max');
}
/**
* Get the call types of the automated report.
*
* @return array
*/
public function getCallTypes(): array
{
return $this->getAttribute('call_types') ?? [];
}
public function getMediaTypes(): array
{
return $this->getAttribute('media_types') ?? [];
}
/**
* Get the minimum call duration of the automated report.
*
* @return int|null
*/
public function getCallDurationMin(): ?int
{
return $this->getAttribute('call_duration_min');
}
/**
* Get the maximum call duration of the automated report.
*
* @return int|null
*/
public function getCallDurationMax(): ?int
{
return $this->getAttribute('call_duration_max');
}
/**
* Get the groups of the automated report.
*
* @return array
*/
public function getGroups(): array
{
return $this->getAttribute('groups') ?? [];
}
/**
* Get the playbook categories of the automated report.
*
* @return array
*/
public function getPlaybookCategories(): array
{
return $this->getAttribute('playbook_categories') ?? [];
}
/**
* Get the deal at call stages of the automated report.
*
* @return array
*/
public function getDealAtCallStages(): array
{
return $this->getAttribute('deal_at_call_stages') ?? [];
}
/**
* Get the current deal stages of the automated report.
*
* @return array
*/
public function getCurrentDealStages(): array
{
return $this->getAttribute('current_deal_stages') ?? [];
}
/**
* Get the recipients of the automated report.
*
* @return array
*/
public function getRecipients(): array
{
return $this->getAttribute('recipients') ?? [];
}
/**
* Get the Jiminny's recipients of the automated report.
*
* @return array
*/
public function getJiminnyRecipients(): array
{
return $this->getAttribute('jiminny_recipients') ?? [];
}
/**
* Get the additional prompt input of the automated report.
*
* @return string|null
*/
public function getAdditionalPromptInput(): ?string
{
return $this->getAttribute('additional_prompt_input');
}
public function getCustomName(): ?string
{
return $this->getAttribute('custom_name');
}
/**
* Get the created at date of the automated report.
*
* @return Carbon
*/
public function getCreatedAt(): Carbon
{
return $this->getAttribute('created_at');
}
/**
* Get the updated at date of the automated report.
*
* @return Carbon
*/
public function getUpdatedAt(): Carbon
{
return $this->getAttribute('updated_at');
}
/**
* Get the deleted at date of the automated report.
*
* @return Carbon|null
*/
public function getDeletedAt(): ?Carbon
{
return $this->getAttribute('deleted_at');
}
public function getTeam(): Team
{
return $this->getAttribute('team');
}
public function getCreator(): ?User
{
return $this->getAttribute('creator');
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\ActivitySearch\FilterDefinition;
use Illuminate\Support\Collection;
use Jiminny\Component\ActivitySearch\FilterDefinition;
use Jiminny\Component\ActivitySearch\FilterDefinitionQuery;
use Jiminny\Component\ActivitySearch\FilterDefinitionQueryCollection;
use Jiminny\Contracts\ActivitySearch\ValidatedFilterDefinitionInterface;
use Jiminny\Contracts\Repositories\UserRepository;
use Jiminny\Models;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Team;
use Jiminny\Traits\RequiresUUID;
use Elastica\Query;
final class CoachingFeedbackCoachUserIn extends FilterDefinition implements ValidatedFilterDefinitionInterface
{
private const int NO_GROUP_ID = 999;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function shouldApplyQueries(): bool
{
return count($this->getValue()) > 0;
}
public function getQueries(): FilterDefinitionQueryCollection
{
$userIds = $this->getValue();
return FilterDefinitionQueryCollection::make([
FilterDefinitionQuery::instance()
->setQuery(new Query\Terms('coachingFeedbacks.coach.id_string', $userIds))
->setPath('coachingFeedbacks.coach', 'coachingFeedbacks'),
]);
}
public function toArray(): array
{
return [
'id' => 'coaching-feedback-user-filter',
'label' => 'Coach',
'helpText' => 'The person who completed the Coaching Framework',
'placeholder' => 'Search coaches',
'inputType' => InputTypeEnum::DROPDOWN_MULTIPLE,
'queryParam' => 'coaching_feedback_coach_id',
'options' => $this->getOptions(),
'groupLabelKey' => 'label',
'groupValuesKey' => 'users',
'optionLabelKey' => 'name',
'optionValueKey' => 'id',
'value' => $this->getValue(),
];
}
private function getOptions(): array
{
$user = $this->executedBy;
$query = $user
->getTeam()
->users()
->whereNotIn(
'uuid',
$this->userRepository->findInaccessibleDeactivatedUserUuids($user)
->map(static fn (string $uuid): string => RequiresUUID::toOptimized($uuid))
->all(),
)
->orderBy('name');
$users = $query
->with('group')
->get()
->reduce(
static function (array $carry, Models\User $user): array {
$group = $user->getGroup();
$groupId = $group !== null
? $group->getUuid()
: self::NO_GROUP_ID;
$groupName = $group !== null
? $group->getName()
: '(NON-GROUPED)';
if (! array_key_exists($groupId, $carry)) {
$carry[$groupId] = [
'label' => $groupName,
'users' => [],
];
}
$carry[$groupId]['users'][] = [
'id' => $user->getUuid(),
'name' => sprintf(
'%s%s',
$user->getName(),
! $user->isStatusActive()
? ' (Inactive)'
: ''
),
];
return $carry;
},
[]
);
return Collection::make($users)
->sortBy('label')
->values()
->toArray();
}
public function getValue(): array
{
if (! $this->criteria->hasCoachingFeedbackCoachUserIds()) {
return $this->getDefaultValue();
}
return array_diff(
$this->criteria->getCoachingFeedbackCoachUserId(),
$this->userRepository->findInaccessibleDeactivatedUserUuids($this->executedBy)->all(),
);
}
private function getDefaultValue(): array
{
return [];
}
public function getValidationRules(?string $prefix = null): array
{
$team = $this->executedBy->getTeam();
return [
$prefix . 'coaching_feedback_coach_id' => 'array',
$prefix . 'coaching_feedback_coach_id.*' => 'uuid:users,team_id,' . $team->getId(),
];
}
public function getSortOrder(): int
{
return 86;
}
public function shouldBeIncluded(Team $team): bool
{
return $team->hasFeature(FeatureEnum::COACHING_FRAMEWORK);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
56296
|
NULL
|
NULL
|
NULL
|