|
11153
|
221
|
12
|
2026-04-14T09:15:39.834484+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158139834_m2.jpg...
|
PhpStorm
|
faVsco.js – AskJiminnyReportActivityService.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Kiosk\AutomatedReports;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityActualDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityUpdatedDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\DealInsights\ClosingPeriodFilter;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\User;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
class AskJiminnyReportActivityService
{
private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;
private const array DATE_FILTER_KEYS = [
ActivityActualDate::PARAM_START_DATE,
ActivityActualDate::PARAM_END_DATE,
ActivityUpdatedDate::PARAM_UPDATED_FROM,
ActivityUpdatedDate::PARAM_UPDATED_TO,
ClosingPeriodFilter::KEY_START_DATE,
ClosingPeriodFilter::KEY_END_DATE,
];
public function __construct(
private readonly ActivitySearch $activitySearch,
private readonly ElasticActivityRepository $elasticRepository,
private readonly LoggerInterface $logger,
) {
}
/**
* Fetch activity IDs for a saved search, passing its filters as-is to Criteria.
* Date filters stored on the saved search are excluded; if no other filters exist,
* no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.
*
* @return string[] Activity IDs
*/
public function getActivityIdsForSavedSearch(
Search $savedSearch,
User $user,
): array {
$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);
$criteria = Criteria::createFromRequest(
array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),
$user->getTimezone()
);
$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);
$activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);
$this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [
'saved_search_id' => $savedSearch->getId(),
'user_id' => $user->getId(),
'activity_count' => count($activityIds),
]);
return $activityIds;
}
private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array
{
$params = [];
$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);
foreach ($savedSearch->getFilters() as $filter) {
$key = $filter->getFilterProperty();
$value = $filter->getFilterValue();
if (in_array($key, self::DATE_FILTER_KEYS, true)) {
continue;
}
if (isset($params[$key])) {
$params[$key][] = $value;
} elseif (in_array($key, $arrayFilterKeys, true)) {
$params[$key] = [$value];
} else {
$params[$key] = $value;
}
}
return $params;
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Repositories;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSort;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSortDirection;
class AutomatedReportsRepository
{
/**
* Create a new automated report
*
* @param array $data
*
* @return AutomatedReport
*/
public function create(array $data): AutomatedReport
{
return AutomatedReport::create($data);
}
/**
* Find an automated report by UUID
*
* @param string $uuid
*
* @return AutomatedReport|null
*/
public function findByUuid(string $uuid): ?AutomatedReport
{
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();
}
public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport
{
if (is_numeric($idOrUuid)) {
return AutomatedReport::find((int) $idOrUuid);
}
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();
}
/**
* Retrieve all standard (non-Ask Jiminny) automated reports.
*
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAllStandardReports(
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->get();
}
/**
* Retrieve all Ask Jiminny reports created by the given user.
*
* @param User $user The user whose reports to retrieve.
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAskJiminnyReportsByUser(
User $user,
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->where('created_by', $user->getId())
->get();
}
private function buildSortedQuery(string $sortColumn, string $sortDirection): \Illuminate\Database\Eloquent\Builder
{
$allowedColumns = ['created_by', 'created_at'];
if (! in_array($sortColumn, $allowedColumns)) {
$sortColumn = 'created_at';
}
$sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';
$query = AutomatedReport::query()->with(['creator', 'team']);
if ($sortColumn === 'created_by') {
$query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')
->orderByRaw("users.name COLLATE utf8mb4_unicode_ci {$sortDirection}")
->select('automated_reports.*');
} else {
$query->orderBy($sortColumn, $sortDirection);
}
return $query;
}
/**
* Get all active and enabled reports with active teams for the specified frequency.
*
* @param string $frequency
*
* @return Collection<AutomatedReport>
*/
public function getActiveReportsByFrequency(string $frequency): Collection
{
return AutomatedReport::where('automated_reports.status', true)
->where('automated_reports.frequency', $frequency)
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->where('teams.status', Team::STATUS_ACTIVE)
->where(function ($query) {
$query->whereNull('automated_reports.expires_at')
->orWhere('automated_reports.expires_at', '>=', now()->toDateString());
})
->select('automated_reports.*')
->get();
}
/**
* Update an automated report
*
* @param AutomatedReport $report
* @param array $data
*
* @return AutomatedReport
*/
public function update(AutomatedReport $report, array $data): AutomatedReport
{
$report->update($data);
return $report;
}
/**
* Create a new automated report result.
*
* @param array $data The data to create the automated report result with.
*
* @return AutomatedReportResult The newly created automated report result.
*/
public function createResult(array $data): AutomatedReportResult
{
return AutomatedReportResult::create($data);
}
/**
* Find an automated report result by UUID.
*
* @param string $uuid The UUID to find the automated report result with.
*
* @return AutomatedReportResult|null The automated report result if found, otherwise null.
*/
public function findResultByUuid(string $uuid): ?AutomatedReportResult
{
return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();
}
public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('uuid', AutomatedReportResult::toOptimized($uuid))
->whereHas('report', static function ($query) use ($user): void {
$query->where('team_id', $user->getTeamId())
->where('created_by', $user->getId());
})
->first();
}
public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('parent_id', $result->getId())
->where('media_type', $type)
->first();
}
public function getGeneratedNotSentResults(): Collection
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNull('sent_at')
->where('status', AutomatedReportResult::STATUS_GENERATED)
->whereHas('report')
->with('report')
->get();
}
public function getPaginatedUserReports(
User $user,
ReportSort $sort,
ReportSortDirection $sortDirection,
int $resultsPerPage,
int $page,
?Carbon $fromDate,
?Carbon $toDate,
array $teamIds,
array $reportTypes,
?string $name,
): LengthAwarePaginator {
$query = AutomatedReportResult::query()
->whereNotNull('automated_report_results.generated_at')
->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')
->where('automated_reports.team_id', $user->getTeamId())
->whereJsonContains('automated_reports.recipients->users', $user->getId())
->orderByRaw("$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}")
->select('automated_report_results.*')
->with('report.team');
if ($fromDate !== null && $toDate !== null) {
$query->whereBetween('generated_at', [$fromDate, $toDate]);
}
if (! empty($teamIds)) {
$query->where(function ($q) use ($teamIds) {
foreach ($teamIds as $id) {
$q->orWhereJsonContains('automated_reports.groups', $id);
}
});
}
if (! empty($reportTypes)) {
$query->whereIn('automated_reports.type', $reportTypes);
}
if (! empty($name)) {
$query->whereLike('name', "%$name%");
}
return $query->paginate($resultsPerPage, ['*'], 'page', $page);
}
public function countUserReports(User $user): int
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNotNull('sent_at')
->whereHas('report', function ($q) use ($user) {
$q->where('team_id', $user->getTeamId())
->whereJsonContains('recipients->users', $user->getId());
})
->count();
}
/**
* Get report IDs for a specific team
*
* @param Team $team
*
* @return \Illuminate\Support\Collection
*/
public function getReportIdsByTeam(Team $team): \Illuminate\Support\Collection
{
return AutomatedReport::where('team_id', $team->getId())->pluck('id');
}
/**
* Get all reports for a specific team
*
* @param Team $team
*
* @return Collection
*/
public function getReportsByTeam(Team $team): Collection
{
return AutomatedReport::where('team_id', $team->getId())->get();
}
/**
* Get all report results for a specific report
*
* @param AutomatedReport $report
*
* @return Collection
*/
public function getResultsByReport(AutomatedReport $report): Collection
{
return $this->getResultsByReportQuery($report)->get();
}
public function getResultsByReportQuery(AutomatedReport $report): Builder
{
return AutomatedReportResult::where('report_id', $report->getId());
}
public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder
{
$reportIds = $this->getReportIdsByTeam($team);
return AutomatedReportResult::query()->whereIn('report_id', $reportIds)
->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);
}
/**
* @param int|null $teamId Optional team ID to filter results
*
* @return \Illuminate\Support\Collection<int, int> Collection of team IDs
*/
public function getTeamIdsWithReportsResults(?int $teamId = null): \Illuminate\Support\Collection
{
$query = DB::table('automated_reports')
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->select('teams.id')
->distinct();
if ($teamId !== null) {
$query->where('teams.id', $teamId);
}
return $query->pluck('teams.id');
}
}
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.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","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.7589844,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceT…Defaults","depth":6,"bounds":{"left":0.7769531,"top":0.017361112,"width":0.12382813,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.009375,"height":0.0},"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.00859375,"height":0.0},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.00859375,"height":0.0},"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.23320313,"top":1.0,"width":0.008203125,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Kiosk\\AutomatedReports;\n\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityActualDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityUpdatedDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealInsights\\ClosingPeriodFilter;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\n\nclass AskJiminnyReportActivityService\n{\n private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;\n\n private const array DATE_FILTER_KEYS = [\n ActivityActualDate::PARAM_START_DATE,\n ActivityActualDate::PARAM_END_DATE,\n ActivityUpdatedDate::PARAM_UPDATED_FROM,\n ActivityUpdatedDate::PARAM_UPDATED_TO,\n ClosingPeriodFilter::KEY_START_DATE,\n ClosingPeriodFilter::KEY_END_DATE,\n ];\n\n public function __construct(\n private readonly ActivitySearch $activitySearch,\n private readonly ElasticActivityRepository $elasticRepository,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n /**\n * Fetch activity IDs for a saved search, passing its filters as-is to Criteria.\n * Date filters stored on the saved search are excluded; if no other filters exist,\n * no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.\n *\n * @return string[] Activity IDs\n */\n public function getActivityIdsForSavedSearch(\n Search $savedSearch,\n User $user,\n ): array {\n $requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);\n\n $criteria = Criteria::createFromRequest(\n array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);\n\n $activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);\n\n $this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [\n 'saved_search_id' => $savedSearch->getId(),\n 'user_id' => $user->getId(),\n 'activity_count' => count($activityIds),\n ]);\n\n return $activityIds;\n }\n\n private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array\n {\n $params = [];\n $arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);\n\n foreach ($savedSearch->getFilters() as $filter) {\n $key = $filter->getFilterProperty();\n $value = $filter->getFilterValue();\n\n if (in_array($key, self::DATE_FILTER_KEYS, true)) {\n continue;\n }\n\n if (isset($params[$key])) {\n $params[$key][] = $value;\n } elseif (in_array($key, $arrayFilterKeys, true)) {\n $params[$key] = [$value];\n } else {\n $params[$key] = $value;\n }\n }\n\n return $params;\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Kiosk\\AutomatedReports;\n\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityActualDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityUpdatedDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealInsights\\ClosingPeriodFilter;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\n\nclass AskJiminnyReportActivityService\n{\n private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;\n\n private const array DATE_FILTER_KEYS = [\n ActivityActualDate::PARAM_START_DATE,\n ActivityActualDate::PARAM_END_DATE,\n ActivityUpdatedDate::PARAM_UPDATED_FROM,\n ActivityUpdatedDate::PARAM_UPDATED_TO,\n ClosingPeriodFilter::KEY_START_DATE,\n ClosingPeriodFilter::KEY_END_DATE,\n ];\n\n public function __construct(\n private readonly ActivitySearch $activitySearch,\n private readonly ElasticActivityRepository $elasticRepository,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n /**\n * Fetch activity IDs for a saved search, passing its filters as-is to Criteria.\n * Date filters stored on the saved search are excluded; if no other filters exist,\n * no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.\n *\n * @return string[] Activity IDs\n */\n public function getActivityIdsForSavedSearch(\n Search $savedSearch,\n User $user,\n ): array {\n $requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);\n\n $criteria = Criteria::createFromRequest(\n array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);\n\n $activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);\n\n $this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [\n 'saved_search_id' => $savedSearch->getId(),\n 'user_id' => $user->getId(),\n 'activity_count' => count($activityIds),\n ]);\n\n return $activityIds;\n }\n\n private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array\n {\n $params = [];\n $arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);\n\n foreach ($savedSearch->getFilters() as $filter) {\n $key = $filter->getFilterProperty();\n $value = $filter->getFilterValue();\n\n if (in_array($key, self::DATE_FILTER_KEYS, true)) {\n continue;\n }\n\n if (isset($params[$key])) {\n $params[$key][] = $value;\n } elseif (in_array($key, $arrayFilterKeys, true)) {\n $params[$key] = [$value];\n } else {\n $params[$key] = $value;\n }\n }\n\n return $params;\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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"15","depth":4,"bounds":{"left":0.2589844,"top":0.28125,"width":0.011328125,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.27265626,"top":0.28125,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.28398436,"top":0.27986112,"width":0.00859375,"height":0.015972223},"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.29257813,"top":0.27986112,"width":0.008203125,"height":0.015972223},"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\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\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,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.0140625,"top":0.041666668,"width":0.028515626,"height":0.021527778},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
8563436494813991353
|
-5967358188006330764
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Kiosk\AutomatedReports;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityActualDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityUpdatedDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\DealInsights\ClosingPeriodFilter;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\User;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
class AskJiminnyReportActivityService
{
private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;
private const array DATE_FILTER_KEYS = [
ActivityActualDate::PARAM_START_DATE,
ActivityActualDate::PARAM_END_DATE,
ActivityUpdatedDate::PARAM_UPDATED_FROM,
ActivityUpdatedDate::PARAM_UPDATED_TO,
ClosingPeriodFilter::KEY_START_DATE,
ClosingPeriodFilter::KEY_END_DATE,
];
public function __construct(
private readonly ActivitySearch $activitySearch,
private readonly ElasticActivityRepository $elasticRepository,
private readonly LoggerInterface $logger,
) {
}
/**
* Fetch activity IDs for a saved search, passing its filters as-is to Criteria.
* Date filters stored on the saved search are excluded; if no other filters exist,
* no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.
*
* @return string[] Activity IDs
*/
public function getActivityIdsForSavedSearch(
Search $savedSearch,
User $user,
): array {
$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);
$criteria = Criteria::createFromRequest(
array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),
$user->getTimezone()
);
$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);
$activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);
$this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [
'saved_search_id' => $savedSearch->getId(),
'user_id' => $user->getId(),
'activity_count' => count($activityIds),
]);
return $activityIds;
}
private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array
{
$params = [];
$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);
foreach ($savedSearch->getFilters() as $filter) {
$key = $filter->getFilterProperty();
$value = $filter->getFilterValue();
if (in_array($key, self::DATE_FILTER_KEYS, true)) {
continue;
}
if (isset($params[$key])) {
$params[$key][] = $value;
} elseif (in_array($key, $arrayFilterKeys, true)) {
$params[$key] = [$value];
} else {
$params[$key] = $value;
}
}
return $params;
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Repositories;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSort;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSortDirection;
class AutomatedReportsRepository
{
/**
* Create a new automated report
*
* @param array $data
*
* @return AutomatedReport
*/
public function create(array $data): AutomatedReport
{
return AutomatedReport::create($data);
}
/**
* Find an automated report by UUID
*
* @param string $uuid
*
* @return AutomatedReport|null
*/
public function findByUuid(string $uuid): ?AutomatedReport
{
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();
}
public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport
{
if (is_numeric($idOrUuid)) {
return AutomatedReport::find((int) $idOrUuid);
}
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();
}
/**
* Retrieve all standard (non-Ask Jiminny) automated reports.
*
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAllStandardReports(
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->get();
}
/**
* Retrieve all Ask Jiminny reports created by the given user.
*
* @param User $user The user whose reports to retrieve.
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAskJiminnyReportsByUser(
User $user,
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->where('created_by', $user->getId())
->get();
}
private function buildSortedQuery(string $sortColumn, string $sortDirection): \Illuminate\Database\Eloquent\Builder
{
$allowedColumns = ['created_by', 'created_at'];
if (! in_array($sortColumn, $allowedColumns)) {
$sortColumn = 'created_at';
}
$sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';
$query = AutomatedReport::query()->with(['creator', 'team']);
if ($sortColumn === 'created_by') {
$query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')
->orderByRaw("users.name COLLATE utf8mb4_unicode_ci {$sortDirection}")
->select('automated_reports.*');
} else {
$query->orderBy($sortColumn, $sortDirection);
}
return $query;
}
/**
* Get all active and enabled reports with active teams for the specified frequency.
*
* @param string $frequency
*
* @return Collection<AutomatedReport>
*/
public function getActiveReportsByFrequency(string $frequency): Collection
{
return AutomatedReport::where('automated_reports.status', true)
->where('automated_reports.frequency', $frequency)
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->where('teams.status', Team::STATUS_ACTIVE)
->where(function ($query) {
$query->whereNull('automated_reports.expires_at')
->orWhere('automated_reports.expires_at', '>=', now()->toDateString());
})
->select('automated_reports.*')
->get();
}
/**
* Update an automated report
*
* @param AutomatedReport $report
* @param array $data
*
* @return AutomatedReport
*/
public function update(AutomatedReport $report, array $data): AutomatedReport
{
$report->update($data);
return $report;
}
/**
* Create a new automated report result.
*
* @param array $data The data to create the automated report result with.
*
* @return AutomatedReportResult The newly created automated report result.
*/
public function createResult(array $data): AutomatedReportResult
{
return AutomatedReportResult::create($data);
}
/**
* Find an automated report result by UUID.
*
* @param string $uuid The UUID to find the automated report result with.
*
* @return AutomatedReportResult|null The automated report result if found, otherwise null.
*/
public function findResultByUuid(string $uuid): ?AutomatedReportResult
{
return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();
}
public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('uuid', AutomatedReportResult::toOptimized($uuid))
->whereHas('report', static function ($query) use ($user): void {
$query->where('team_id', $user->getTeamId())
->where('created_by', $user->getId());
})
->first();
}
public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('parent_id', $result->getId())
->where('media_type', $type)
->first();
}
public function getGeneratedNotSentResults(): Collection
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNull('sent_at')
->where('status', AutomatedReportResult::STATUS_GENERATED)
->whereHas('report')
->with('report')
->get();
}
public function getPaginatedUserReports(
User $user,
ReportSort $sort,
ReportSortDirection $sortDirection,
int $resultsPerPage,
int $page,
?Carbon $fromDate,
?Carbon $toDate,
array $teamIds,
array $reportTypes,
?string $name,
): LengthAwarePaginator {
$query = AutomatedReportResult::query()
->whereNotNull('automated_report_results.generated_at')
->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')
->where('automated_reports.team_id', $user->getTeamId())
->whereJsonContains('automated_reports.recipients->users', $user->getId())
->orderByRaw("$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}")
->select('automated_report_results.*')
->with('report.team');
if ($fromDate !== null && $toDate !== null) {
$query->whereBetween('generated_at', [$fromDate, $toDate]);
}
if (! empty($teamIds)) {
$query->where(function ($q) use ($teamIds) {
foreach ($teamIds as $id) {
$q->orWhereJsonContains('automated_reports.groups', $id);
}
});
}
if (! empty($reportTypes)) {
$query->whereIn('automated_reports.type', $reportTypes);
}
if (! empty($name)) {
$query->whereLike('name', "%$name%");
}
return $query->paginate($resultsPerPage, ['*'], 'page', $page);
}
public function countUserReports(User $user): int
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNotNull('sent_at')
->whereHas('report', function ($q) use ($user) {
$q->where('team_id', $user->getTeamId())
->whereJsonContains('recipients->users', $user->getId());
})
->count();
}
/**
* Get report IDs for a specific team
*
* @param Team $team
*
* @return \Illuminate\Support\Collection
*/
public function getReportIdsByTeam(Team $team): \Illuminate\Support\Collection
{
return AutomatedReport::where('team_id', $team->getId())->pluck('id');
}
/**
* Get all reports for a specific team
*
* @param Team $team
*
* @return Collection
*/
public function getReportsByTeam(Team $team): Collection
{
return AutomatedReport::where('team_id', $team->getId())->get();
}
/**
* Get all report results for a specific report
*
* @param AutomatedReport $report
*
* @return Collection
*/
public function getResultsByReport(AutomatedReport $report): Collection
{
return $this->getResultsByReportQuery($report)->get();
}
public function getResultsByReportQuery(AutomatedReport $report): Builder
{
return AutomatedReportResult::where('report_id', $report->getId());
}
public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder
{
$reportIds = $this->getReportIdsByTeam($team);
return AutomatedReportResult::query()->whereIn('report_id', $reportIds)
->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);
}
/**
* @param int|null $teamId Optional team ID to filter results
*
* @return \Illuminate\Support\Collection<int, int> Collection of team IDs
*/
public function getTeamIdsWithReportsResults(?int $teamId = null): \Illuminate\Support\Collection
{
$query = DB::table('automated_reports')
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->select('teams.id')
->distinct();
if ($teamId !== null) {
$query->where('teams.id', $teamId);
}
return $query->pluck('teams.id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
11151
|
|
11155
|
221
|
13
|
2026-04-14T09:16:10.155109+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158170155_m2.jpg...
|
PhpStorm
|
faVsco.js – AskJiminnyReportActivityService.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Kiosk\AutomatedReports;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityActualDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityUpdatedDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\DealInsights\ClosingPeriodFilter;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\User;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
class AskJiminnyReportActivityService
{
private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;
private const array DATE_FILTER_KEYS = [
ActivityActualDate::PARAM_START_DATE,
ActivityActualDate::PARAM_END_DATE,
ActivityUpdatedDate::PARAM_UPDATED_FROM,
ActivityUpdatedDate::PARAM_UPDATED_TO,
ClosingPeriodFilter::KEY_START_DATE,
ClosingPeriodFilter::KEY_END_DATE,
];
public function __construct(
private readonly ActivitySearch $activitySearch,
private readonly ElasticActivityRepository $elasticRepository,
private readonly LoggerInterface $logger,
) {
}
/**
* Fetch activity IDs for a saved search, passing its filters as-is to Criteria.
* Date filters stored on the saved search are excluded; if no other filters exist,
* no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.
*
* @return string[] Activity IDs
*/
public function getActivityIdsForSavedSearch(
Search $savedSearch,
User $user,
): array {
$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);
$criteria = Criteria::createFromRequest(
array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),
$user->getTimezone()
);
$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);
$activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);
$this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [
'saved_search_id' => $savedSearch->getId(),
'user_id' => $user->getId(),
'activity_count' => count($activityIds),
]);
return $activityIds;
}
private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array
{
$params = [];
$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);
foreach ($savedSearch->getFilters() as $filter) {
$key = $filter->getFilterProperty();
$value = $filter->getFilterValue();
if (in_array($key, self::DATE_FILTER_KEYS, true)) {
continue;
}
if (isset($params[$key])) {
$params[$key][] = $value;
} elseif (in_array($key, $arrayFilterKeys, true)) {
$params[$key] = [$value];
} else {
$params[$key] = $value;
}
}
return $params;
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Repositories;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSort;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSortDirection;
class AutomatedReportsRepository
{
/**
* Create a new automated report
*
* @param array $data
*
* @return AutomatedReport
*/
public function create(array $data): AutomatedReport
{
return AutomatedReport::create($data);
}
/**
* Find an automated report by UUID
*
* @param string $uuid
*
* @return AutomatedReport|null
*/
public function findByUuid(string $uuid): ?AutomatedReport
{
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();
}
public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport
{
if (is_numeric($idOrUuid)) {
return AutomatedReport::find((int) $idOrUuid);
}
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();
}
/**
* Retrieve all standard (non-Ask Jiminny) automated reports.
*
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAllStandardReports(
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->get();
}
/**
* Retrieve all Ask Jiminny reports created by the given user.
*
* @param User $user The user whose reports to retrieve.
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAskJiminnyReportsByUser(
User $user,
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->where('created_by', $user->getId())
->get();
}
private function buildSortedQuery(string $sortColumn, string $sortDirection): \Illuminate\Database\Eloquent\Builder
{
$allowedColumns = ['created_by', 'created_at'];
if (! in_array($sortColumn, $allowedColumns)) {
$sortColumn = 'created_at';
}
$sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';
$query = AutomatedReport::query()->with(['creator', 'team']);
if ($sortColumn === 'created_by') {
$query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')
->orderByRaw("users.name COLLATE utf8mb4_unicode_ci {$sortDirection}")
->select('automated_reports.*');
} else {
$query->orderBy($sortColumn, $sortDirection);
}
return $query;
}
/**
* Get all active and enabled reports with active teams for the specified frequency.
*
* @param string $frequency
*
* @return Collection<AutomatedReport>
*/
public function getActiveReportsByFrequency(string $frequency): Collection
{
return AutomatedReport::where('automated_reports.status', true)
->where('automated_reports.frequency', $frequency)
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->where('teams.status', Team::STATUS_ACTIVE)
->where(function ($query) {
$query->whereNull('automated_reports.expires_at')
->orWhere('automated_reports.expires_at', '>=', now()->toDateString());
})
->select('automated_reports.*')
->get();
}
/**
* Update an automated report
*
* @param AutomatedReport $report
* @param array $data
*
* @return AutomatedReport
*/
public function update(AutomatedReport $report, array $data): AutomatedReport
{
$report->update($data);
return $report;
}
/**
* Create a new automated report result.
*
* @param array $data The data to create the automated report result with.
*
* @return AutomatedReportResult The newly created automated report result.
*/
public function createResult(array $data): AutomatedReportResult
{
return AutomatedReportResult::create($data);
}
/**
* Find an automated report result by UUID.
*
* @param string $uuid The UUID to find the automated report result with.
*
* @return AutomatedReportResult|null The automated report result if found, otherwise null.
*/
public function findResultByUuid(string $uuid): ?AutomatedReportResult
{
return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();
}
public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('uuid', AutomatedReportResult::toOptimized($uuid))
->whereHas('report', static function ($query) use ($user): void {
$query->where('team_id', $user->getTeamId())
->where('created_by', $user->getId());
})
->first();
}
public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('parent_id', $result->getId())
->where('media_type', $type)
->first();
}
public function getGeneratedNotSentResults(): Collection
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNull('sent_at')
->where('status', AutomatedReportResult::STATUS_GENERATED)
->whereHas('report')
->with('report')
->get();
}
public function getPaginatedUserReports(
User $user,
ReportSort $sort,
ReportSortDirection $sortDirection,
int $resultsPerPage,
int $page,
?Carbon $fromDate,
?Carbon $toDate,
array $teamIds,
array $reportTypes,
?string $name,
): LengthAwarePaginator {
$query = AutomatedReportResult::query()
->whereNotNull('automated_report_results.generated_at')
->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')
->where('automated_reports.team_id', $user->getTeamId())
->whereJsonContains('automated_reports.recipients->users', $user->getId())
->orderByRaw("$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}")
->select('automated_report_results.*')
->with('report.team');
if ($fromDate !== null && $toDate !== null) {
$query->whereBetween('generated_at', [$fromDate, $toDate]);
}
if (! empty($teamIds)) {
$query->where(function ($q) use ($teamIds) {
foreach ($teamIds as $id) {
$q->orWhereJsonContains('automated_reports.groups', $id);
}
});
}
if (! empty($reportTypes)) {
$query->whereIn('automated_reports.type', $reportTypes);
}
if (! empty($name)) {
$query->whereLike('name', "%$name%");
}
return $query->paginate($resultsPerPage, ['*'], 'page', $page);
}
public function countUserReports(User $user): int
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNotNull('sent_at')
->whereHas('report', function ($q) use ($user) {
$q->where('team_id', $user->getTeamId())
->whereJsonContains('recipients->users', $user->getId());
})
->count();
}
/**
* Get report IDs for a specific team
*
* @param Team $team
*
* @return \Illuminate\Support\Collection
*/
public function getReportIdsByTeam(Team $team): \Illuminate\Support\Collection
{
return AutomatedReport::where('team_id', $team->getId())->pluck('id');
}
/**
* Get all reports for a specific team
*
* @param Team $team
*
* @return Collection
*/
public function getReportsByTeam(Team $team): Collection
{
return AutomatedReport::where('team_id', $team->getId())->get();
}
/**
* Get all report results for a specific report
*
* @param AutomatedReport $report
*
* @return Collection
*/
public function getResultsByReport(AutomatedReport $report): Collection
{
return $this->getResultsByReportQuery($report)->get();
}
public function getResultsByReportQuery(AutomatedReport $report): Builder
{
return AutomatedReportResult::where('report_id', $report->getId());
}
public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder
{
$reportIds = $this->getReportIdsByTeam($team);
return AutomatedReportResult::query()->whereIn('report_id', $reportIds)
->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);
}
/**
* @param int|null $teamId Optional team ID to filter results
*
* @return \Illuminate\Support\Collection<int, int> Collection of team IDs
*/
public function getTeamIdsWithReportsResults(?int $teamId = null): \Illuminate\Support\Collection
{
$query = DB::table('automated_reports')
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->select('teams.id')
->distinct();
if ($teamId !== null) {
$query->where('teams.id', $teamId);
}
return $query->pluck('teams.id');
}
}
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.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","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.7589844,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceT…Defaults","depth":6,"bounds":{"left":0.7769531,"top":0.017361112,"width":0.12382813,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.009375,"height":0.0},"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.00859375,"height":0.0},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.00859375,"height":0.0},"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.23320313,"top":1.0,"width":0.008203125,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Kiosk\\AutomatedReports;\n\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityActualDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityUpdatedDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealInsights\\ClosingPeriodFilter;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\n\nclass AskJiminnyReportActivityService\n{\n private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;\n\n private const array DATE_FILTER_KEYS = [\n ActivityActualDate::PARAM_START_DATE,\n ActivityActualDate::PARAM_END_DATE,\n ActivityUpdatedDate::PARAM_UPDATED_FROM,\n ActivityUpdatedDate::PARAM_UPDATED_TO,\n ClosingPeriodFilter::KEY_START_DATE,\n ClosingPeriodFilter::KEY_END_DATE,\n ];\n\n public function __construct(\n private readonly ActivitySearch $activitySearch,\n private readonly ElasticActivityRepository $elasticRepository,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n /**\n * Fetch activity IDs for a saved search, passing its filters as-is to Criteria.\n * Date filters stored on the saved search are excluded; if no other filters exist,\n * no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.\n *\n * @return string[] Activity IDs\n */\n public function getActivityIdsForSavedSearch(\n Search $savedSearch,\n User $user,\n ): array {\n $requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);\n\n $criteria = Criteria::createFromRequest(\n array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);\n\n $activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);\n\n $this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [\n 'saved_search_id' => $savedSearch->getId(),\n 'user_id' => $user->getId(),\n 'activity_count' => count($activityIds),\n ]);\n\n return $activityIds;\n }\n\n private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array\n {\n $params = [];\n $arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);\n\n foreach ($savedSearch->getFilters() as $filter) {\n $key = $filter->getFilterProperty();\n $value = $filter->getFilterValue();\n\n if (in_array($key, self::DATE_FILTER_KEYS, true)) {\n continue;\n }\n\n if (isset($params[$key])) {\n $params[$key][] = $value;\n } elseif (in_array($key, $arrayFilterKeys, true)) {\n $params[$key] = [$value];\n } else {\n $params[$key] = $value;\n }\n }\n\n return $params;\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Kiosk\\AutomatedReports;\n\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityActualDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityUpdatedDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealInsights\\ClosingPeriodFilter;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\n\nclass AskJiminnyReportActivityService\n{\n private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;\n\n private const array DATE_FILTER_KEYS = [\n ActivityActualDate::PARAM_START_DATE,\n ActivityActualDate::PARAM_END_DATE,\n ActivityUpdatedDate::PARAM_UPDATED_FROM,\n ActivityUpdatedDate::PARAM_UPDATED_TO,\n ClosingPeriodFilter::KEY_START_DATE,\n ClosingPeriodFilter::KEY_END_DATE,\n ];\n\n public function __construct(\n private readonly ActivitySearch $activitySearch,\n private readonly ElasticActivityRepository $elasticRepository,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n /**\n * Fetch activity IDs for a saved search, passing its filters as-is to Criteria.\n * Date filters stored on the saved search are excluded; if no other filters exist,\n * no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.\n *\n * @return string[] Activity IDs\n */\n public function getActivityIdsForSavedSearch(\n Search $savedSearch,\n User $user,\n ): array {\n $requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);\n\n $criteria = Criteria::createFromRequest(\n array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);\n\n $activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);\n\n $this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [\n 'saved_search_id' => $savedSearch->getId(),\n 'user_id' => $user->getId(),\n 'activity_count' => count($activityIds),\n ]);\n\n return $activityIds;\n }\n\n private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array\n {\n $params = [];\n $arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);\n\n foreach ($savedSearch->getFilters() as $filter) {\n $key = $filter->getFilterProperty();\n $value = $filter->getFilterValue();\n\n if (in_array($key, self::DATE_FILTER_KEYS, true)) {\n continue;\n }\n\n if (isset($params[$key])) {\n $params[$key][] = $value;\n } elseif (in_array($key, $arrayFilterKeys, true)) {\n $params[$key] = [$value];\n } else {\n $params[$key] = $value;\n }\n }\n\n return $params;\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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"15","depth":4,"bounds":{"left":0.2589844,"top":0.28125,"width":0.011328125,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.27265626,"top":0.28125,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.28398436,"top":0.27986112,"width":0.00859375,"height":0.015972223},"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.29257813,"top":0.27986112,"width":0.008203125,"height":0.015972223},"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\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\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,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.0140625,"top":0.041666668,"width":0.028515626,"height":0.021527778},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
8563436494813991353
|
-5967358188006330764
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Kiosk\AutomatedReports;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityActualDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityUpdatedDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\DealInsights\ClosingPeriodFilter;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\User;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
class AskJiminnyReportActivityService
{
private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;
private const array DATE_FILTER_KEYS = [
ActivityActualDate::PARAM_START_DATE,
ActivityActualDate::PARAM_END_DATE,
ActivityUpdatedDate::PARAM_UPDATED_FROM,
ActivityUpdatedDate::PARAM_UPDATED_TO,
ClosingPeriodFilter::KEY_START_DATE,
ClosingPeriodFilter::KEY_END_DATE,
];
public function __construct(
private readonly ActivitySearch $activitySearch,
private readonly ElasticActivityRepository $elasticRepository,
private readonly LoggerInterface $logger,
) {
}
/**
* Fetch activity IDs for a saved search, passing its filters as-is to Criteria.
* Date filters stored on the saved search are excluded; if no other filters exist,
* no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.
*
* @return string[] Activity IDs
*/
public function getActivityIdsForSavedSearch(
Search $savedSearch,
User $user,
): array {
$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);
$criteria = Criteria::createFromRequest(
array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),
$user->getTimezone()
);
$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);
$activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);
$this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [
'saved_search_id' => $savedSearch->getId(),
'user_id' => $user->getId(),
'activity_count' => count($activityIds),
]);
return $activityIds;
}
private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array
{
$params = [];
$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);
foreach ($savedSearch->getFilters() as $filter) {
$key = $filter->getFilterProperty();
$value = $filter->getFilterValue();
if (in_array($key, self::DATE_FILTER_KEYS, true)) {
continue;
}
if (isset($params[$key])) {
$params[$key][] = $value;
} elseif (in_array($key, $arrayFilterKeys, true)) {
$params[$key] = [$value];
} else {
$params[$key] = $value;
}
}
return $params;
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Repositories;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSort;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSortDirection;
class AutomatedReportsRepository
{
/**
* Create a new automated report
*
* @param array $data
*
* @return AutomatedReport
*/
public function create(array $data): AutomatedReport
{
return AutomatedReport::create($data);
}
/**
* Find an automated report by UUID
*
* @param string $uuid
*
* @return AutomatedReport|null
*/
public function findByUuid(string $uuid): ?AutomatedReport
{
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();
}
public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport
{
if (is_numeric($idOrUuid)) {
return AutomatedReport::find((int) $idOrUuid);
}
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();
}
/**
* Retrieve all standard (non-Ask Jiminny) automated reports.
*
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAllStandardReports(
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->get();
}
/**
* Retrieve all Ask Jiminny reports created by the given user.
*
* @param User $user The user whose reports to retrieve.
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAskJiminnyReportsByUser(
User $user,
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->where('created_by', $user->getId())
->get();
}
private function buildSortedQuery(string $sortColumn, string $sortDirection): \Illuminate\Database\Eloquent\Builder
{
$allowedColumns = ['created_by', 'created_at'];
if (! in_array($sortColumn, $allowedColumns)) {
$sortColumn = 'created_at';
}
$sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';
$query = AutomatedReport::query()->with(['creator', 'team']);
if ($sortColumn === 'created_by') {
$query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')
->orderByRaw("users.name COLLATE utf8mb4_unicode_ci {$sortDirection}")
->select('automated_reports.*');
} else {
$query->orderBy($sortColumn, $sortDirection);
}
return $query;
}
/**
* Get all active and enabled reports with active teams for the specified frequency.
*
* @param string $frequency
*
* @return Collection<AutomatedReport>
*/
public function getActiveReportsByFrequency(string $frequency): Collection
{
return AutomatedReport::where('automated_reports.status', true)
->where('automated_reports.frequency', $frequency)
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->where('teams.status', Team::STATUS_ACTIVE)
->where(function ($query) {
$query->whereNull('automated_reports.expires_at')
->orWhere('automated_reports.expires_at', '>=', now()->toDateString());
})
->select('automated_reports.*')
->get();
}
/**
* Update an automated report
*
* @param AutomatedReport $report
* @param array $data
*
* @return AutomatedReport
*/
public function update(AutomatedReport $report, array $data): AutomatedReport
{
$report->update($data);
return $report;
}
/**
* Create a new automated report result.
*
* @param array $data The data to create the automated report result with.
*
* @return AutomatedReportResult The newly created automated report result.
*/
public function createResult(array $data): AutomatedReportResult
{
return AutomatedReportResult::create($data);
}
/**
* Find an automated report result by UUID.
*
* @param string $uuid The UUID to find the automated report result with.
*
* @return AutomatedReportResult|null The automated report result if found, otherwise null.
*/
public function findResultByUuid(string $uuid): ?AutomatedReportResult
{
return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();
}
public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('uuid', AutomatedReportResult::toOptimized($uuid))
->whereHas('report', static function ($query) use ($user): void {
$query->where('team_id', $user->getTeamId())
->where('created_by', $user->getId());
})
->first();
}
public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('parent_id', $result->getId())
->where('media_type', $type)
->first();
}
public function getGeneratedNotSentResults(): Collection
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNull('sent_at')
->where('status', AutomatedReportResult::STATUS_GENERATED)
->whereHas('report')
->with('report')
->get();
}
public function getPaginatedUserReports(
User $user,
ReportSort $sort,
ReportSortDirection $sortDirection,
int $resultsPerPage,
int $page,
?Carbon $fromDate,
?Carbon $toDate,
array $teamIds,
array $reportTypes,
?string $name,
): LengthAwarePaginator {
$query = AutomatedReportResult::query()
->whereNotNull('automated_report_results.generated_at')
->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')
->where('automated_reports.team_id', $user->getTeamId())
->whereJsonContains('automated_reports.recipients->users', $user->getId())
->orderByRaw("$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}")
->select('automated_report_results.*')
->with('report.team');
if ($fromDate !== null && $toDate !== null) {
$query->whereBetween('generated_at', [$fromDate, $toDate]);
}
if (! empty($teamIds)) {
$query->where(function ($q) use ($teamIds) {
foreach ($teamIds as $id) {
$q->orWhereJsonContains('automated_reports.groups', $id);
}
});
}
if (! empty($reportTypes)) {
$query->whereIn('automated_reports.type', $reportTypes);
}
if (! empty($name)) {
$query->whereLike('name', "%$name%");
}
return $query->paginate($resultsPerPage, ['*'], 'page', $page);
}
public function countUserReports(User $user): int
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNotNull('sent_at')
->whereHas('report', function ($q) use ($user) {
$q->where('team_id', $user->getTeamId())
->whereJsonContains('recipients->users', $user->getId());
})
->count();
}
/**
* Get report IDs for a specific team
*
* @param Team $team
*
* @return \Illuminate\Support\Collection
*/
public function getReportIdsByTeam(Team $team): \Illuminate\Support\Collection
{
return AutomatedReport::where('team_id', $team->getId())->pluck('id');
}
/**
* Get all reports for a specific team
*
* @param Team $team
*
* @return Collection
*/
public function getReportsByTeam(Team $team): Collection
{
return AutomatedReport::where('team_id', $team->getId())->get();
}
/**
* Get all report results for a specific report
*
* @param AutomatedReport $report
*
* @return Collection
*/
public function getResultsByReport(AutomatedReport $report): Collection
{
return $this->getResultsByReportQuery($report)->get();
}
public function getResultsByReportQuery(AutomatedReport $report): Builder
{
return AutomatedReportResult::where('report_id', $report->getId());
}
public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder
{
$reportIds = $this->getReportIdsByTeam($team);
return AutomatedReportResult::query()->whereIn('report_id', $reportIds)
->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);
}
/**
* @param int|null $teamId Optional team ID to filter results
*
* @return \Illuminate\Support\Collection<int, int> Collection of team IDs
*/
public function getTeamIdsWithReportsResults(?int $teamId = null): \Illuminate\Support\Collection
{
$query = DB::table('automated_reports')
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->select('teams.id')
->distinct();
if ($teamId !== null) {
$query->where('teams.id', $teamId);
}
return $query->pluck('teams.id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
|
11157
|
221
|
14
|
2026-04-14T09:16:40.454196+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158200454_m2.jpg...
|
PhpStorm
|
faVsco.js – AskJiminnyReportActivityService.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Kiosk\AutomatedReports;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityActualDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityUpdatedDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\DealInsights\ClosingPeriodFilter;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\User;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
class AskJiminnyReportActivityService
{
private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;
private const array DATE_FILTER_KEYS = [
ActivityActualDate::PARAM_START_DATE,
ActivityActualDate::PARAM_END_DATE,
ActivityUpdatedDate::PARAM_UPDATED_FROM,
ActivityUpdatedDate::PARAM_UPDATED_TO,
ClosingPeriodFilter::KEY_START_DATE,
ClosingPeriodFilter::KEY_END_DATE,
];
public function __construct(
private readonly ActivitySearch $activitySearch,
private readonly ElasticActivityRepository $elasticRepository,
private readonly LoggerInterface $logger,
) {
}
/**
* Fetch activity IDs for a saved search, passing its filters as-is to Criteria.
* Date filters stored on the saved search are excluded; if no other filters exist,
* no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.
*
* @return string[] Activity IDs
*/
public function getActivityIdsForSavedSearch(
Search $savedSearch,
User $user,
): array {
$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);
$criteria = Criteria::createFromRequest(
array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),
$user->getTimezone()
);
$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);
$activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);
$this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [
'saved_search_id' => $savedSearch->getId(),
'user_id' => $user->getId(),
'activity_count' => count($activityIds),
]);
return $activityIds;
}
private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array
{
$params = [];
$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);
foreach ($savedSearch->getFilters() as $filter) {
$key = $filter->getFilterProperty();
$value = $filter->getFilterValue();
if (in_array($key, self::DATE_FILTER_KEYS, true)) {
continue;
}
if (isset($params[$key])) {
$params[$key][] = $value;
} elseif (in_array($key, $arrayFilterKeys, true)) {
$params[$key] = [$value];
} else {
$params[$key] = $value;
}
}
return $params;
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Repositories;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSort;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSortDirection;
class AutomatedReportsRepository
{
/**
* Create a new automated report
*
* @param array $data
*
* @return AutomatedReport
*/
public function create(array $data): AutomatedReport
{
return AutomatedReport::create($data);
}
/**
* Find an automated report by UUID
*
* @param string $uuid
*
* @return AutomatedReport|null
*/
public function findByUuid(string $uuid): ?AutomatedReport
{
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();
}
public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport
{
if (is_numeric($idOrUuid)) {
return AutomatedReport::find((int) $idOrUuid);
}
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();
}
/**
* Retrieve all standard (non-Ask Jiminny) automated reports.
*
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAllStandardReports(
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->get();
}
/**
* Retrieve all Ask Jiminny reports created by the given user.
*
* @param User $user The user whose reports to retrieve.
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAskJiminnyReportsByUser(
User $user,
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->where('created_by', $user->getId())
->get();
}
private function buildSortedQuery(string $sortColumn, string $sortDirection): \Illuminate\Database\Eloquent\Builder
{
$allowedColumns = ['created_by', 'created_at'];
if (! in_array($sortColumn, $allowedColumns)) {
$sortColumn = 'created_at';
}
$sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';
$query = AutomatedReport::query()->with(['creator', 'team']);
if ($sortColumn === 'created_by') {
$query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')
->orderByRaw("users.name COLLATE utf8mb4_unicode_ci {$sortDirection}")
->select('automated_reports.*');
} else {
$query->orderBy($sortColumn, $sortDirection);
}
return $query;
}
/**
* Get all active and enabled reports with active teams for the specified frequency.
*
* @param string $frequency
*
* @return Collection<AutomatedReport>
*/
public function getActiveReportsByFrequency(string $frequency): Collection
{
return AutomatedReport::where('automated_reports.status', true)
->where('automated_reports.frequency', $frequency)
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->where('teams.status', Team::STATUS_ACTIVE)
->where(function ($query) {
$query->whereNull('automated_reports.expires_at')
->orWhere('automated_reports.expires_at', '>=', now()->toDateString());
})
->select('automated_reports.*')
->get();
}
/**
* Update an automated report
*
* @param AutomatedReport $report
* @param array $data
*
* @return AutomatedReport
*/
public function update(AutomatedReport $report, array $data): AutomatedReport
{
$report->update($data);
return $report;
}
/**
* Create a new automated report result.
*
* @param array $data The data to create the automated report result with.
*
* @return AutomatedReportResult The newly created automated report result.
*/
public function createResult(array $data): AutomatedReportResult
{
return AutomatedReportResult::create($data);
}
/**
* Find an automated report result by UUID.
*
* @param string $uuid The UUID to find the automated report result with.
*
* @return AutomatedReportResult|null The automated report result if found, otherwise null.
*/
public function findResultByUuid(string $uuid): ?AutomatedReportResult
{
return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();
}
public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('uuid', AutomatedReportResult::toOptimized($uuid))
->whereHas('report', static function ($query) use ($user): void {
$query->where('team_id', $user->getTeamId())
->where('created_by', $user->getId());
})
->first();
}
public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('parent_id', $result->getId())
->where('media_type', $type)
->first();
}
public function getGeneratedNotSentResults(): Collection
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNull('sent_at')
->where('status', AutomatedReportResult::STATUS_GENERATED)
->whereHas('report')
->with('report')
->get();
}
public function getPaginatedUserReports(
User $user,
ReportSort $sort,
ReportSortDirection $sortDirection,
int $resultsPerPage,
int $page,
?Carbon $fromDate,
?Carbon $toDate,
array $teamIds,
array $reportTypes,
?string $name,
): LengthAwarePaginator {
$query = AutomatedReportResult::query()
->whereNotNull('automated_report_results.generated_at')
->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')
->where('automated_reports.team_id', $user->getTeamId())
->whereJsonContains('automated_reports.recipients->users', $user->getId())
->orderByRaw("$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}")
->select('automated_report_results.*')
->with('report.team');
if ($fromDate !== null && $toDate !== null) {
$query->whereBetween('generated_at', [$fromDate, $toDate]);
}
if (! empty($teamIds)) {
$query->where(function ($q) use ($teamIds) {
foreach ($teamIds as $id) {
$q->orWhereJsonContains('automated_reports.groups', $id);
}
});
}
if (! empty($reportTypes)) {
$query->whereIn('automated_reports.type', $reportTypes);
}
if (! empty($name)) {
$query->whereLike('name', "%$name%");
}
return $query->paginate($resultsPerPage, ['*'], 'page', $page);
}
public function countUserReports(User $user): int
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNotNull('sent_at')
->whereHas('report', function ($q) use ($user) {
$q->where('team_id', $user->getTeamId())
->whereJsonContains('recipients->users', $user->getId());
})
->count();
}
/**
* Get report IDs for a specific team
*
* @param Team $team
*
* @return \Illuminate\Support\Collection
*/
public function getReportIdsByTeam(Team $team): \Illuminate\Support\Collection
{
return AutomatedReport::where('team_id', $team->getId())->pluck('id');
}
/**
* Get all reports for a specific team
*
* @param Team $team
*
* @return Collection
*/
public function getReportsByTeam(Team $team): Collection
{
return AutomatedReport::where('team_id', $team->getId())->get();
}
/**
* Get all report results for a specific report
*
* @param AutomatedReport $report
*
* @return Collection
*/
public function getResultsByReport(AutomatedReport $report): Collection
{
return $this->getResultsByReportQuery($report)->get();
}
public function getResultsByReportQuery(AutomatedReport $report): Builder
{
return AutomatedReportResult::where('report_id', $report->getId());
}
public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder
{
$reportIds = $this->getReportIdsByTeam($team);
return AutomatedReportResult::query()->whereIn('report_id', $reportIds)
->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);
}
/**
* @param int|null $teamId Optional team ID to filter results
*
* @return \Illuminate\Support\Collection<int, int> Collection of team IDs
*/
public function getTeamIdsWithReportsResults(?int $teamId = null): \Illuminate\Support\Collection
{
$query = DB::table('automated_reports')
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->select('teams.id')
->distinct();
if ($teamId !== null) {
$query->where('teams.id', $teamId);
}
return $query->pluck('teams.id');
}
}
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.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","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.7589844,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceT…Defaults","depth":6,"bounds":{"left":0.7769531,"top":0.017361112,"width":0.12382813,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.009375,"height":0.0},"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.00859375,"height":0.0},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.00859375,"height":0.0},"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.23320313,"top":1.0,"width":0.008203125,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Kiosk\\AutomatedReports;\n\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityActualDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityUpdatedDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealInsights\\ClosingPeriodFilter;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\n\nclass AskJiminnyReportActivityService\n{\n private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;\n\n private const array DATE_FILTER_KEYS = [\n ActivityActualDate::PARAM_START_DATE,\n ActivityActualDate::PARAM_END_DATE,\n ActivityUpdatedDate::PARAM_UPDATED_FROM,\n ActivityUpdatedDate::PARAM_UPDATED_TO,\n ClosingPeriodFilter::KEY_START_DATE,\n ClosingPeriodFilter::KEY_END_DATE,\n ];\n\n public function __construct(\n private readonly ActivitySearch $activitySearch,\n private readonly ElasticActivityRepository $elasticRepository,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n /**\n * Fetch activity IDs for a saved search, passing its filters as-is to Criteria.\n * Date filters stored on the saved search are excluded; if no other filters exist,\n * no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.\n *\n * @return string[] Activity IDs\n */\n public function getActivityIdsForSavedSearch(\n Search $savedSearch,\n User $user,\n ): array {\n $requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);\n\n $criteria = Criteria::createFromRequest(\n array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);\n\n $activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);\n\n $this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [\n 'saved_search_id' => $savedSearch->getId(),\n 'user_id' => $user->getId(),\n 'activity_count' => count($activityIds),\n ]);\n\n return $activityIds;\n }\n\n private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array\n {\n $params = [];\n $arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);\n\n foreach ($savedSearch->getFilters() as $filter) {\n $key = $filter->getFilterProperty();\n $value = $filter->getFilterValue();\n\n if (in_array($key, self::DATE_FILTER_KEYS, true)) {\n continue;\n }\n\n if (isset($params[$key])) {\n $params[$key][] = $value;\n } elseif (in_array($key, $arrayFilterKeys, true)) {\n $params[$key] = [$value];\n } else {\n $params[$key] = $value;\n }\n }\n\n return $params;\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Kiosk\\AutomatedReports;\n\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityActualDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityUpdatedDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealInsights\\ClosingPeriodFilter;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\n\nclass AskJiminnyReportActivityService\n{\n private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;\n\n private const array DATE_FILTER_KEYS = [\n ActivityActualDate::PARAM_START_DATE,\n ActivityActualDate::PARAM_END_DATE,\n ActivityUpdatedDate::PARAM_UPDATED_FROM,\n ActivityUpdatedDate::PARAM_UPDATED_TO,\n ClosingPeriodFilter::KEY_START_DATE,\n ClosingPeriodFilter::KEY_END_DATE,\n ];\n\n public function __construct(\n private readonly ActivitySearch $activitySearch,\n private readonly ElasticActivityRepository $elasticRepository,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n /**\n * Fetch activity IDs for a saved search, passing its filters as-is to Criteria.\n * Date filters stored on the saved search are excluded; if no other filters exist,\n * no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.\n *\n * @return string[] Activity IDs\n */\n public function getActivityIdsForSavedSearch(\n Search $savedSearch,\n User $user,\n ): array {\n $requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);\n\n $criteria = Criteria::createFromRequest(\n array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);\n\n $activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);\n\n $this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [\n 'saved_search_id' => $savedSearch->getId(),\n 'user_id' => $user->getId(),\n 'activity_count' => count($activityIds),\n ]);\n\n return $activityIds;\n }\n\n private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array\n {\n $params = [];\n $arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);\n\n foreach ($savedSearch->getFilters() as $filter) {\n $key = $filter->getFilterProperty();\n $value = $filter->getFilterValue();\n\n if (in_array($key, self::DATE_FILTER_KEYS, true)) {\n continue;\n }\n\n if (isset($params[$key])) {\n $params[$key][] = $value;\n } elseif (in_array($key, $arrayFilterKeys, true)) {\n $params[$key] = [$value];\n } else {\n $params[$key] = $value;\n }\n }\n\n return $params;\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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"15","depth":4,"bounds":{"left":0.2589844,"top":0.28125,"width":0.011328125,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.27265626,"top":0.28125,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.28398436,"top":0.27986112,"width":0.00859375,"height":0.015972223},"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.29257813,"top":0.27986112,"width":0.008203125,"height":0.015972223},"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\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\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,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.0140625,"top":0.041666668,"width":0.028515626,"height":0.021527778},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
8563436494813991353
|
-5967358188006330764
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Kiosk\AutomatedReports;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityActualDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityUpdatedDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\DealInsights\ClosingPeriodFilter;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\User;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
class AskJiminnyReportActivityService
{
private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;
private const array DATE_FILTER_KEYS = [
ActivityActualDate::PARAM_START_DATE,
ActivityActualDate::PARAM_END_DATE,
ActivityUpdatedDate::PARAM_UPDATED_FROM,
ActivityUpdatedDate::PARAM_UPDATED_TO,
ClosingPeriodFilter::KEY_START_DATE,
ClosingPeriodFilter::KEY_END_DATE,
];
public function __construct(
private readonly ActivitySearch $activitySearch,
private readonly ElasticActivityRepository $elasticRepository,
private readonly LoggerInterface $logger,
) {
}
/**
* Fetch activity IDs for a saved search, passing its filters as-is to Criteria.
* Date filters stored on the saved search are excluded; if no other filters exist,
* no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.
*
* @return string[] Activity IDs
*/
public function getActivityIdsForSavedSearch(
Search $savedSearch,
User $user,
): array {
$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);
$criteria = Criteria::createFromRequest(
array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),
$user->getTimezone()
);
$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);
$activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);
$this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [
'saved_search_id' => $savedSearch->getId(),
'user_id' => $user->getId(),
'activity_count' => count($activityIds),
]);
return $activityIds;
}
private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array
{
$params = [];
$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);
foreach ($savedSearch->getFilters() as $filter) {
$key = $filter->getFilterProperty();
$value = $filter->getFilterValue();
if (in_array($key, self::DATE_FILTER_KEYS, true)) {
continue;
}
if (isset($params[$key])) {
$params[$key][] = $value;
} elseif (in_array($key, $arrayFilterKeys, true)) {
$params[$key] = [$value];
} else {
$params[$key] = $value;
}
}
return $params;
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Repositories;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSort;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSortDirection;
class AutomatedReportsRepository
{
/**
* Create a new automated report
*
* @param array $data
*
* @return AutomatedReport
*/
public function create(array $data): AutomatedReport
{
return AutomatedReport::create($data);
}
/**
* Find an automated report by UUID
*
* @param string $uuid
*
* @return AutomatedReport|null
*/
public function findByUuid(string $uuid): ?AutomatedReport
{
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();
}
public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport
{
if (is_numeric($idOrUuid)) {
return AutomatedReport::find((int) $idOrUuid);
}
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();
}
/**
* Retrieve all standard (non-Ask Jiminny) automated reports.
*
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAllStandardReports(
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->get();
}
/**
* Retrieve all Ask Jiminny reports created by the given user.
*
* @param User $user The user whose reports to retrieve.
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAskJiminnyReportsByUser(
User $user,
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->where('created_by', $user->getId())
->get();
}
private function buildSortedQuery(string $sortColumn, string $sortDirection): \Illuminate\Database\Eloquent\Builder
{
$allowedColumns = ['created_by', 'created_at'];
if (! in_array($sortColumn, $allowedColumns)) {
$sortColumn = 'created_at';
}
$sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';
$query = AutomatedReport::query()->with(['creator', 'team']);
if ($sortColumn === 'created_by') {
$query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')
->orderByRaw("users.name COLLATE utf8mb4_unicode_ci {$sortDirection}")
->select('automated_reports.*');
} else {
$query->orderBy($sortColumn, $sortDirection);
}
return $query;
}
/**
* Get all active and enabled reports with active teams for the specified frequency.
*
* @param string $frequency
*
* @return Collection<AutomatedReport>
*/
public function getActiveReportsByFrequency(string $frequency): Collection
{
return AutomatedReport::where('automated_reports.status', true)
->where('automated_reports.frequency', $frequency)
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->where('teams.status', Team::STATUS_ACTIVE)
->where(function ($query) {
$query->whereNull('automated_reports.expires_at')
->orWhere('automated_reports.expires_at', '>=', now()->toDateString());
})
->select('automated_reports.*')
->get();
}
/**
* Update an automated report
*
* @param AutomatedReport $report
* @param array $data
*
* @return AutomatedReport
*/
public function update(AutomatedReport $report, array $data): AutomatedReport
{
$report->update($data);
return $report;
}
/**
* Create a new automated report result.
*
* @param array $data The data to create the automated report result with.
*
* @return AutomatedReportResult The newly created automated report result.
*/
public function createResult(array $data): AutomatedReportResult
{
return AutomatedReportResult::create($data);
}
/**
* Find an automated report result by UUID.
*
* @param string $uuid The UUID to find the automated report result with.
*
* @return AutomatedReportResult|null The automated report result if found, otherwise null.
*/
public function findResultByUuid(string $uuid): ?AutomatedReportResult
{
return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();
}
public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('uuid', AutomatedReportResult::toOptimized($uuid))
->whereHas('report', static function ($query) use ($user): void {
$query->where('team_id', $user->getTeamId())
->where('created_by', $user->getId());
})
->first();
}
public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('parent_id', $result->getId())
->where('media_type', $type)
->first();
}
public function getGeneratedNotSentResults(): Collection
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNull('sent_at')
->where('status', AutomatedReportResult::STATUS_GENERATED)
->whereHas('report')
->with('report')
->get();
}
public function getPaginatedUserReports(
User $user,
ReportSort $sort,
ReportSortDirection $sortDirection,
int $resultsPerPage,
int $page,
?Carbon $fromDate,
?Carbon $toDate,
array $teamIds,
array $reportTypes,
?string $name,
): LengthAwarePaginator {
$query = AutomatedReportResult::query()
->whereNotNull('automated_report_results.generated_at')
->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')
->where('automated_reports.team_id', $user->getTeamId())
->whereJsonContains('automated_reports.recipients->users', $user->getId())
->orderByRaw("$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}")
->select('automated_report_results.*')
->with('report.team');
if ($fromDate !== null && $toDate !== null) {
$query->whereBetween('generated_at', [$fromDate, $toDate]);
}
if (! empty($teamIds)) {
$query->where(function ($q) use ($teamIds) {
foreach ($teamIds as $id) {
$q->orWhereJsonContains('automated_reports.groups', $id);
}
});
}
if (! empty($reportTypes)) {
$query->whereIn('automated_reports.type', $reportTypes);
}
if (! empty($name)) {
$query->whereLike('name', "%$name%");
}
return $query->paginate($resultsPerPage, ['*'], 'page', $page);
}
public function countUserReports(User $user): int
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNotNull('sent_at')
->whereHas('report', function ($q) use ($user) {
$q->where('team_id', $user->getTeamId())
->whereJsonContains('recipients->users', $user->getId());
})
->count();
}
/**
* Get report IDs for a specific team
*
* @param Team $team
*
* @return \Illuminate\Support\Collection
*/
public function getReportIdsByTeam(Team $team): \Illuminate\Support\Collection
{
return AutomatedReport::where('team_id', $team->getId())->pluck('id');
}
/**
* Get all reports for a specific team
*
* @param Team $team
*
* @return Collection
*/
public function getReportsByTeam(Team $team): Collection
{
return AutomatedReport::where('team_id', $team->getId())->get();
}
/**
* Get all report results for a specific report
*
* @param AutomatedReport $report
*
* @return Collection
*/
public function getResultsByReport(AutomatedReport $report): Collection
{
return $this->getResultsByReportQuery($report)->get();
}
public function getResultsByReportQuery(AutomatedReport $report): Builder
{
return AutomatedReportResult::where('report_id', $report->getId());
}
public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder
{
$reportIds = $this->getReportIdsByTeam($team);
return AutomatedReportResult::query()->whereIn('report_id', $reportIds)
->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);
}
/**
* @param int|null $teamId Optional team ID to filter results
*
* @return \Illuminate\Support\Collection<int, int> Collection of team IDs
*/
public function getTeamIdsWithReportsResults(?int $teamId = null): \Illuminate\Support\Collection
{
$query = DB::table('automated_reports')
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->select('teams.id')
->distinct();
if ($teamId !== null) {
$query->where('teams.id', $teamId);
}
return $query->pluck('teams.id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
11155
|
|
11159
|
221
|
15
|
2026-04-14T09:17:10.786821+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158230786_m2.jpg...
|
PhpStorm
|
faVsco.js – AskJiminnyReportActivityService.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Kiosk\AutomatedReports;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityActualDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityUpdatedDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\DealInsights\ClosingPeriodFilter;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\User;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
class AskJiminnyReportActivityService
{
private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;
private const array DATE_FILTER_KEYS = [
ActivityActualDate::PARAM_START_DATE,
ActivityActualDate::PARAM_END_DATE,
ActivityUpdatedDate::PARAM_UPDATED_FROM,
ActivityUpdatedDate::PARAM_UPDATED_TO,
ClosingPeriodFilter::KEY_START_DATE,
ClosingPeriodFilter::KEY_END_DATE,
];
public function __construct(
private readonly ActivitySearch $activitySearch,
private readonly ElasticActivityRepository $elasticRepository,
private readonly LoggerInterface $logger,
) {
}
/**
* Fetch activity IDs for a saved search, passing its filters as-is to Criteria.
* Date filters stored on the saved search are excluded; if no other filters exist,
* no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.
*
* @return string[] Activity IDs
*/
public function getActivityIdsForSavedSearch(
Search $savedSearch,
User $user,
): array {
$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);
$criteria = Criteria::createFromRequest(
array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),
$user->getTimezone()
);
$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);
$activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);
$this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [
'saved_search_id' => $savedSearch->getId(),
'user_id' => $user->getId(),
'activity_count' => count($activityIds),
]);
return $activityIds;
}
private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array
{
$params = [];
$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);
foreach ($savedSearch->getFilters() as $filter) {
$key = $filter->getFilterProperty();
$value = $filter->getFilterValue();
if (in_array($key, self::DATE_FILTER_KEYS, true)) {
continue;
}
if (isset($params[$key])) {
$params[$key][] = $value;
} elseif (in_array($key, $arrayFilterKeys, true)) {
$params[$key] = [$value];
} else {
$params[$key] = $value;
}
}
return $params;
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Repositories;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSort;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSortDirection;
class AutomatedReportsRepository
{
/**
* Create a new automated report
*
* @param array $data
*
* @return AutomatedReport
*/
public function create(array $data): AutomatedReport
{
return AutomatedReport::create($data);
}
/**
* Find an automated report by UUID
*
* @param string $uuid
*
* @return AutomatedReport|null
*/
public function findByUuid(string $uuid): ?AutomatedReport
{
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();
}
public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport
{
if (is_numeric($idOrUuid)) {
return AutomatedReport::find((int) $idOrUuid);
}
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();
}
/**
* Retrieve all standard (non-Ask Jiminny) automated reports.
*
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAllStandardReports(
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->get();
}
/**
* Retrieve all Ask Jiminny reports created by the given user.
*
* @param User $user The user whose reports to retrieve.
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAskJiminnyReportsByUser(
User $user,
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->where('created_by', $user->getId())
->get();
}
private function buildSortedQuery(string $sortColumn, string $sortDirection): \Illuminate\Database\Eloquent\Builder
{
$allowedColumns = ['created_by', 'created_at'];
if (! in_array($sortColumn, $allowedColumns)) {
$sortColumn = 'created_at';
}
$sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';
$query = AutomatedReport::query()->with(['creator', 'team']);
if ($sortColumn === 'created_by') {
$query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')
->orderByRaw("users.name COLLATE utf8mb4_unicode_ci {$sortDirection}")
->select('automated_reports.*');
} else {
$query->orderBy($sortColumn, $sortDirection);
}
return $query;
}
/**
* Get all active and enabled reports with active teams for the specified frequency.
*
* @param string $frequency
*
* @return Collection<AutomatedReport>
*/
public function getActiveReportsByFrequency(string $frequency): Collection
{
return AutomatedReport::where('automated_reports.status', true)
->where('automated_reports.frequency', $frequency)
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->where('teams.status', Team::STATUS_ACTIVE)
->where(function ($query) {
$query->whereNull('automated_reports.expires_at')
->orWhere('automated_reports.expires_at', '>=', now()->toDateString());
})
->select('automated_reports.*')
->get();
}
/**
* Update an automated report
*
* @param AutomatedReport $report
* @param array $data
*
* @return AutomatedReport
*/
public function update(AutomatedReport $report, array $data): AutomatedReport
{
$report->update($data);
return $report;
}
/**
* Create a new automated report result.
*
* @param array $data The data to create the automated report result with.
*
* @return AutomatedReportResult The newly created automated report result.
*/
public function createResult(array $data): AutomatedReportResult
{
return AutomatedReportResult::create($data);
}
/**
* Find an automated report result by UUID.
*
* @param string $uuid The UUID to find the automated report result with.
*
* @return AutomatedReportResult|null The automated report result if found, otherwise null.
*/
public function findResultByUuid(string $uuid): ?AutomatedReportResult
{
return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();
}
public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('uuid', AutomatedReportResult::toOptimized($uuid))
->whereHas('report', static function ($query) use ($user): void {
$query->where('team_id', $user->getTeamId())
->where('created_by', $user->getId());
})
->first();
}
public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('parent_id', $result->getId())
->where('media_type', $type)
->first();
}
public function getGeneratedNotSentResults(): Collection
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNull('sent_at')
->where('status', AutomatedReportResult::STATUS_GENERATED)
->whereHas('report')
->with('report')
->get();
}
public function getPaginatedUserReports(
User $user,
ReportSort $sort,
ReportSortDirection $sortDirection,
int $resultsPerPage,
int $page,
?Carbon $fromDate,
?Carbon $toDate,
array $teamIds,
array $reportTypes,
?string $name,
): LengthAwarePaginator {
$query = AutomatedReportResult::query()
->whereNotNull('automated_report_results.generated_at')
->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')
->where('automated_reports.team_id', $user->getTeamId())
->whereJsonContains('automated_reports.recipients->users', $user->getId())
->orderByRaw("$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}")
->select('automated_report_results.*')
->with('report.team');
if ($fromDate !== null && $toDate !== null) {
$query->whereBetween('generated_at', [$fromDate, $toDate]);
}
if (! empty($teamIds)) {
$query->where(function ($q) use ($teamIds) {
foreach ($teamIds as $id) {
$q->orWhereJsonContains('automated_reports.groups', $id);
}
});
}
if (! empty($reportTypes)) {
$query->whereIn('automated_reports.type', $reportTypes);
}
if (! empty($name)) {
$query->whereLike('name', "%$name%");
}
return $query->paginate($resultsPerPage, ['*'], 'page', $page);
}
public function countUserReports(User $user): int
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNotNull('sent_at')
->whereHas('report', function ($q) use ($user) {
$q->where('team_id', $user->getTeamId())
->whereJsonContains('recipients->users', $user->getId());
})
->count();
}
/**
* Get report IDs for a specific team
*
* @param Team $team
*
* @return \Illuminate\Support\Collection
*/
public function getReportIdsByTeam(Team $team): \Illuminate\Support\Collection
{
return AutomatedReport::where('team_id', $team->getId())->pluck('id');
}
/**
* Get all reports for a specific team
*
* @param Team $team
*
* @return Collection
*/
public function getReportsByTeam(Team $team): Collection
{
return AutomatedReport::where('team_id', $team->getId())->get();
}
/**
* Get all report results for a specific report
*
* @param AutomatedReport $report
*
* @return Collection
*/
public function getResultsByReport(AutomatedReport $report): Collection
{
return $this->getResultsByReportQuery($report)->get();
}
public function getResultsByReportQuery(AutomatedReport $report): Builder
{
return AutomatedReportResult::where('report_id', $report->getId());
}
public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder
{
$reportIds = $this->getReportIdsByTeam($team);
return AutomatedReportResult::query()->whereIn('report_id', $reportIds)
->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);
}
/**
* @param int|null $teamId Optional team ID to filter results
*
* @return \Illuminate\Support\Collection<int, int> Collection of team IDs
*/
public function getTeamIdsWithReportsResults(?int $teamId = null): \Illuminate\Support\Collection
{
$query = DB::table('automated_reports')
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->select('teams.id')
->distinct();
if ($teamId !== null) {
$query->where('teams.id', $teamId);
}
return $query->pluck('teams.id');
}
}
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.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","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.7589844,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceT…Defaults","depth":6,"bounds":{"left":0.7769531,"top":0.017361112,"width":0.12382813,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.009375,"height":0.0},"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.00859375,"height":0.0},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.00859375,"height":0.0},"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.23320313,"top":1.0,"width":0.008203125,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Kiosk\\AutomatedReports;\n\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityActualDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityUpdatedDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealInsights\\ClosingPeriodFilter;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\n\nclass AskJiminnyReportActivityService\n{\n private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;\n\n private const array DATE_FILTER_KEYS = [\n ActivityActualDate::PARAM_START_DATE,\n ActivityActualDate::PARAM_END_DATE,\n ActivityUpdatedDate::PARAM_UPDATED_FROM,\n ActivityUpdatedDate::PARAM_UPDATED_TO,\n ClosingPeriodFilter::KEY_START_DATE,\n ClosingPeriodFilter::KEY_END_DATE,\n ];\n\n public function __construct(\n private readonly ActivitySearch $activitySearch,\n private readonly ElasticActivityRepository $elasticRepository,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n /**\n * Fetch activity IDs for a saved search, passing its filters as-is to Criteria.\n * Date filters stored on the saved search are excluded; if no other filters exist,\n * no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.\n *\n * @return string[] Activity IDs\n */\n public function getActivityIdsForSavedSearch(\n Search $savedSearch,\n User $user,\n ): array {\n $requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);\n\n $criteria = Criteria::createFromRequest(\n array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);\n\n $activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);\n\n $this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [\n 'saved_search_id' => $savedSearch->getId(),\n 'user_id' => $user->getId(),\n 'activity_count' => count($activityIds),\n ]);\n\n return $activityIds;\n }\n\n private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array\n {\n $params = [];\n $arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);\n\n foreach ($savedSearch->getFilters() as $filter) {\n $key = $filter->getFilterProperty();\n $value = $filter->getFilterValue();\n\n if (in_array($key, self::DATE_FILTER_KEYS, true)) {\n continue;\n }\n\n if (isset($params[$key])) {\n $params[$key][] = $value;\n } elseif (in_array($key, $arrayFilterKeys, true)) {\n $params[$key] = [$value];\n } else {\n $params[$key] = $value;\n }\n }\n\n return $params;\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Kiosk\\AutomatedReports;\n\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityActualDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityUpdatedDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealInsights\\ClosingPeriodFilter;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\n\nclass AskJiminnyReportActivityService\n{\n private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;\n\n private const array DATE_FILTER_KEYS = [\n ActivityActualDate::PARAM_START_DATE,\n ActivityActualDate::PARAM_END_DATE,\n ActivityUpdatedDate::PARAM_UPDATED_FROM,\n ActivityUpdatedDate::PARAM_UPDATED_TO,\n ClosingPeriodFilter::KEY_START_DATE,\n ClosingPeriodFilter::KEY_END_DATE,\n ];\n\n public function __construct(\n private readonly ActivitySearch $activitySearch,\n private readonly ElasticActivityRepository $elasticRepository,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n /**\n * Fetch activity IDs for a saved search, passing its filters as-is to Criteria.\n * Date filters stored on the saved search are excluded; if no other filters exist,\n * no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.\n *\n * @return string[] Activity IDs\n */\n public function getActivityIdsForSavedSearch(\n Search $savedSearch,\n User $user,\n ): array {\n $requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);\n\n $criteria = Criteria::createFromRequest(\n array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);\n\n $activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);\n\n $this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [\n 'saved_search_id' => $savedSearch->getId(),\n 'user_id' => $user->getId(),\n 'activity_count' => count($activityIds),\n ]);\n\n return $activityIds;\n }\n\n private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array\n {\n $params = [];\n $arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);\n\n foreach ($savedSearch->getFilters() as $filter) {\n $key = $filter->getFilterProperty();\n $value = $filter->getFilterValue();\n\n if (in_array($key, self::DATE_FILTER_KEYS, true)) {\n continue;\n }\n\n if (isset($params[$key])) {\n $params[$key][] = $value;\n } elseif (in_array($key, $arrayFilterKeys, true)) {\n $params[$key] = [$value];\n } else {\n $params[$key] = $value;\n }\n }\n\n return $params;\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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"15","depth":4,"bounds":{"left":0.2589844,"top":0.28125,"width":0.011328125,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.27265626,"top":0.28125,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.28398436,"top":0.27986112,"width":0.00859375,"height":0.015972223},"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.29257813,"top":0.27986112,"width":0.008203125,"height":0.015972223},"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\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\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,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.0140625,"top":0.041666668,"width":0.028515626,"height":0.021527778},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
8563436494813991353
|
-5967358188006330764
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Kiosk\AutomatedReports;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityActualDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityUpdatedDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\DealInsights\ClosingPeriodFilter;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\User;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
class AskJiminnyReportActivityService
{
private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;
private const array DATE_FILTER_KEYS = [
ActivityActualDate::PARAM_START_DATE,
ActivityActualDate::PARAM_END_DATE,
ActivityUpdatedDate::PARAM_UPDATED_FROM,
ActivityUpdatedDate::PARAM_UPDATED_TO,
ClosingPeriodFilter::KEY_START_DATE,
ClosingPeriodFilter::KEY_END_DATE,
];
public function __construct(
private readonly ActivitySearch $activitySearch,
private readonly ElasticActivityRepository $elasticRepository,
private readonly LoggerInterface $logger,
) {
}
/**
* Fetch activity IDs for a saved search, passing its filters as-is to Criteria.
* Date filters stored on the saved search are excluded; if no other filters exist,
* no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.
*
* @return string[] Activity IDs
*/
public function getActivityIdsForSavedSearch(
Search $savedSearch,
User $user,
): array {
$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);
$criteria = Criteria::createFromRequest(
array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),
$user->getTimezone()
);
$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);
$activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);
$this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [
'saved_search_id' => $savedSearch->getId(),
'user_id' => $user->getId(),
'activity_count' => count($activityIds),
]);
return $activityIds;
}
private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array
{
$params = [];
$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);
foreach ($savedSearch->getFilters() as $filter) {
$key = $filter->getFilterProperty();
$value = $filter->getFilterValue();
if (in_array($key, self::DATE_FILTER_KEYS, true)) {
continue;
}
if (isset($params[$key])) {
$params[$key][] = $value;
} elseif (in_array($key, $arrayFilterKeys, true)) {
$params[$key] = [$value];
} else {
$params[$key] = $value;
}
}
return $params;
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Repositories;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSort;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSortDirection;
class AutomatedReportsRepository
{
/**
* Create a new automated report
*
* @param array $data
*
* @return AutomatedReport
*/
public function create(array $data): AutomatedReport
{
return AutomatedReport::create($data);
}
/**
* Find an automated report by UUID
*
* @param string $uuid
*
* @return AutomatedReport|null
*/
public function findByUuid(string $uuid): ?AutomatedReport
{
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();
}
public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport
{
if (is_numeric($idOrUuid)) {
return AutomatedReport::find((int) $idOrUuid);
}
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();
}
/**
* Retrieve all standard (non-Ask Jiminny) automated reports.
*
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAllStandardReports(
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->get();
}
/**
* Retrieve all Ask Jiminny reports created by the given user.
*
* @param User $user The user whose reports to retrieve.
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAskJiminnyReportsByUser(
User $user,
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->where('created_by', $user->getId())
->get();
}
private function buildSortedQuery(string $sortColumn, string $sortDirection): \Illuminate\Database\Eloquent\Builder
{
$allowedColumns = ['created_by', 'created_at'];
if (! in_array($sortColumn, $allowedColumns)) {
$sortColumn = 'created_at';
}
$sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';
$query = AutomatedReport::query()->with(['creator', 'team']);
if ($sortColumn === 'created_by') {
$query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')
->orderByRaw("users.name COLLATE utf8mb4_unicode_ci {$sortDirection}")
->select('automated_reports.*');
} else {
$query->orderBy($sortColumn, $sortDirection);
}
return $query;
}
/**
* Get all active and enabled reports with active teams for the specified frequency.
*
* @param string $frequency
*
* @return Collection<AutomatedReport>
*/
public function getActiveReportsByFrequency(string $frequency): Collection
{
return AutomatedReport::where('automated_reports.status', true)
->where('automated_reports.frequency', $frequency)
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->where('teams.status', Team::STATUS_ACTIVE)
->where(function ($query) {
$query->whereNull('automated_reports.expires_at')
->orWhere('automated_reports.expires_at', '>=', now()->toDateString());
})
->select('automated_reports.*')
->get();
}
/**
* Update an automated report
*
* @param AutomatedReport $report
* @param array $data
*
* @return AutomatedReport
*/
public function update(AutomatedReport $report, array $data): AutomatedReport
{
$report->update($data);
return $report;
}
/**
* Create a new automated report result.
*
* @param array $data The data to create the automated report result with.
*
* @return AutomatedReportResult The newly created automated report result.
*/
public function createResult(array $data): AutomatedReportResult
{
return AutomatedReportResult::create($data);
}
/**
* Find an automated report result by UUID.
*
* @param string $uuid The UUID to find the automated report result with.
*
* @return AutomatedReportResult|null The automated report result if found, otherwise null.
*/
public function findResultByUuid(string $uuid): ?AutomatedReportResult
{
return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();
}
public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('uuid', AutomatedReportResult::toOptimized($uuid))
->whereHas('report', static function ($query) use ($user): void {
$query->where('team_id', $user->getTeamId())
->where('created_by', $user->getId());
})
->first();
}
public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('parent_id', $result->getId())
->where('media_type', $type)
->first();
}
public function getGeneratedNotSentResults(): Collection
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNull('sent_at')
->where('status', AutomatedReportResult::STATUS_GENERATED)
->whereHas('report')
->with('report')
->get();
}
public function getPaginatedUserReports(
User $user,
ReportSort $sort,
ReportSortDirection $sortDirection,
int $resultsPerPage,
int $page,
?Carbon $fromDate,
?Carbon $toDate,
array $teamIds,
array $reportTypes,
?string $name,
): LengthAwarePaginator {
$query = AutomatedReportResult::query()
->whereNotNull('automated_report_results.generated_at')
->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')
->where('automated_reports.team_id', $user->getTeamId())
->whereJsonContains('automated_reports.recipients->users', $user->getId())
->orderByRaw("$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}")
->select('automated_report_results.*')
->with('report.team');
if ($fromDate !== null && $toDate !== null) {
$query->whereBetween('generated_at', [$fromDate, $toDate]);
}
if (! empty($teamIds)) {
$query->where(function ($q) use ($teamIds) {
foreach ($teamIds as $id) {
$q->orWhereJsonContains('automated_reports.groups', $id);
}
});
}
if (! empty($reportTypes)) {
$query->whereIn('automated_reports.type', $reportTypes);
}
if (! empty($name)) {
$query->whereLike('name', "%$name%");
}
return $query->paginate($resultsPerPage, ['*'], 'page', $page);
}
public function countUserReports(User $user): int
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNotNull('sent_at')
->whereHas('report', function ($q) use ($user) {
$q->where('team_id', $user->getTeamId())
->whereJsonContains('recipients->users', $user->getId());
})
->count();
}
/**
* Get report IDs for a specific team
*
* @param Team $team
*
* @return \Illuminate\Support\Collection
*/
public function getReportIdsByTeam(Team $team): \Illuminate\Support\Collection
{
return AutomatedReport::where('team_id', $team->getId())->pluck('id');
}
/**
* Get all reports for a specific team
*
* @param Team $team
*
* @return Collection
*/
public function getReportsByTeam(Team $team): Collection
{
return AutomatedReport::where('team_id', $team->getId())->get();
}
/**
* Get all report results for a specific report
*
* @param AutomatedReport $report
*
* @return Collection
*/
public function getResultsByReport(AutomatedReport $report): Collection
{
return $this->getResultsByReportQuery($report)->get();
}
public function getResultsByReportQuery(AutomatedReport $report): Builder
{
return AutomatedReportResult::where('report_id', $report->getId());
}
public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder
{
$reportIds = $this->getReportIdsByTeam($team);
return AutomatedReportResult::query()->whereIn('report_id', $reportIds)
->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);
}
/**
* @param int|null $teamId Optional team ID to filter results
*
* @return \Illuminate\Support\Collection<int, int> Collection of team IDs
*/
public function getTeamIdsWithReportsResults(?int $teamId = null): \Illuminate\Support\Collection
{
$query = DB::table('automated_reports')
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->select('teams.id')
->distinct();
if ($teamId !== null) {
$query->where('teams.id', $teamId);
}
return $query->pluck('teams.id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
11155
|
|
11160
|
221
|
16
|
2026-04-14T09:17:11.332388+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158231332_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditFV faVsco.jsProjectvViewNavigateCo PhpStormFileEditFV faVsco.jsProjectvViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© DeviceRepository.php© ElasticActivityRepository.pl© EmailMessageRepository.p© GenericAiPromptRepositor:© GroupRepository.php(C) InboxEmailBatchRepositor)InboxRepository.php© InvitationRepository.php© JobRepository.php© LanguageRepository.php© MomentRepository.php© NotificationRepository.php© ParticipantRepository.php© ParticipantSpeechReposito© ParticipantStatsRepository© PlaybookCategoryRepositc© PlaybookRepository.php® PlaylistActivityRepository.fPlaylistRepository.phpPlaylistShareRepository.ph© QuestionRepository.php© RoleChangeEventRepositor© RoleRepository.php© SearchRepository.php© SnapshotRepository.php© SocialAccountRepository.p© StageRepository.php© SubscriptionSetRepository.TaskRepository.php© TeamAiContextRepository.TeamDomainsRepository.p©TeamInsightsRepository.pt©TeamRepository.php©ThemeRepository.php© TimezoneRepository.php© TopicRepository.php© TopicTriggerRepository.ph© TrackRepository.php© TranscriptionModelLocaleF© TranscriptionRepository.phC) TranscriptionSummarvRep© UserRepository.php© VocabularyRepository.pnp› D Rulesv D Services> [ Activity> C AjReports› D AvatarcalendarD ConferenceD Crm>MImport> MInternallv → Kioskv D AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsStTests passed: 1 (7 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console EUiconsole SlAGiNGASkJIminnykeportAcuivilyservice.ono xActiviysearch.php© Criteria.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php(e TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpOnDemandV2Controller.php© HistoryService.php© AskJiminnyReportActivityServiceTest.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityService1 usagepublic function __construct(private readonly ActivitySearch $activitySearch,private readonly ElasticActivityRepository $elasticRepository,private readonly LoggerInterface $logger,Df...3class Automacedkeportskepo ofA15 V4 ^ v 3959114115116117118119120/*** Retrieve all standard (non-Ask Liminny) an43* @param string $sortColumnThe column te 44* Oparam string $sortDirection The sort dire45* @return Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Liminny reports created 55* OodrdllusernusenThe User Who: 57*oparam scrine osorclocunnThe coLomn t958* Oparam string $sortDirection The sort dire59* @return Collection<AutomatedReport>*/—6214 usages63public function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J2 usagesprivate function buildSortedQuery(string $sor_68-71/*** Get all active and enabled reports with al73* @param string $frequency* dreturn cocLectron<Aucomacedкeрort»23 usagespublic function getActiveReportsByFrequency(§g0/*** Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,xno dueconstraint is applied - matching the behaviour of getContextForAskAnythingByFilte* @return string[] Activity IDs*/14 usaeespublic function getActivityIdsForSavedSearchCSearch $savedSearch,User $user,): array {$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);ocrlrerta = unlrerta.:credcerronkeqvestmargee €$requestParams,['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'array_merge ($requestParams,['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'$user->getTimezone()):$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);$activityIds = $this->elasticRepository->onDemandSearchIds0nly($user, $criteria, $filter$this->logger→>info('[AskviminnyReport] Fetched activity IDs for saved search', [saved_search_id => $savedSearch->getid),'user_id' => $user->getId(),'activity_count' => count($activityIds),1):return $activityIds;1 usageprivace tunccion bunLakequestrarams-romsearch(search esaveasearch, user suser: array$params = [];$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);foreach ($savedSearch->getFilters() as $filter) {$key = $filter->getFilterPropertyO);$valve = $filter->getFilterValve();if Cin_array(Skey,haystack: self::DATE_FILTER_KEYS,strict: true)){X Reject File 0* €, 0lablf Support Daily • in 2h 43 mAAskJiminnyReportActivityServiceT….Defaults100% C•Tue 14 Apr 12:17:11CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ...again. Why is there issue with that? Where is it ed to work with that. How is it used inCAskJ1minyReportActivityService. phpL44-66 should be sameed on savedSearch. THe ids in on demand and inLet me read the OnDemandV2Controller to understand how it builds criteria there:Poad OnDerwNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php:90-93:0 phpVO\Repository\0nDemandActivitySearch\Criteria::createFromRequest(array merge($request→>allo, ('limit' = $topCount, 'paqe' = 1]).suser->geclimezoneit passes srequest→>all() - wnich Includes sequence_number Trom the URL (e.g. sequence_number=4 Trom your staging URL). so when a user nas beenpaginating on the frontend, sequence_number is naturally non-zero.The full explanationyou didn't ask for themFilterActivityburaclonkandeisFirstRequest) in Criteriareturns true when sequenceNumber === 0 . When it's the "first request" these implicit defaults kick in automatically even ifOrganiserGroupInDefault on first requestman curation = minonly_recorded = 1User's own aroupEffectUrops u-secone acuivitlesRestricts to user's arourFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest() = false → no implicit defaults →reuins e acuvtles,AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence_number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-only + durationz1 together matchednothing.Why sequence_number-1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Apate filters are already intentionally stripped (that's existing logic in DATE_FILTER_KEYS)3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representsSetting sequence_number=1 is the minimal, correct signal: "this is not a fresh session open, don't apply page-load defaults". The criteria is otherwise builtIdentically to now the controller bullas it - same uriteria:: creater romkequest, same getondemandPagerilterset, same ondemandSearchidson ly — so theresults will now match.0 dl •Itlle wiun changesvapp/Services/Kiosk/AutomatedReports/ [ AskJiminnyReportActivityService.php +1 -1Ask anything (2*L)+ <> Code Claude Sonnet 4.6Vew allliReject allAccept allWinasun leams48:4uir-o( 4 spaces...
|
NULL
|
-4780954924196883603
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileEditFV faVsco.jsProjectvViewNavigateCo PhpStormFileEditFV faVsco.jsProjectvViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© DeviceRepository.php© ElasticActivityRepository.pl© EmailMessageRepository.p© GenericAiPromptRepositor:© GroupRepository.php(C) InboxEmailBatchRepositor)InboxRepository.php© InvitationRepository.php© JobRepository.php© LanguageRepository.php© MomentRepository.php© NotificationRepository.php© ParticipantRepository.php© ParticipantSpeechReposito© ParticipantStatsRepository© PlaybookCategoryRepositc© PlaybookRepository.php® PlaylistActivityRepository.fPlaylistRepository.phpPlaylistShareRepository.ph© QuestionRepository.php© RoleChangeEventRepositor© RoleRepository.php© SearchRepository.php© SnapshotRepository.php© SocialAccountRepository.p© StageRepository.php© SubscriptionSetRepository.TaskRepository.php© TeamAiContextRepository.TeamDomainsRepository.p©TeamInsightsRepository.pt©TeamRepository.php©ThemeRepository.php© TimezoneRepository.php© TopicRepository.php© TopicTriggerRepository.ph© TrackRepository.php© TranscriptionModelLocaleF© TranscriptionRepository.phC) TranscriptionSummarvRep© UserRepository.php© VocabularyRepository.pnp› D Rulesv D Services> [ Activity> C AjReports› D AvatarcalendarD ConferenceD Crm>MImport> MInternallv → Kioskv D AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsStTests passed: 1 (7 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console EUiconsole SlAGiNGASkJIminnykeportAcuivilyservice.ono xActiviysearch.php© Criteria.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php(e TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpOnDemandV2Controller.php© HistoryService.php© AskJiminnyReportActivityServiceTest.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityService1 usagepublic function __construct(private readonly ActivitySearch $activitySearch,private readonly ElasticActivityRepository $elasticRepository,private readonly LoggerInterface $logger,Df...3class Automacedkeportskepo ofA15 V4 ^ v 3959114115116117118119120/*** Retrieve all standard (non-Ask Liminny) an43* @param string $sortColumnThe column te 44* Oparam string $sortDirection The sort dire45* @return Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Liminny reports created 55* OodrdllusernusenThe User Who: 57*oparam scrine osorclocunnThe coLomn t958* Oparam string $sortDirection The sort dire59* @return Collection<AutomatedReport>*/—6214 usages63public function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J2 usagesprivate function buildSortedQuery(string $sor_68-71/*** Get all active and enabled reports with al73* @param string $frequency* dreturn cocLectron<Aucomacedкeрort»23 usagespublic function getActiveReportsByFrequency(§g0/*** Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,xno dueconstraint is applied - matching the behaviour of getContextForAskAnythingByFilte* @return string[] Activity IDs*/14 usaeespublic function getActivityIdsForSavedSearchCSearch $savedSearch,User $user,): array {$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);ocrlrerta = unlrerta.:credcerronkeqvestmargee €$requestParams,['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'array_merge ($requestParams,['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'$user->getTimezone()):$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);$activityIds = $this->elasticRepository->onDemandSearchIds0nly($user, $criteria, $filter$this->logger→>info('[AskviminnyReport] Fetched activity IDs for saved search', [saved_search_id => $savedSearch->getid),'user_id' => $user->getId(),'activity_count' => count($activityIds),1):return $activityIds;1 usageprivace tunccion bunLakequestrarams-romsearch(search esaveasearch, user suser: array$params = [];$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);foreach ($savedSearch->getFilters() as $filter) {$key = $filter->getFilterPropertyO);$valve = $filter->getFilterValve();if Cin_array(Skey,haystack: self::DATE_FILTER_KEYS,strict: true)){X Reject File 0* €, 0lablf Support Daily • in 2h 43 mAAskJiminnyReportActivityServiceT….Defaults100% C•Tue 14 Apr 12:17:11CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ...again. Why is there issue with that? Where is it ed to work with that. How is it used inCAskJ1minyReportActivityService. phpL44-66 should be sameed on savedSearch. THe ids in on demand and inLet me read the OnDemandV2Controller to understand how it builds criteria there:Poad OnDerwNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php:90-93:0 phpVO\Repository\0nDemandActivitySearch\Criteria::createFromRequest(array merge($request→>allo, ('limit' = $topCount, 'paqe' = 1]).suser->geclimezoneit passes srequest→>all() - wnich Includes sequence_number Trom the URL (e.g. sequence_number=4 Trom your staging URL). so when a user nas beenpaginating on the frontend, sequence_number is naturally non-zero.The full explanationyou didn't ask for themFilterActivityburaclonkandeisFirstRequest) in Criteriareturns true when sequenceNumber === 0 . When it's the "first request" these implicit defaults kick in automatically even ifOrganiserGroupInDefault on first requestman curation = minonly_recorded = 1User's own aroupEffectUrops u-secone acuivitlesRestricts to user's arourFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest() = false → no implicit defaults →reuins e acuvtles,AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence_number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-only + durationz1 together matchednothing.Why sequence_number-1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Apate filters are already intentionally stripped (that's existing logic in DATE_FILTER_KEYS)3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representsSetting sequence_number=1 is the minimal, correct signal: "this is not a fresh session open, don't apply page-load defaults". The criteria is otherwise builtIdentically to now the controller bullas it - same uriteria:: creater romkequest, same getondemandPagerilterset, same ondemandSearchidson ly — so theresults will now match.0 dl •Itlle wiun changesvapp/Services/Kiosk/AutomatedReports/ [ AskJiminnyReportActivityService.php +1 -1Ask anything (2*L)+ <> Code Claude Sonnet 4.6Vew allliReject allAccept allWinasun leams48:4uir-o( 4 spaces...
|
11155
|
|
11162
|
221
|
17
|
2026-04-14T09:17:14.788948+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158234788_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.js#11894 on JY-18909-automated-reports-ask-iminny K vProjectvToolsWindowHelp© DeviceRepository.php© ElasticActivityRepository.pl© EmailMessageRepository.p© GenericAiPromptRepositor:© GroupRepository.php(C) InboxEmailBatchRepositor)InboxRepository.php© InvitationRepository.php© JobRepository.php© LanguageRepository.php© MomentRepository.php© NotificationRepository.php© ParticipantRepository.php© ParticipantSpeechReposito© ParticipantStatsRepository© PlaybookCategoryRepositc© PlaybookRepository.php® PlaylistActivityRepository.fPlaylistRepository.phpPlaylistShareRepository.ph© QuestionRepository.php© RoleChangeEventRepositor© RoleRepository.php© SearchRepository.php© SnapshotRepository.php© SocialAccountRepository.p© StageRepository.php© SubscriptionSetRepository.TaskRepository.php© TeamAiContextRepository.TeamDomainsRepository.p©TeamInsightsRepository.pt©TeamRepository.php©ThemeRepository.php© TimezoneRepository.php© TopicRepository.php© TopicTriggerRepository.ph© TrackRepository.php© TranscriptionModelLocaleF© TranscriptionRepository.phC) TranscriptionSummarvRep© UserRepository.php© VocabularyRepository.pnp› D Rulesv D Services> [ Activity> D AjReports› D AvatarcalendarD ConferenceD Crm>MImport> MInternallv → Kioskv D AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsStTests passed: 1 (8 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console EUiconsole SlAGiNGAskJIminnykeporiAcuivilyservice.ono xActiviysearch.php© Criteria.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php(e TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpOnDemandV2Controller.php© HistoryService.php© AskJiminnyReportActivityServiceTest.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityService1 usagepublic function __construct(private readonly ActivitySearch $activitySearch,private readonly ElasticActivityRepository $elasticRepository,private readonly LoggerInterface $logger,Df...3class Automacedkeportskepo ofA15 V4 ^ v 3959114115116117118119120/*** Retrieve all standard (non-Ask Liminny) an43* @param string $sortColumnThe column te 44* Oparam string $sortDirection The sort dire45*orerurn coccecclonsauromceoreooro12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Liminny reports created 55* OodrdllusernusenThe User Who: 57*oparam scrine osorclocunnThe coLomn t958* Oparam string $sortDirection The sort dire59* @return Collection<AutomatedReport>*/—6214 usages63public function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J2 usagesprivate function buildSortedQuery(string $sor_68-71/*** Get all active and enabled reports with al73* @param string $frequency* dreturh coLcectzon<aucomacedкeрort>23 usagespublic function getActiveReportsByFrequency(§g0/*** Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,xno dueconstraint is applied - matching the behaviour of getContextForAskAnythingByFilte* @return string[] Activity IDs*/14 usaeespublic function getActivityIdsForSavedSearch(Search $savedSearch,User $user,): array {$requestParams = Sthis->buildRequestParamsFromSearch($savedSearch, Suser);ocrlrerta = unlrerta.:credcerronkeqvestmargee €$requestParams,['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'array_merge ($requestParams,['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'$user->getTimezone()):$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);$activityIds = $this->elasticRepository->onDemandSearchIds0nly($user, $criteria, $filter$this->logger→>info('[AskviminnyReport] Fetched activity IDs for saved search', [saved_search_id => $savedSearch->getid),'user_id' => $user->getId(),'activity_count' => count($activityIds),1):return $activityIds;1 usageprivace tunccion bunLakequestrarams-romsearch(search esaveasearch, user suser): array$params = [];$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);foreach ($savedSearch->getFilters() as $filter) {$key = $filter->getFilterPropertyO);$valve = $filter->getFilterValve();if Cin_array(Skey,haystack: self::DATE_FILTER_KEYS,strict: true)){X Reject File 0* €, 0lablSupport Daily - in 2h 43 mAU AskJiminnyReportActivityServiceT..Defaults100% C•Tue 14 Apr 12:17:14CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ...again. Why is there issue with that? Where is it ed to work with that. How is it used inCAskJ1minyReportActivityService. phpL44-66 should be sameed on savedSearch. THe ids in on demand and inLet me read the OnDemandV2Controller to understand how it builds criteria there:Poad OnDemandV?ConwNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php:90-93:0 phpVO\Repository\0nDemandActivitySearch\Criteria::createFromRequest(array merge($request→>allo, ('limit' = $topCount, 'paqe' = 11)suser->geclimezoneit passes Srequest→>all() - wnich Includes sequence_number trom the URL (e.g. sequence_number=4 Trom your staging URL). so when a user nas beenpaginating on the frontend, sequence_number is naturally non-zero.The full explanationyou didn't ask for themFilterActivityburaclonkandeisFirstRequest in Criteria returns true when sequenceNumber === 0 . When it's the "first request" these implicit defaults kick in automatically even ifDefault on first requestman curation = minonly_recorded = 1User's own aroupEffectUrops u-secone acuivitlesActuvltvkecordecOrganiserGroupInRestricts to user's arourFrontend hits /api/v1/page/on-demand?topic_id[]=..&sequence_number=4 → sequence_number=4 → isFirstRequest() = false → no implicit defaults →reuins e acuvtles,AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence_number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-only + duration≥1 together matchednothing.Why sequence_number-1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)n DATE_FILTER_ KEYS lAdding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representsSetting sequence_number=1 is the minimal, correct signal: "this is not a fresh session open, don't apply page-load defaults". The criteria is otherwise builtIdenticalvao nowa ne controleroulasne samer uo derehadreaterconkequest samer oeitonDemandPaderultenset same onDemandsearchidsunilv - sonneresults will now match.Itlle wiun changesvapp/Services/Kiosk/AutomatedReports/ [ AskJiminnyReportActivityService.php +1 -1Ask anything (2*L)+ <> Code Claude Sonnet 4.6Vew allliReject allAccept allWinasun leams48:4uir-o( 4 spaces...
|
NULL
|
5554419219574949985
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.js#11894 on JY-18909-automated-reports-ask-iminny K vProjectvToolsWindowHelp© DeviceRepository.php© ElasticActivityRepository.pl© EmailMessageRepository.p© GenericAiPromptRepositor:© GroupRepository.php(C) InboxEmailBatchRepositor)InboxRepository.php© InvitationRepository.php© JobRepository.php© LanguageRepository.php© MomentRepository.php© NotificationRepository.php© ParticipantRepository.php© ParticipantSpeechReposito© ParticipantStatsRepository© PlaybookCategoryRepositc© PlaybookRepository.php® PlaylistActivityRepository.fPlaylistRepository.phpPlaylistShareRepository.ph© QuestionRepository.php© RoleChangeEventRepositor© RoleRepository.php© SearchRepository.php© SnapshotRepository.php© SocialAccountRepository.p© StageRepository.php© SubscriptionSetRepository.TaskRepository.php© TeamAiContextRepository.TeamDomainsRepository.p©TeamInsightsRepository.pt©TeamRepository.php©ThemeRepository.php© TimezoneRepository.php© TopicRepository.php© TopicTriggerRepository.ph© TrackRepository.php© TranscriptionModelLocaleF© TranscriptionRepository.phC) TranscriptionSummarvRep© UserRepository.php© VocabularyRepository.pnp› D Rulesv D Services> [ Activity> D AjReports› D AvatarcalendarD ConferenceD Crm>MImport> MInternallv → Kioskv D AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsStTests passed: 1 (8 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console EUiconsole SlAGiNGAskJIminnykeporiAcuivilyservice.ono xActiviysearch.php© Criteria.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php(e TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpOnDemandV2Controller.php© HistoryService.php© AskJiminnyReportActivityServiceTest.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityService1 usagepublic function __construct(private readonly ActivitySearch $activitySearch,private readonly ElasticActivityRepository $elasticRepository,private readonly LoggerInterface $logger,Df...3class Automacedkeportskepo ofA15 V4 ^ v 3959114115116117118119120/*** Retrieve all standard (non-Ask Liminny) an43* @param string $sortColumnThe column te 44* Oparam string $sortDirection The sort dire45*orerurn coccecclonsauromceoreooro12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Liminny reports created 55* OodrdllusernusenThe User Who: 57*oparam scrine osorclocunnThe coLomn t958* Oparam string $sortDirection The sort dire59* @return Collection<AutomatedReport>*/—6214 usages63public function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J2 usagesprivate function buildSortedQuery(string $sor_68-71/*** Get all active and enabled reports with al73* @param string $frequency* dreturh coLcectzon<aucomacedкeрort>23 usagespublic function getActiveReportsByFrequency(§g0/*** Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,xno dueconstraint is applied - matching the behaviour of getContextForAskAnythingByFilte* @return string[] Activity IDs*/14 usaeespublic function getActivityIdsForSavedSearch(Search $savedSearch,User $user,): array {$requestParams = Sthis->buildRequestParamsFromSearch($savedSearch, Suser);ocrlrerta = unlrerta.:credcerronkeqvestmargee €$requestParams,['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'array_merge ($requestParams,['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'$user->getTimezone()):$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);$activityIds = $this->elasticRepository->onDemandSearchIds0nly($user, $criteria, $filter$this->logger→>info('[AskviminnyReport] Fetched activity IDs for saved search', [saved_search_id => $savedSearch->getid),'user_id' => $user->getId(),'activity_count' => count($activityIds),1):return $activityIds;1 usageprivace tunccion bunLakequestrarams-romsearch(search esaveasearch, user suser): array$params = [];$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);foreach ($savedSearch->getFilters() as $filter) {$key = $filter->getFilterPropertyO);$valve = $filter->getFilterValve();if Cin_array(Skey,haystack: self::DATE_FILTER_KEYS,strict: true)){X Reject File 0* €, 0lablSupport Daily - in 2h 43 mAU AskJiminnyReportActivityServiceT..Defaults100% C•Tue 14 Apr 12:17:14CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ...again. Why is there issue with that? Where is it ed to work with that. How is it used inCAskJ1minyReportActivityService. phpL44-66 should be sameed on savedSearch. THe ids in on demand and inLet me read the OnDemandV2Controller to understand how it builds criteria there:Poad OnDemandV?ConwNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php:90-93:0 phpVO\Repository\0nDemandActivitySearch\Criteria::createFromRequest(array merge($request→>allo, ('limit' = $topCount, 'paqe' = 11)suser->geclimezoneit passes Srequest→>all() - wnich Includes sequence_number trom the URL (e.g. sequence_number=4 Trom your staging URL). so when a user nas beenpaginating on the frontend, sequence_number is naturally non-zero.The full explanationyou didn't ask for themFilterActivityburaclonkandeisFirstRequest in Criteria returns true when sequenceNumber === 0 . When it's the "first request" these implicit defaults kick in automatically even ifDefault on first requestman curation = minonly_recorded = 1User's own aroupEffectUrops u-secone acuivitlesActuvltvkecordecOrganiserGroupInRestricts to user's arourFrontend hits /api/v1/page/on-demand?topic_id[]=..&sequence_number=4 → sequence_number=4 → isFirstRequest() = false → no implicit defaults →reuins e acuvtles,AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence_number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-only + duration≥1 together matchednothing.Why sequence_number-1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)n DATE_FILTER_ KEYS lAdding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representsSetting sequence_number=1 is the minimal, correct signal: "this is not a fresh session open, don't apply page-load defaults". The criteria is otherwise builtIdenticalvao nowa ne controleroulasne samer uo derehadreaterconkequest samer oeitonDemandPaderultenset same onDemandsearchidsunilv - sonneresults will now match.Itlle wiun changesvapp/Services/Kiosk/AutomatedReports/ [ AskJiminnyReportActivityService.php +1 -1Ask anything (2*L)+ <> Code Claude Sonnet 4.6Vew allliReject allAccept allWinasun leams48:4uir-o( 4 spaces...
|
NULL
|
|
11164
|
221
|
18
|
2026-04-14T09:17:23.632452+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158243632_m2.jpg...
|
PhpStorm
|
faVsco.js – AskJiminnyReportActivityService.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Kiosk\AutomatedReports;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityActualDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityUpdatedDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\DealInsights\ClosingPeriodFilter;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\User;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
class AskJiminnyReportActivityService
{
private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;
private const array DATE_FILTER_KEYS = [
ActivityActualDate::PARAM_START_DATE,
ActivityActualDate::PARAM_END_DATE,
ActivityUpdatedDate::PARAM_UPDATED_FROM,
ActivityUpdatedDate::PARAM_UPDATED_TO,
ClosingPeriodFilter::KEY_START_DATE,
ClosingPeriodFilter::KEY_END_DATE,
];
public function __construct(
private readonly ActivitySearch $activitySearch,
private readonly ElasticActivityRepository $elasticRepository,
private readonly LoggerInterface $logger,
) {
}
/**
* Fetch activity IDs for a saved search, passing its filters as-is to Criteria.
* Date filters stored on the saved search are excluded; if no other filters exist,
* no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.
*
* @return string[] Activity IDs
*/
public function getActivityIdsForSavedSearch(
Search $savedSearch,
User $user,
): array {
$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);
$criteria = Criteria::createFromRequest(
array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),
$user->getTimezone()
);
$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);
$activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);
$this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [
'saved_search_id' => $savedSearch->getId(),
'user_id' => $user->getId(),
'activity_count' => count($activityIds),
]);
return $activityIds;
}
private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array
{
$params = [];
$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);
foreach ($savedSearch->getFilters() as $filter) {
$key = $filter->getFilterProperty();
$value = $filter->getFilterValue();
if (in_array($key, self::DATE_FILTER_KEYS, true)) {
continue;
}
if (isset($params[$key])) {
$params[$key][] = $value;
} elseif (in_array($key, $arrayFilterKeys, true)) {
$params[$key] = [$value];
} else {
$params[$key] = $value;
}
}
return $params;
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Repositories;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSort;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSortDirection;
class AutomatedReportsRepository
{
/**
* Create a new automated report
*
* @param array $data
*
* @return AutomatedReport
*/
public function create(array $data): AutomatedReport
{
return AutomatedReport::create($data);
}
/**
* Find an automated report by UUID
*
* @param string $uuid
*
* @return AutomatedReport|null
*/
public function findByUuid(string $uuid): ?AutomatedReport
{
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();
}
public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport
{
if (is_numeric($idOrUuid)) {
return AutomatedReport::find((int) $idOrUuid);
}
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();
}
/**
* Retrieve all standard (non-Ask Jiminny) automated reports.
*
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAllStandardReports(
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->get();
}
/**
* Retrieve all Ask Jiminny reports created by the given user.
*
* @param User $user The user whose reports to retrieve.
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAskJiminnyReportsByUser(
User $user,
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->where('created_by', $user->getId())
->get();
}
private function buildSortedQuery(string $sortColumn, string $sortDirection): \Illuminate\Database\Eloquent\Builder
{
$allowedColumns = ['created_by', 'created_at'];
if (! in_array($sortColumn, $allowedColumns)) {
$sortColumn = 'created_at';
}
$sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';
$query = AutomatedReport::query()->with(['creator', 'team']);
if ($sortColumn === 'created_by') {
$query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')
->orderByRaw("users.name COLLATE utf8mb4_unicode_ci {$sortDirection}")
->select('automated_reports.*');
} else {
$query->orderBy($sortColumn, $sortDirection);
}
return $query;
}
/**
* Get all active and enabled reports with active teams for the specified frequency.
*
* @param string $frequency
*
* @return Collection<AutomatedReport>
*/
public function getActiveReportsByFrequency(string $frequency): Collection
{
return AutomatedReport::where('automated_reports.status', true)
->where('automated_reports.frequency', $frequency)
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->where('teams.status', Team::STATUS_ACTIVE)
->where(function ($query) {
$query->whereNull('automated_reports.expires_at')
->orWhere('automated_reports.expires_at', '>=', now()->toDateString());
})
->select('automated_reports.*')
->get();
}
/**
* Update an automated report
*
* @param AutomatedReport $report
* @param array $data
*
* @return AutomatedReport
*/
public function update(AutomatedReport $report, array $data): AutomatedReport
{
$report->update($data);
return $report;
}
/**
* Create a new automated report result.
*
* @param array $data The data to create the automated report result with.
*
* @return AutomatedReportResult The newly created automated report result.
*/
public function createResult(array $data): AutomatedReportResult
{
return AutomatedReportResult::create($data);
}
/**
* Find an automated report result by UUID.
*
* @param string $uuid The UUID to find the automated report result with.
*
* @return AutomatedReportResult|null The automated report result if found, otherwise null.
*/
public function findResultByUuid(string $uuid): ?AutomatedReportResult
{
return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();
}
public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('uuid', AutomatedReportResult::toOptimized($uuid))
->whereHas('report', static function ($query) use ($user): void {
$query->where('team_id', $user->getTeamId())
->where('created_by', $user->getId());
})
->first();
}
public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('parent_id', $result->getId())
->where('media_type', $type)
->first();
}
public function getGeneratedNotSentResults(): Collection
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNull('sent_at')
->where('status', AutomatedReportResult::STATUS_GENERATED)
->whereHas('report')
->with('report')
->get();
}
public function getPaginatedUserReports(
User $user,
ReportSort $sort,
ReportSortDirection $sortDirection,
int $resultsPerPage,
int $page,
?Carbon $fromDate,
?Carbon $toDate,
array $teamIds,
array $reportTypes,
?string $name,
): LengthAwarePaginator {
$query = AutomatedReportResult::query()
->whereNotNull('automated_report_results.generated_at')
->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')
->where('automated_reports.team_id', $user->getTeamId())
->whereJsonContains('automated_reports.recipients->users', $user->getId())
->orderByRaw("$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}")
->select('automated_report_results.*')
->with('report.team');
if ($fromDate !== null && $toDate !== null) {
$query->whereBetween('generated_at', [$fromDate, $toDate]);
}
if (! empty($teamIds)) {
$query->where(function ($q) use ($teamIds) {
foreach ($teamIds as $id) {
$q->orWhereJsonContains('automated_reports.groups', $id);
}
});
}
if (! empty($reportTypes)) {
$query->whereIn('automated_reports.type', $reportTypes);
}
if (! empty($name)) {
$query->whereLike('name', "%$name%");
}
return $query->paginate($resultsPerPage, ['*'], 'page', $page);
}
public function countUserReports(User $user): int
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNotNull('sent_at')
->whereHas('report', function ($q) use ($user) {
$q->where('team_id', $user->getTeamId())
->whereJsonContains('recipients->users', $user->getId());
})
->count();
}
/**
* Get report IDs for a specific team
*
* @param Team $team
*
* @return \Illuminate\Support\Collection
*/
public function getReportIdsByTeam(Team $team): \Illuminate\Support\Collection
{
return AutomatedReport::where('team_id', $team->getId())->pluck('id');
}
/**
* Get all reports for a specific team
*
* @param Team $team
*
* @return Collection
*/
public function getReportsByTeam(Team $team): Collection
{
return AutomatedReport::where('team_id', $team->getId())->get();
}
/**
* Get all report results for a specific report
*
* @param AutomatedReport $report
*
* @return Collection
*/
public function getResultsByReport(AutomatedReport $report): Collection
{
return $this->getResultsByReportQuery($report)->get();
}
public function getResultsByReportQuery(AutomatedReport $report): Builder
{
return AutomatedReportResult::where('report_id', $report->getId());
}
public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder
{
$reportIds = $this->getReportIdsByTeam($team);
return AutomatedReportResult::query()->whereIn('report_id', $reportIds)
->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);
}
/**
* @param int|null $teamId Optional team ID to filter results
*
* @return \Illuminate\Support\Collection<int, int> Collection of team IDs
*/
public function getTeamIdsWithReportsResults(?int $teamId = null): \Illuminate\Support\Collection
{
$query = DB::table('automated_reports')
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->select('teams.id')
->distinct();
if ($teamId !== null) {
$query->where('teams.id', $teamId);
}
return $query->pluck('teams.id');
}
}
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.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","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.7589844,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceT…Defaults","depth":6,"bounds":{"left":0.7769531,"top":0.017361112,"width":0.12382813,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.009375,"height":0.0},"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.00859375,"height":0.0},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.00859375,"height":0.0},"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.23320313,"top":1.0,"width":0.008203125,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Kiosk\\AutomatedReports;\n\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityActualDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityUpdatedDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealInsights\\ClosingPeriodFilter;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\n\nclass AskJiminnyReportActivityService\n{\n private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;\n\n private const array DATE_FILTER_KEYS = [\n ActivityActualDate::PARAM_START_DATE,\n ActivityActualDate::PARAM_END_DATE,\n ActivityUpdatedDate::PARAM_UPDATED_FROM,\n ActivityUpdatedDate::PARAM_UPDATED_TO,\n ClosingPeriodFilter::KEY_START_DATE,\n ClosingPeriodFilter::KEY_END_DATE,\n ];\n\n public function __construct(\n private readonly ActivitySearch $activitySearch,\n private readonly ElasticActivityRepository $elasticRepository,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n /**\n * Fetch activity IDs for a saved search, passing its filters as-is to Criteria.\n * Date filters stored on the saved search are excluded; if no other filters exist,\n * no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.\n *\n * @return string[] Activity IDs\n */\n public function getActivityIdsForSavedSearch(\n Search $savedSearch,\n User $user,\n ): array {\n $requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);\n\n $criteria = Criteria::createFromRequest(\n array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);\n\n $activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);\n\n $this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [\n 'saved_search_id' => $savedSearch->getId(),\n 'user_id' => $user->getId(),\n 'activity_count' => count($activityIds),\n ]);\n\n return $activityIds;\n }\n\n private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array\n {\n $params = [];\n $arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);\n\n foreach ($savedSearch->getFilters() as $filter) {\n $key = $filter->getFilterProperty();\n $value = $filter->getFilterValue();\n\n if (in_array($key, self::DATE_FILTER_KEYS, true)) {\n continue;\n }\n\n if (isset($params[$key])) {\n $params[$key][] = $value;\n } elseif (in_array($key, $arrayFilterKeys, true)) {\n $params[$key] = [$value];\n } else {\n $params[$key] = $value;\n }\n }\n\n return $params;\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Kiosk\\AutomatedReports;\n\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityActualDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityUpdatedDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealInsights\\ClosingPeriodFilter;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\n\nclass AskJiminnyReportActivityService\n{\n private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;\n\n private const array DATE_FILTER_KEYS = [\n ActivityActualDate::PARAM_START_DATE,\n ActivityActualDate::PARAM_END_DATE,\n ActivityUpdatedDate::PARAM_UPDATED_FROM,\n ActivityUpdatedDate::PARAM_UPDATED_TO,\n ClosingPeriodFilter::KEY_START_DATE,\n ClosingPeriodFilter::KEY_END_DATE,\n ];\n\n public function __construct(\n private readonly ActivitySearch $activitySearch,\n private readonly ElasticActivityRepository $elasticRepository,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n /**\n * Fetch activity IDs for a saved search, passing its filters as-is to Criteria.\n * Date filters stored on the saved search are excluded; if no other filters exist,\n * no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.\n *\n * @return string[] Activity IDs\n */\n public function getActivityIdsForSavedSearch(\n Search $savedSearch,\n User $user,\n ): array {\n $requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);\n\n $criteria = Criteria::createFromRequest(\n array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);\n\n $activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);\n\n $this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [\n 'saved_search_id' => $savedSearch->getId(),\n 'user_id' => $user->getId(),\n 'activity_count' => count($activityIds),\n ]);\n\n return $activityIds;\n }\n\n private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array\n {\n $params = [];\n $arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);\n\n foreach ($savedSearch->getFilters() as $filter) {\n $key = $filter->getFilterProperty();\n $value = $filter->getFilterValue();\n\n if (in_array($key, self::DATE_FILTER_KEYS, true)) {\n continue;\n }\n\n if (isset($params[$key])) {\n $params[$key][] = $value;\n } elseif (in_array($key, $arrayFilterKeys, true)) {\n $params[$key] = [$value];\n } else {\n $params[$key] = $value;\n }\n }\n\n return $params;\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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"15","depth":4,"bounds":{"left":0.2589844,"top":0.28125,"width":0.011328125,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.27265626,"top":0.28125,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.28398436,"top":0.27986112,"width":0.00859375,"height":0.015972223},"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.29257813,"top":0.27986112,"width":0.008203125,"height":0.015972223},"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\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSort;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\ReportSortDirection;\n\nclass AutomatedReportsRepository\n{\n /**\n * Create a new automated report\n *\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function create(array $data): AutomatedReport\n {\n return AutomatedReport::create($data);\n }\n\n /**\n * Find an automated report by UUID\n *\n * @param string $uuid\n *\n * @return AutomatedReport|null\n */\n public function findByUuid(string $uuid): ?AutomatedReport\n {\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();\n }\n\n public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport\n {\n if (is_numeric($idOrUuid)) {\n return AutomatedReport::find((int) $idOrUuid);\n }\n\n return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();\n }\n\n /**\n * Retrieve all standard (non-Ask Jiminny) automated reports.\n *\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAllStandardReports(\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->get();\n }\n\n /**\n * Retrieve all Ask Jiminny reports created by the given user.\n *\n * @param User $user The user whose reports to retrieve.\n * @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.\n * @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.\n *\n * @return Collection<AutomatedReport>\n */\n public function getAskJiminnyReportsByUser(\n User $user,\n string $sortColumn = 'created_at',\n string $sortDirection = 'desc'\n ): Collection {\n return $this->buildSortedQuery($sortColumn, $sortDirection)\n ->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)\n ->where('created_by', $user->getId())\n ->get();\n }\n\n private function buildSortedQuery(string $sortColumn, string $sortDirection): \\Illuminate\\Database\\Eloquent\\Builder\n {\n $allowedColumns = ['created_by', 'created_at'];\n if (! in_array($sortColumn, $allowedColumns)) {\n $sortColumn = 'created_at';\n }\n\n $sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';\n\n $query = AutomatedReport::query()->with(['creator', 'team']);\n\n if ($sortColumn === 'created_by') {\n $query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')\n ->orderByRaw(\"users.name COLLATE utf8mb4_unicode_ci {$sortDirection}\")\n ->select('automated_reports.*');\n } else {\n $query->orderBy($sortColumn, $sortDirection);\n }\n\n return $query;\n }\n\n /**\n * Get all active and enabled reports with active teams for the specified frequency.\n *\n * @param string $frequency\n *\n * @return Collection<AutomatedReport>\n */\n public function getActiveReportsByFrequency(string $frequency): Collection\n {\n return AutomatedReport::where('automated_reports.status', true)\n ->where('automated_reports.frequency', $frequency)\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->where('teams.status', Team::STATUS_ACTIVE)\n ->where(function ($query) {\n $query->whereNull('automated_reports.expires_at')\n ->orWhere('automated_reports.expires_at', '>=', now()->toDateString());\n })\n ->select('automated_reports.*')\n ->get();\n }\n\n /**\n * Update an automated report\n *\n * @param AutomatedReport $report\n * @param array $data\n *\n * @return AutomatedReport\n */\n public function update(AutomatedReport $report, array $data): AutomatedReport\n {\n $report->update($data);\n\n return $report;\n }\n\n /**\n * Create a new automated report result.\n *\n * @param array $data The data to create the automated report result with.\n *\n * @return AutomatedReportResult The newly created automated report result.\n */\n public function createResult(array $data): AutomatedReportResult\n {\n return AutomatedReportResult::create($data);\n }\n\n /**\n * Find an automated report result by UUID.\n *\n * @param string $uuid The UUID to find the automated report result with.\n *\n * @return AutomatedReportResult|null The automated report result if found, otherwise null.\n */\n public function findResultByUuid(string $uuid): ?AutomatedReportResult\n {\n return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();\n }\n\n public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('uuid', AutomatedReportResult::toOptimized($uuid))\n ->whereHas('report', static function ($query) use ($user): void {\n $query->where('team_id', $user->getTeamId())\n ->where('created_by', $user->getId());\n })\n ->first();\n }\n\n public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult\n {\n return AutomatedReportResult::query()\n ->where('parent_id', $result->getId())\n ->where('media_type', $type)\n ->first();\n }\n\n public function getGeneratedNotSentResults(): Collection\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNull('sent_at')\n ->where('status', AutomatedReportResult::STATUS_GENERATED)\n ->whereHas('report')\n ->with('report')\n ->get();\n }\n\n public function getPaginatedUserReports(\n User $user,\n ReportSort $sort,\n ReportSortDirection $sortDirection,\n int $resultsPerPage,\n int $page,\n ?Carbon $fromDate,\n ?Carbon $toDate,\n array $teamIds,\n array $reportTypes,\n ?string $name,\n ): LengthAwarePaginator {\n $query = AutomatedReportResult::query()\n ->whereNotNull('automated_report_results.generated_at')\n ->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')\n ->where('automated_reports.team_id', $user->getTeamId())\n ->whereJsonContains('automated_reports.recipients->users', $user->getId())\n ->orderByRaw(\"$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}\")\n ->select('automated_report_results.*')\n ->with('report.team');\n\n if ($fromDate !== null && $toDate !== null) {\n $query->whereBetween('generated_at', [$fromDate, $toDate]);\n }\n\n if (! empty($teamIds)) {\n $query->where(function ($q) use ($teamIds) {\n foreach ($teamIds as $id) {\n $q->orWhereJsonContains('automated_reports.groups', $id);\n }\n });\n }\n\n if (! empty($reportTypes)) {\n $query->whereIn('automated_reports.type', $reportTypes);\n }\n\n if (! empty($name)) {\n $query->whereLike('name', \"%$name%\");\n }\n\n return $query->paginate($resultsPerPage, ['*'], 'page', $page);\n }\n\n public function countUserReports(User $user): int\n {\n return AutomatedReportResult::query()\n ->whereNotNull('generated_at')\n ->whereNotNull('sent_at')\n ->whereHas('report', function ($q) use ($user) {\n $q->where('team_id', $user->getTeamId())\n ->whereJsonContains('recipients->users', $user->getId());\n })\n ->count();\n }\n\n /**\n * Get report IDs for a specific team\n *\n * @param Team $team\n *\n * @return \\Illuminate\\Support\\Collection\n */\n public function getReportIdsByTeam(Team $team): \\Illuminate\\Support\\Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->pluck('id');\n }\n\n /**\n * Get all reports for a specific team\n *\n * @param Team $team\n *\n * @return Collection\n */\n public function getReportsByTeam(Team $team): Collection\n {\n return AutomatedReport::where('team_id', $team->getId())->get();\n }\n\n /**\n * Get all report results for a specific report\n *\n * @param AutomatedReport $report\n *\n * @return Collection\n */\n public function getResultsByReport(AutomatedReport $report): Collection\n {\n return $this->getResultsByReportQuery($report)->get();\n }\n\n public function getResultsByReportQuery(AutomatedReport $report): Builder\n {\n return AutomatedReportResult::where('report_id', $report->getId());\n }\n\n public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder\n {\n $reportIds = $this->getReportIdsByTeam($team);\n\n return AutomatedReportResult::query()->whereIn('report_id', $reportIds)\n ->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);\n }\n\n /**\n * @param int|null $teamId Optional team ID to filter results\n *\n * @return \\Illuminate\\Support\\Collection<int, int> Collection of team IDs\n */\n public function getTeamIdsWithReportsResults(?int $teamId = null): \\Illuminate\\Support\\Collection\n {\n $query = DB::table('automated_reports')\n ->join('teams', 'automated_reports.team_id', '=', 'teams.id')\n ->select('teams.id')\n ->distinct();\n\n if ($teamId !== null) {\n $query->where('teams.id', $teamId);\n }\n\n return $query->pluck('teams.id');\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,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.0140625,"top":0.041666668,"width":0.028515626,"height":0.021527778},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
8563436494813991353
|
-5967358188006330764
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Kiosk\AutomatedReports;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityActualDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityUpdatedDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\DealInsights\ClosingPeriodFilter;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\User;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
class AskJiminnyReportActivityService
{
private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;
private const array DATE_FILTER_KEYS = [
ActivityActualDate::PARAM_START_DATE,
ActivityActualDate::PARAM_END_DATE,
ActivityUpdatedDate::PARAM_UPDATED_FROM,
ActivityUpdatedDate::PARAM_UPDATED_TO,
ClosingPeriodFilter::KEY_START_DATE,
ClosingPeriodFilter::KEY_END_DATE,
];
public function __construct(
private readonly ActivitySearch $activitySearch,
private readonly ElasticActivityRepository $elasticRepository,
private readonly LoggerInterface $logger,
) {
}
/**
* Fetch activity IDs for a saved search, passing its filters as-is to Criteria.
* Date filters stored on the saved search are excluded; if no other filters exist,
* no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.
*
* @return string[] Activity IDs
*/
public function getActivityIdsForSavedSearch(
Search $savedSearch,
User $user,
): array {
$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);
$criteria = Criteria::createFromRequest(
array_merge($requestParams, ['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page' => 1, 'sequence_number' => 1]),
$user->getTimezone()
);
$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);
$activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);
$this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [
'saved_search_id' => $savedSearch->getId(),
'user_id' => $user->getId(),
'activity_count' => count($activityIds),
]);
return $activityIds;
}
private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array
{
$params = [];
$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);
foreach ($savedSearch->getFilters() as $filter) {
$key = $filter->getFilterProperty();
$value = $filter->getFilterValue();
if (in_array($key, self::DATE_FILTER_KEYS, true)) {
continue;
}
if (isset($params[$key])) {
$params[$key][] = $value;
} elseif (in_array($key, $arrayFilterKeys, true)) {
$params[$key] = [$value];
} else {
$params[$key] = $value;
}
}
return $params;
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Repositories;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSort;
use Jiminny\Services\Kiosk\AutomatedReports\ReportSortDirection;
class AutomatedReportsRepository
{
/**
* Create a new automated report
*
* @param array $data
*
* @return AutomatedReport
*/
public function create(array $data): AutomatedReport
{
return AutomatedReport::create($data);
}
/**
* Find an automated report by UUID
*
* @param string $uuid
*
* @return AutomatedReport|null
*/
public function findByUuid(string $uuid): ?AutomatedReport
{
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($uuid))->first();
}
public function findByIdOrUuid(string $idOrUuid): ?AutomatedReport
{
if (is_numeric($idOrUuid)) {
return AutomatedReport::find((int) $idOrUuid);
}
return AutomatedReport::where('uuid', AutomatedReport::toOptimized($idOrUuid))->first();
}
/**
* Retrieve all standard (non-Ask Jiminny) automated reports.
*
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAllStandardReports(
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->whereNot('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->get();
}
/**
* Retrieve all Ask Jiminny reports created by the given user.
*
* @param User $user The user whose reports to retrieve.
* @param string $sortColumn The column to sort by. Allowed values: 'created_by', 'created_at'. Defaults to 'created_at'.
* @param string $sortDirection The sort direction. Allowed values: 'asc', 'desc'. Defaults to 'desc'.
*
* @return Collection<AutomatedReport>
*/
public function getAskJiminnyReportsByUser(
User $user,
string $sortColumn = 'created_at',
string $sortDirection = 'desc'
): Collection {
return $this->buildSortedQuery($sortColumn, $sortDirection)
->where('type', AutomatedReportsService::TYPE_ASK_JIMINNY)
->where('created_by', $user->getId())
->get();
}
private function buildSortedQuery(string $sortColumn, string $sortDirection): \Illuminate\Database\Eloquent\Builder
{
$allowedColumns = ['created_by', 'created_at'];
if (! in_array($sortColumn, $allowedColumns)) {
$sortColumn = 'created_at';
}
$sortDirection = strtolower($sortDirection) === 'asc' ? 'asc' : 'desc';
$query = AutomatedReport::query()->with(['creator', 'team']);
if ($sortColumn === 'created_by') {
$query->leftJoin('users', 'users.id', '=', 'automated_reports.created_by')
->orderByRaw("users.name COLLATE utf8mb4_unicode_ci {$sortDirection}")
->select('automated_reports.*');
} else {
$query->orderBy($sortColumn, $sortDirection);
}
return $query;
}
/**
* Get all active and enabled reports with active teams for the specified frequency.
*
* @param string $frequency
*
* @return Collection<AutomatedReport>
*/
public function getActiveReportsByFrequency(string $frequency): Collection
{
return AutomatedReport::where('automated_reports.status', true)
->where('automated_reports.frequency', $frequency)
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->where('teams.status', Team::STATUS_ACTIVE)
->where(function ($query) {
$query->whereNull('automated_reports.expires_at')
->orWhere('automated_reports.expires_at', '>=', now()->toDateString());
})
->select('automated_reports.*')
->get();
}
/**
* Update an automated report
*
* @param AutomatedReport $report
* @param array $data
*
* @return AutomatedReport
*/
public function update(AutomatedReport $report, array $data): AutomatedReport
{
$report->update($data);
return $report;
}
/**
* Create a new automated report result.
*
* @param array $data The data to create the automated report result with.
*
* @return AutomatedReportResult The newly created automated report result.
*/
public function createResult(array $data): AutomatedReportResult
{
return AutomatedReportResult::create($data);
}
/**
* Find an automated report result by UUID.
*
* @param string $uuid The UUID to find the automated report result with.
*
* @return AutomatedReportResult|null The automated report result if found, otherwise null.
*/
public function findResultByUuid(string $uuid): ?AutomatedReportResult
{
return AutomatedReportResult::where('uuid', AutomatedReportResult::toOptimized($uuid))->first();
}
public function findResultByUuidForUser(string $uuid, User $user): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('uuid', AutomatedReportResult::toOptimized($uuid))
->whereHas('report', static function ($query) use ($user): void {
$query->where('team_id', $user->getTeamId())
->where('created_by', $user->getId());
})
->first();
}
public function findChildResult(AutomatedReportResult $result, string $type): ?AutomatedReportResult
{
return AutomatedReportResult::query()
->where('parent_id', $result->getId())
->where('media_type', $type)
->first();
}
public function getGeneratedNotSentResults(): Collection
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNull('sent_at')
->where('status', AutomatedReportResult::STATUS_GENERATED)
->whereHas('report')
->with('report')
->get();
}
public function getPaginatedUserReports(
User $user,
ReportSort $sort,
ReportSortDirection $sortDirection,
int $resultsPerPage,
int $page,
?Carbon $fromDate,
?Carbon $toDate,
array $teamIds,
array $reportTypes,
?string $name,
): LengthAwarePaginator {
$query = AutomatedReportResult::query()
->whereNotNull('automated_report_results.generated_at')
->join('automated_reports', 'automated_report_results.report_id', '=', 'automated_reports.id')
->where('automated_reports.team_id', $user->getTeamId())
->whereJsonContains('automated_reports.recipients->users', $user->getId())
->orderByRaw("$sort->value COLLATE utf8mb4_unicode_ci {$sortDirection->value}")
->select('automated_report_results.*')
->with('report.team');
if ($fromDate !== null && $toDate !== null) {
$query->whereBetween('generated_at', [$fromDate, $toDate]);
}
if (! empty($teamIds)) {
$query->where(function ($q) use ($teamIds) {
foreach ($teamIds as $id) {
$q->orWhereJsonContains('automated_reports.groups', $id);
}
});
}
if (! empty($reportTypes)) {
$query->whereIn('automated_reports.type', $reportTypes);
}
if (! empty($name)) {
$query->whereLike('name', "%$name%");
}
return $query->paginate($resultsPerPage, ['*'], 'page', $page);
}
public function countUserReports(User $user): int
{
return AutomatedReportResult::query()
->whereNotNull('generated_at')
->whereNotNull('sent_at')
->whereHas('report', function ($q) use ($user) {
$q->where('team_id', $user->getTeamId())
->whereJsonContains('recipients->users', $user->getId());
})
->count();
}
/**
* Get report IDs for a specific team
*
* @param Team $team
*
* @return \Illuminate\Support\Collection
*/
public function getReportIdsByTeam(Team $team): \Illuminate\Support\Collection
{
return AutomatedReport::where('team_id', $team->getId())->pluck('id');
}
/**
* Get all reports for a specific team
*
* @param Team $team
*
* @return Collection
*/
public function getReportsByTeam(Team $team): Collection
{
return AutomatedReport::where('team_id', $team->getId())->get();
}
/**
* Get all report results for a specific report
*
* @param AutomatedReport $report
*
* @return Collection
*/
public function getResultsByReport(AutomatedReport $report): Collection
{
return $this->getResultsByReportQuery($report)->get();
}
public function getResultsByReportQuery(AutomatedReport $report): Builder
{
return AutomatedReportResult::where('report_id', $report->getId());
}
public function getReportResultsQueryForRetention(Team $team, CarbonImmutable $retentionDate): Builder
{
$reportIds = $this->getReportIdsByTeam($team);
return AutomatedReportResult::query()->whereIn('report_id', $reportIds)
->whereRaw('IFNULL(generated_at, created_at) <= ?', [$retentionDate]);
}
/**
* @param int|null $teamId Optional team ID to filter results
*
* @return \Illuminate\Support\Collection<int, int> Collection of team IDs
*/
public function getTeamIdsWithReportsResults(?int $teamId = null): \Illuminate\Support\Collection
{
$query = DB::table('automated_reports')
->join('teams', 'automated_reports.team_id', '=', 'teams.id')
->select('teams.id')
->distinct();
if ($teamId !== null) {
$query->where('teams.id', $teamId);
}
return $query->pluck('teams.id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
11162
|
|
11167
|
221
|
19
|
2026-04-14T09:17:30.588324+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158250588_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.js#11894 on JY-18909-automated-reports-ask-iminny K vProjectvToolsWindowHelp© DeviceRepository.php© ElasticActivityRepository.pl© EmailMessageRepository.p© GenericAiPromptRepositor:© GroupRepository.php(C) InboxEmailBatchRepositon)InboxRepository.php© InvitationRepository.php© JobRepository.php© LanguageRepository.php© MomentRepository.php© NotificationRepository.php© ParticipantRepository.php© ParticipantSpeechReposito© ParticipantStatsRepository© PlaybookCategoryRepositc© PlaybookRepository.php® PlaylistActivityRepository.fPlaylistRepository.phpPlaylistShareRepository.ph© QuestionRepository.php© RoleChangeEventRepositor© RoleRepository.php© SearchRepository.php© SnapshotRepository.php© SocialAccountRepository.p© StageRepository.php© SubscriptionSetRepository.TaskRepository.php© TeamAiContextRepository.TeamDomainsRepository.p©TeamInsightsRepository.pt©TeamRepository.php©ThemeRepository.php© TimezoneRepository.php© TopicRepository.php© TopicTriggerRepository.ph© TrackRepository.php© TranscriptionModelLocaleF© TranscriptionRepository.phC) TranscriptionSummarvRep© UserRepository.php© VocabularyRepository.pnp> D Rulesv D Services> [ Activity> C AjReports› D AvatarcalendarD ConferenceD Crm>MImport> MInternallv → Kioskv D AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsStTests passed: 1 (8 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console EUiconsole SlAGiNGAskJIminnykeporiAcuivilyservice.ono xActiviysearch.php© Criteria.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php(e) TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpOnDemandV2Controller.php© HistoryService.php© AskJiminnyReportActivityServiceTest.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityService1 usagepublic function __construct(private readonly ActivitySearch $activitySearch,private readonly ElasticActivityRepository $elasticRepository,private readonly LoggerInterface $logger,Df...3class Automacedkeportskepo ofA15 V4 ^ v 3959114115116117118119120/*** Retrieve all standard (non-Ask Liminny) ai 43* @param string $sortColumnThe column te 44* Oparam string $sortDirection The sort dire45*orerurn coccecclonsauromceoreooro12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Liminny reports created 55* OodrdllusernusenThe User Who: 57*oparam scrine osorclocunnThe coLomn t958* Oparam string $sortDirection The sort dire59* @return Collection<AutomatedReport>*/—6214 usages63public function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J2 usagesprivate function buildSortedQuery(string $sor_68-71/*** Get all active and enabled reports with al73* @param string $frequency* dreturh coLcectzon<aucomacedкeрort>23 usagespublic function getActiveReportsByFrequency(§g0/*** Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,xno dueconstraint is applied - matching the behaviour of getContextForAskAnythingByFilte* @return string[] Activity IDs*/14 usaeespublic function getActivityIdsForSavedSearch(Search $savedSearch,User $user,): array {$requestParams = Sthis->buildRequestParamsFromSearch($savedSearch, Suser);=ururerta.:credcerronkedvestmargee €$requestParams,['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'array_merge ($requestParams,['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'$user->getTimezone()):$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, Suser);$activityIds = $this->elasticRepository->onDemandSearchIds0nly($user, $criteria, $filte$this->logger→>info('[AskviminnyReport] Fetched activity IDs for saved search', [saved_search_id => $savedSearch->getid),'user_id' => $user->getId(),'activity_count' => count($activityIds),1):return $activityIds;1 usageprivace tunccion bunLakequestrarams-romsearch(search esaveasearch, user suser): array$params = [];$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);foreach ($savedSearch->getFilters() as $filter) {$key = $filter->getFilterPropertyO);$valve = $filter->getFilterValve();if Cin_array(Skey,haystack: self::DATE_FILTER_KEYS,strict: true)){X Reject File 0* €, 0lablf Support Daily • in 2h 43 mAAskJiminnyReportActivityServiceT….Defaults100% C•Tue 14 Apr 12:17:30CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ...again. Why is there issue with that? Where is it [EMAIL]#L44-66 should be samed to work with that. How is it used inwLet me read the OnDemandV2Controller to understand how it builds criteria there:Poad OnDemandV?ConNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php:90-93:0 phpVO\Repository\0nDemandActivitySearch\Criteria::createFromRequest(array merge($request→>allo, ('limit' = $topCount, 'paqe' = 1]).suser->geclimezoneit passes srequest→>all() - wnich Includes sequence_number Trom the URL (e.g. sequence_number=4 Trom your staging URL). so when a user nas beenpaginating on the frontend, sequence_number is naturally non-zero.The full explanationyou didn't ask for themFilterActivityburaclonkandeisFirstRequest) in Criteriareturns true when sequenceNumber === 0 . When it's the "first request" these implicit defaults kick in automatically even ifDefault on first requestman curation = minonly_recorded = 1User's own aroupEffectUrops u-secone acuvitlesOrganiserGroupInRestricts to user's arourFrontend hits /api/v1/page/on-demand?topic_id[]=..&sequence_number=4 → sequence_number=4 → isFirstRequest() = false → no implicit defaults →reuins e acuvtles,AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence_number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-only + durationz1 together matchednothing.Why sequence_number=1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionally stripped (that's existing logic in DATE_FILTER _KEYS )3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representsSetting sequence_number=1 is the minimal, correct signal: "this is not a fresh session open, don't apply page-load defaults". The criteria is otherwise builtIdentically to now the controller bullas it - same uriteria:: creater romkequest, same getondemandPagerilterset, same ondemandSearchidson ly — so theresults will now match.0 dl •Itlle wiun changesvapp/Services/Kiosk/AutomatedReports/ [ AskJiminnyReportActivityService.php +1 -1Ask anything (24L)+ <> Code Claude Sonnet 4.6Vew allliReject allAccept allWinasun leams48:4uir-o( 4 spaces...
|
NULL
|
3540713842421423582
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileEditViewNavigateCodeLaravelRefactorFV PhpStormFileEditViewNavigateCodeLaravelRefactorFV faVsco.js#11894 on JY-18909-automated-reports-ask-iminny K vProjectvToolsWindowHelp© DeviceRepository.php© ElasticActivityRepository.pl© EmailMessageRepository.p© GenericAiPromptRepositor:© GroupRepository.php(C) InboxEmailBatchRepositon)InboxRepository.php© InvitationRepository.php© JobRepository.php© LanguageRepository.php© MomentRepository.php© NotificationRepository.php© ParticipantRepository.php© ParticipantSpeechReposito© ParticipantStatsRepository© PlaybookCategoryRepositc© PlaybookRepository.php® PlaylistActivityRepository.fPlaylistRepository.phpPlaylistShareRepository.ph© QuestionRepository.php© RoleChangeEventRepositor© RoleRepository.php© SearchRepository.php© SnapshotRepository.php© SocialAccountRepository.p© StageRepository.php© SubscriptionSetRepository.TaskRepository.php© TeamAiContextRepository.TeamDomainsRepository.p©TeamInsightsRepository.pt©TeamRepository.php©ThemeRepository.php© TimezoneRepository.php© TopicRepository.php© TopicTriggerRepository.ph© TrackRepository.php© TranscriptionModelLocaleF© TranscriptionRepository.phC) TranscriptionSummarvRep© UserRepository.php© VocabularyRepository.pnp> D Rulesv D Services> [ Activity> C AjReports› D AvatarcalendarD ConferenceD Crm>MImport> MInternallv → Kioskv D AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsStTests passed: 1 (8 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console EUiconsole SlAGiNGAskJIminnykeporiAcuivilyservice.ono xActiviysearch.php© Criteria.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php(e) TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpOnDemandV2Controller.php© HistoryService.php© AskJiminnyReportActivityServiceTest.php© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityService1 usagepublic function __construct(private readonly ActivitySearch $activitySearch,private readonly ElasticActivityRepository $elasticRepository,private readonly LoggerInterface $logger,Df...3class Automacedkeportskepo ofA15 V4 ^ v 3959114115116117118119120/*** Retrieve all standard (non-Ask Liminny) ai 43* @param string $sortColumnThe column te 44* Oparam string $sortDirection The sort dire45*orerurn coccecclonsauromceoreooro12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Liminny reports created 55* OodrdllusernusenThe User Who: 57*oparam scrine osorclocunnThe coLomn t958* Oparam string $sortDirection The sort dire59* @return Collection<AutomatedReport>*/—6214 usages63public function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J2 usagesprivate function buildSortedQuery(string $sor_68-71/*** Get all active and enabled reports with al73* @param string $frequency* dreturh coLcectzon<aucomacedкeрort>23 usagespublic function getActiveReportsByFrequency(§g0/*** Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,xno dueconstraint is applied - matching the behaviour of getContextForAskAnythingByFilte* @return string[] Activity IDs*/14 usaeespublic function getActivityIdsForSavedSearch(Search $savedSearch,User $user,): array {$requestParams = Sthis->buildRequestParamsFromSearch($savedSearch, Suser);=ururerta.:credcerronkedvestmargee €$requestParams,['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'array_merge ($requestParams,['limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'$user->getTimezone()):$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, Suser);$activityIds = $this->elasticRepository->onDemandSearchIds0nly($user, $criteria, $filte$this->logger→>info('[AskviminnyReport] Fetched activity IDs for saved search', [saved_search_id => $savedSearch->getid),'user_id' => $user->getId(),'activity_count' => count($activityIds),1):return $activityIds;1 usageprivace tunccion bunLakequestrarams-romsearch(search esaveasearch, user suser): array$params = [];$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);foreach ($savedSearch->getFilters() as $filter) {$key = $filter->getFilterPropertyO);$valve = $filter->getFilterValve();if Cin_array(Skey,haystack: self::DATE_FILTER_KEYS,strict: true)){X Reject File 0* €, 0lablf Support Daily • in 2h 43 mAAskJiminnyReportActivityServiceT….Defaults100% C•Tue 14 Apr 12:17:30CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ...again. Why is there issue with that? Where is it [EMAIL]#L44-66 should be samed to work with that. How is it used inwLet me read the OnDemandV2Controller to understand how it builds criteria there:Poad OnDemandV?ConNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php:90-93:0 phpVO\Repository\0nDemandActivitySearch\Criteria::createFromRequest(array merge($request→>allo, ('limit' = $topCount, 'paqe' = 1]).suser->geclimezoneit passes srequest→>all() - wnich Includes sequence_number Trom the URL (e.g. sequence_number=4 Trom your staging URL). so when a user nas beenpaginating on the frontend, sequence_number is naturally non-zero.The full explanationyou didn't ask for themFilterActivityburaclonkandeisFirstRequest) in Criteriareturns true when sequenceNumber === 0 . When it's the "first request" these implicit defaults kick in automatically even ifDefault on first requestman curation = minonly_recorded = 1User's own aroupEffectUrops u-secone acuvitlesOrganiserGroupInRestricts to user's arourFrontend hits /api/v1/page/on-demand?topic_id[]=..&sequence_number=4 → sequence_number=4 → isFirstRequest() = false → no implicit defaults →reuins e acuvtles,AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence_number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-only + durationz1 together matchednothing.Why sequence_number=1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionally stripped (that's existing logic in DATE_FILTER _KEYS )3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representsSetting sequence_number=1 is the minimal, correct signal: "this is not a fresh session open, don't apply page-load defaults". The criteria is otherwise builtIdentically to now the controller bullas it - same uriteria:: creater romkequest, same getondemandPagerilterset, same ondemandSearchidson ly — so theresults will now match.0 dl •Itlle wiun changesvapp/Services/Kiosk/AutomatedReports/ [ AskJiminnyReportActivityService.php +1 -1Ask anything (24L)+ <> Code Claude Sonnet 4.6Vew allliReject allAccept allWinasun leams48:4uir-o( 4 spaces...
|
NULL
|
|
11169
|
221
|
20
|
2026-04-14T09:17:35.765798+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158255765_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditFV faVsco.jsProjectvViewNavigateCo PhpStormFileEditFV faVsco.jsProjectvViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© DeviceRepository.php© ElasticActivityRepository.pl© EmailMessageRepository.p© GenericAiPromptRepositor:© GroupRepository.php(C) InboxEmailBatchRepositon)InboxRepository.php© InvitationRepository.php© JobRepository.php© LanguageRepository.php© MomentRepository.php© NotificationRepository.php© ParticipantRepository.php© ParticipantSpeechReposito© ParticipantStatsRepository© PlaybookCategoryRepositc© PlaybookRepository.php® PlaylistActivityRepository.fPlaylistRepository.phpPlaylistShareRepository.ph© QuestionRepository.php© RoleChangeEventRepositor© RoleRepository.php© SearchRepository.php© SnapshotRepository.php© SocialAccountRepository.p© StageRepository.php© SubscriptionSetRepository.TaskRepository.php© TeamAiContextRepository.TeamDomainsRepository.p©TeamInsightsRepository.pt©TeamRepository.php©ThemeRepository.php© TimezoneRepository.php© TopicRepository.php© TopicTriggerRepository.ph© TrackRepository.php© TranscriptionModelLocaleF© TranscriptionRepository.phC) TranscriptionSummarvRep© UserRepository.php© VocabularyRepository.pnp> D Rulesv D Services> [ Activity> C AjReports› D AvatarcalendarD ConferenceD Crm>MImport> MInternallv → Kioskv D AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsStTests passed: 1 (8 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console EUiconsole SlAGiNGASkJiminnykeportAcuivilyservice.ono xActiviysearch.php© Criteria.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php© HistoryService.php© AskJiminnyReportActivityServiceTest.phpclass AskJiminnyReportActivityService© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.php(e TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedkeportskepo ofA15 V4 A V59114115116117118119120/*** Retrieve all standard (non-Ask Jiminny) M* @param string $sortColumnThe column t< 45* Cparam string ssortDirection The sort dir 46*orerurn coccectlonsauromcreoreooro12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Liminny reports created A55-56* OodrdllusernusenIne User Who: 57*oparam scrine osorclocunnIne coLumn c458* @param string $sortDirection The sort dire59* @return Collection<AutomatedReport>*/14 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J—622 usages/**private function buildSortedQuery(string $sor7e_71* Get all active and enabled reports with ac 73* @param string $frequency—76* dreturn cocLectron<Aucomacedкeрort»23 usagespublic function getActiveReportsByFrequency(s 80public function__construct(private readonly ActivitySearch SactivitySearch,private readonly ElasticActivityRepository $elasticRepository,private readonly LoggerInterface $logger,) 1..3* Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,* no date constraint is applied - matching the behaviour of getContextForAskAnythingByFilte* Creturn string[] Activity IDs14 usagespubuic tunccion getAcuivity.asrorsavedsearchcSearch $savedSearch,user puser): array €$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);$criteria = Criteria::createFromRequest(AccepuRenectsrequescrarams, L'Limit => seLt.:DEFAULI_TUP_ACTIVIllES_CUUnl, "page"array_merge (SrequestParams,I'Limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'user-›deta nezone u&T to Cascade.mmurerer - vus-raco utyoearciepoerunuenanorader urerser ncrremar suser.$activityIds = $this->elasticRepository->onDemandSearchIds0nly($user, $criteria, $filter$this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', ['saved_search_id' => $savedSearch->getId(),'user_id' => $user->getId(),'activity_count' => count($activityIds),return sactvitvlos.Tusageprivate function buildRequestParamsFromSearch(Search $savedSearch, User $user): array$params = []:$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);foreach ($savedSearch->getFilters() as $filter) €$key = $filter->getFilterPropertyO;$valve = $filter->getFilterValueO;if (in_array($key,haystack: self::DATE_FILTER_KEYS,strict: true))continue,X Reject File 0* €, 0lablf Support Daily • in 2h 43 mAAskJiminnyReportActivityServiceT….Defaults100% C•Tue 14 Apr 12:17:35CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..again. Why is there issue with that? Where is it ed to work with that. How is it used inCAskJ1minyReportActivityService. phpL44-66 should be sameed on savedSearch. THe ids in on demand and inLet me read the OnDemandV2Controller to understand how it builds criteria there:Poad OnDemandV?ConwNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php:90-93:0 phpVO\Repository\0nDemandActivitySearch\Criteria::createFromRequest(array merge($request→>allo, ('limit' = $topCount, 'paqe' = 1]).suser->geclimezoneit passes srequest→>all() - wnich Includes sequence_number Trom the URL (e.g. sequence_number=4 Trom your staging URL). so when a user nas beenpaginating on the frontend, sequence_number is naturally non-zero.The full explanationyou didn't ask for themFilterActivityburaclonkandeisFirstRequest) in Criteriareturns true when sequenceNumber === 0 . When it's the "first request" these implicit defaults kick in automatically even ifActuvltvkecordecOrganiserGroupInDefault on first requestman curation = minonly_recorded = 1User's own aroupEffectUrops u-secone acuvitlesRecorded activities onvRestricts to user's arourFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest() = false → no implicit defaults →reuins e acuvtles,AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence_number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-only + durationz1 together matchednothing.Why sequence_number=1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionally stripped (that's existing logic in DATE_FILTER _KEYS )3. Aoding imolicit min duration only recorded, ano arouo scone on ton wou d contradict what the saveo search representsSetting sequence_number=1 is the minimal, correct signal: "this is not a fresh session open, don't apply page-load defaults". The criteria is otherwise builtIdentically to now the controller bullas it - same uriteria:: creater romkequest, same getonDemandPagefilterset, same ondemandsearchidsonly — so theresults will now match.0 dl •Itlle wiun changesvapp/Services/Kiosk/AutomatedReports/ [ AskJiminnyReportActivityService.php +1 -1Ask anything (2*L)+ <> CodeClaude Sonnet 4.6Vew allliReject allAccept allwinasun leams54:1uir-o( 4 spaces...
|
NULL
|
8292899655258257894
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileEditFV faVsco.jsProjectvViewNavigateCo PhpStormFileEditFV faVsco.jsProjectvViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© DeviceRepository.php© ElasticActivityRepository.pl© EmailMessageRepository.p© GenericAiPromptRepositor:© GroupRepository.php(C) InboxEmailBatchRepositon)InboxRepository.php© InvitationRepository.php© JobRepository.php© LanguageRepository.php© MomentRepository.php© NotificationRepository.php© ParticipantRepository.php© ParticipantSpeechReposito© ParticipantStatsRepository© PlaybookCategoryRepositc© PlaybookRepository.php® PlaylistActivityRepository.fPlaylistRepository.phpPlaylistShareRepository.ph© QuestionRepository.php© RoleChangeEventRepositor© RoleRepository.php© SearchRepository.php© SnapshotRepository.php© SocialAccountRepository.p© StageRepository.php© SubscriptionSetRepository.TaskRepository.php© TeamAiContextRepository.TeamDomainsRepository.p©TeamInsightsRepository.pt©TeamRepository.php©ThemeRepository.php© TimezoneRepository.php© TopicRepository.php© TopicTriggerRepository.ph© TrackRepository.php© TranscriptionModelLocaleF© TranscriptionRepository.phC) TranscriptionSummarvRep© UserRepository.php© VocabularyRepository.pnp> D Rulesv D Services> [ Activity> C AjReports› D AvatarcalendarD ConferenceD Crm>MImport> MInternallv → Kioskv D AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsStTests passed: 1 (8 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console EUiconsole SlAGiNGASkJiminnykeportAcuivilyservice.ono xActiviysearch.php© Criteria.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php© HistoryService.php© AskJiminnyReportActivityServiceTest.phpclass AskJiminnyReportActivityService© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.php(e TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedkeportskepo ofA15 V4 A V59114115116117118119120/*** Retrieve all standard (non-Ask Jiminny) M* @param string $sortColumnThe column t< 45* Cparam string ssortDirection The sort dir 46*orerurn coccectlonsauromcreoreooro12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Liminny reports created A55-56* OodrdllusernusenIne User Who: 57*oparam scrine osorclocunnIne coLumn c458* @param string $sortDirection The sort dire59* @return Collection<AutomatedReport>*/14 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J—622 usages/**private function buildSortedQuery(string $sor7e_71* Get all active and enabled reports with ac 73* @param string $frequency—76* dreturn cocLectron<Aucomacedкeрort»23 usagespublic function getActiveReportsByFrequency(s 80public function__construct(private readonly ActivitySearch SactivitySearch,private readonly ElasticActivityRepository $elasticRepository,private readonly LoggerInterface $logger,) 1..3* Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,* no date constraint is applied - matching the behaviour of getContextForAskAnythingByFilte* Creturn string[] Activity IDs14 usagespubuic tunccion getAcuivity.asrorsavedsearchcSearch $savedSearch,user puser): array €$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);$criteria = Criteria::createFromRequest(AccepuRenectsrequescrarams, L'Limit => seLt.:DEFAULI_TUP_ACTIVIllES_CUUnl, "page"array_merge (SrequestParams,I'Limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT, 'page'user-›deta nezone u&T to Cascade.mmurerer - vus-raco utyoearciepoerunuenanorader urerser ncrremar suser.$activityIds = $this->elasticRepository->onDemandSearchIds0nly($user, $criteria, $filter$this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', ['saved_search_id' => $savedSearch->getId(),'user_id' => $user->getId(),'activity_count' => count($activityIds),return sactvitvlos.Tusageprivate function buildRequestParamsFromSearch(Search $savedSearch, User $user): array$params = []:$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);foreach ($savedSearch->getFilters() as $filter) €$key = $filter->getFilterPropertyO;$valve = $filter->getFilterValueO;if (in_array($key,haystack: self::DATE_FILTER_KEYS,strict: true))continue,X Reject File 0* €, 0lablf Support Daily • in 2h 43 mAAskJiminnyReportActivityServiceT….Defaults100% C•Tue 14 Apr 12:17:35CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..again. Why is there issue with that? Where is it ed to work with that. How is it used inCAskJ1minyReportActivityService. phpL44-66 should be sameed on savedSearch. THe ids in on demand and inLet me read the OnDemandV2Controller to understand how it builds criteria there:Poad OnDemandV?ConwNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php:90-93:0 phpVO\Repository\0nDemandActivitySearch\Criteria::createFromRequest(array merge($request→>allo, ('limit' = $topCount, 'paqe' = 1]).suser->geclimezoneit passes srequest→>all() - wnich Includes sequence_number Trom the URL (e.g. sequence_number=4 Trom your staging URL). so when a user nas beenpaginating on the frontend, sequence_number is naturally non-zero.The full explanationyou didn't ask for themFilterActivityburaclonkandeisFirstRequest) in Criteriareturns true when sequenceNumber === 0 . When it's the "first request" these implicit defaults kick in automatically even ifActuvltvkecordecOrganiserGroupInDefault on first requestman curation = minonly_recorded = 1User's own aroupEffectUrops u-secone acuvitlesRecorded activities onvRestricts to user's arourFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest() = false → no implicit defaults →reuins e acuvtles,AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence_number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-only + durationz1 together matchednothing.Why sequence_number=1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionally stripped (that's existing logic in DATE_FILTER _KEYS )3. Aoding imolicit min duration only recorded, ano arouo scone on ton wou d contradict what the saveo search representsSetting sequence_number=1 is the minimal, correct signal: "this is not a fresh session open, don't apply page-load defaults". The criteria is otherwise builtIdentically to now the controller bullas it - same uriteria:: creater romkequest, same getonDemandPagefilterset, same ondemandsearchidsonly — so theresults will now match.0 dl •Itlle wiun changesvapp/Services/Kiosk/AutomatedReports/ [ AskJiminnyReportActivityService.php +1 -1Ask anything (2*L)+ <> CodeClaude Sonnet 4.6Vew allliReject allAccept allwinasun leams54:1uir-o( 4 spaces...
|
11167
|
|
11171
|
221
|
21
|
2026-04-14T09:17:40.117285+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158260117_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditFV faVsco.jsProjectvViewNavigateCo PhpStormFileEditFV faVsco.jsProjectvViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© DeviceRepository.php© ElasticActivityRepository.pl© EmailMessageRepository.p© GenericAiPromptRepositor:© GroupRepository.php(C) InboxEmailBatchRepositor)InboxRepository.php© InvitationRepository.php© JobRepository.php© LanguageRepository.php© MomentRepository.php© NotificationRepository.php© ParticipantRepository.php© ParticipantSpeechReposito© ParticipantStatsRepository© PlaybookCategoryRepositc© PlaybookRepository.php® PlaylistActivityRepository.fPlaylistRepository.phpPlaylistShareRepository.ph© QuestionRepository.php© RoleChangeEventRepositor© RoleRepository.php© SearchRepository.php© SnapshotRepository.php© SocialAccountRepository.p© StageRepository.php© SubscriptionSetRepository.TaskRepository.php© TeamAiContextRepository.TeamDomainsRepository.p©TeamInsightsRepository.pt©TeamRepository.php©ThemeRepository.php© TimezoneRepository.php© TopicRepository.php© TopicTriggerRepository.ph© TrackRepository.php© TranscriptionModelLocaleF© TranscriptionRepository.phC) TranscriptionSummarvRep© UserRepository.php© VocabularyRepository.pnp› D Rulesv D Services> [ Activity> D AjReports› D AvatarcalendarD ConferenceD Crm>MImport> MInternallv → Kioskv D AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsStTests passed: 1 (8 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console LUlconsole SlAGiNGASkJiminnykeportAcuivilyservice.ono xActiviysearch.php© Criteria.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php© OnDemandV2Controller.php© HistoryService.php© AskJiminnyReportActivityServiceTest.phpclass AskJiminnyReportActivityService© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.php(e) TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedkeportskepo ofA15 X4AV59114115116117118119120/*** Retrieve all standard (non-Ask Jiminny) M* @param string $sortColumnThe column t< 45* Cparam string ssortDirection The sort dir 46*orerurn coccecclonsauromceoreooro12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Liminny reports created A55-56* Oodrdll usernusenIne User Who: 57* @param string $sortColumnThe column t( 58* @param string $sortDirection The sort dire59* @return Collection<AutomatedReport>*/14 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J—622 usages/**private function buildSortedQuery(string $sor7e_71* Get all active and enabled reports with ac73* @param string $frequency—76* dreturh coLcectzon<aucomacedкeрort>23 usagespublic function getActiveReportsByFrequency(s 80public function__construct(private readonly ActivitySearch SactivitySearch,private readonly ElasticActivityRepository $elasticRepository,private readonly LoggerInterface $logger,) 1..3* Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,* no date constraint is applied - matching the behaviour of getContextForAskAnythingByFilte* Creturn string[] Activity IDs*/14 usagespubuic tunccion getAcuivity.asrorsavedsearchcSearch $savedSearch,user puser): array €$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);$criteria = Criteria::createFromRequest(array_mergelsrequescrarams, L'LImit = seLT:.DEFAULI_TUP_ALTIL- Accept Rejedge'array_merge (SrequestParams, [l'limit'F> self::DEFAULT_TOP_ACTIVITIES_CoUNT, 'page'1, 'sequence_number"nuser->cerznezoneu);$filterSet = $this->activitySearch->get0nDemandPageFilterSet($criteria, $user);$activityIds = $this-›elasticRepository->onDemandSearchIds0nly($user, $criteria, $filter$this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search'. ['saved_search_id' => $savedSearch->getId(),'user_id' => Suser-›getid(),'accivity_count => count(paccivitylas),return sacurylos1 usageprivate function buildRequestParamsFromSearch(Search $savedSearch, User $user): array$params = []:$arrayFilterKeys = $this-›activitySearch->getArrayFilterKeys(Suser);foreach ($savedSearch->getFilters() as $filter) €$key = $filter->getFilterPropertyO;$valve = $filter->getFilterValueO;if (in_array($key,coneanue.SELT..DAIC PILICK KCYSstrict: true)){X Reject File 0* €, 0lablf Support Daily • in 2h 43 mAAskJiminnyReportActivityServiceT….Defaults100% C•Tue 14 Apr 12:17:39CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..again. Why is there issue with that? Where is it ed to work with that. How is it used inCAskJ1minyReportActivityService. phpL44-66 should be sameed on savedSearch. THe ids in on demand and inLet me read the OnDemandV2Controller to understand how it builds criteria there:Poad OnDemandV?ConwNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php:90-93:0 phpVO\Repository\0nDemandActivitySearch\Criteria::createFromRequest(array merge($request→>allo, ('limit' = $topCount, 'paqe' = 1]).suser->geclimezoneit passes srequest→>all() - wnich Includes sequence_number Trom the URL (e.g. sequence_number=4 Trom your staging URL). so when a user nas beenpaginating on the frontend, sequence_number is naturally non-zero.The full explanationyou didn't ask for themFilterActivityburaclonkandeisFirstRequest in Criteria returns true when sequenceNumber === 0 . When it's the "first request" these implicit defaults kick in automatically even ifActuvltvkecordecOrganiserGroupInDefault on first requestman curation = minonly_recorded = 1User's own aroupEffectUrops u-secone acuvitlesRestricts to user's arourFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest() = false → no implicit defaults →reuins e acuvtles,AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence_number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-only + durationz1 together matchednothing.Why sequence_number=1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionally stripped (that's existing logic in DATE_FILTER _KEYS )3. Aoding imolicit min duration only recorded, ano arouo scone on ton wou d contradict what the saveo search representsSetting sequence_number=1 is the minimal, correct signal: "this is not a fresh session open, don't apply page-load defaults". The criteria is otherwise builtIdentically to now the controller bullas it - same uriteria:: creater romkequest, same getonDemandPagefilterset, same ondemandsearchidsonly — so theresults will now match.0 dl •Itlle wiun changesvapp/Services/Kiosk/AutomatedReports/ [ AskJiminnyReportActivityService.php +2 -1Ask anything (2*L)+ <> CodeClaude Sonnet 4.6Vew allliReject allAccept allwinasun leams52:14uir-o( 4 spaces...
|
NULL
|
5309593290486198007
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileEditFV faVsco.jsProjectvViewNavigateCo PhpStormFileEditFV faVsco.jsProjectvViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© DeviceRepository.php© ElasticActivityRepository.pl© EmailMessageRepository.p© GenericAiPromptRepositor:© GroupRepository.php(C) InboxEmailBatchRepositor)InboxRepository.php© InvitationRepository.php© JobRepository.php© LanguageRepository.php© MomentRepository.php© NotificationRepository.php© ParticipantRepository.php© ParticipantSpeechReposito© ParticipantStatsRepository© PlaybookCategoryRepositc© PlaybookRepository.php® PlaylistActivityRepository.fPlaylistRepository.phpPlaylistShareRepository.ph© QuestionRepository.php© RoleChangeEventRepositor© RoleRepository.php© SearchRepository.php© SnapshotRepository.php© SocialAccountRepository.p© StageRepository.php© SubscriptionSetRepository.TaskRepository.php© TeamAiContextRepository.TeamDomainsRepository.p©TeamInsightsRepository.pt©TeamRepository.php©ThemeRepository.php© TimezoneRepository.php© TopicRepository.php© TopicTriggerRepository.ph© TrackRepository.php© TranscriptionModelLocaleF© TranscriptionRepository.phC) TranscriptionSummarvRep© UserRepository.php© VocabularyRepository.pnp› D Rulesv D Services> [ Activity> D AjReports› D AvatarcalendarD ConferenceD Crm>MImport> MInternallv → Kioskv D AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsStTests passed: 1 (8 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console LUlconsole SlAGiNGASkJiminnykeportAcuivilyservice.ono xActiviysearch.php© Criteria.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php© OnDemandV2Controller.php© HistoryService.php© AskJiminnyReportActivityServiceTest.phpclass AskJiminnyReportActivityService© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.php(e) TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedkeportskepo ofA15 X4AV59114115116117118119120/*** Retrieve all standard (non-Ask Jiminny) M* @param string $sortColumnThe column t< 45* Cparam string ssortDirection The sort dir 46*orerurn coccecclonsauromceoreooro12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Liminny reports created A55-56* Oodrdll usernusenIne User Who: 57* @param string $sortColumnThe column t( 58* @param string $sortDirection The sort dire59* @return Collection<AutomatedReport>*/14 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J—622 usages/**private function buildSortedQuery(string $sor7e_71* Get all active and enabled reports with ac73* @param string $frequency—76* dreturh coLcectzon<aucomacedкeрort>23 usagespublic function getActiveReportsByFrequency(s 80public function__construct(private readonly ActivitySearch SactivitySearch,private readonly ElasticActivityRepository $elasticRepository,private readonly LoggerInterface $logger,) 1..3* Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,* no date constraint is applied - matching the behaviour of getContextForAskAnythingByFilte* Creturn string[] Activity IDs*/14 usagespubuic tunccion getAcuivity.asrorsavedsearchcSearch $savedSearch,user puser): array €$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);$criteria = Criteria::createFromRequest(array_mergelsrequescrarams, L'LImit = seLT:.DEFAULI_TUP_ALTIL- Accept Rejedge'array_merge (SrequestParams, [l'limit'F> self::DEFAULT_TOP_ACTIVITIES_CoUNT, 'page'1, 'sequence_number"nuser->cerznezoneu);$filterSet = $this->activitySearch->get0nDemandPageFilterSet($criteria, $user);$activityIds = $this-›elasticRepository->onDemandSearchIds0nly($user, $criteria, $filter$this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search'. ['saved_search_id' => $savedSearch->getId(),'user_id' => Suser-›getid(),'accivity_count => count(paccivitylas),return sacurylos1 usageprivate function buildRequestParamsFromSearch(Search $savedSearch, User $user): array$params = []:$arrayFilterKeys = $this-›activitySearch->getArrayFilterKeys(Suser);foreach ($savedSearch->getFilters() as $filter) €$key = $filter->getFilterPropertyO;$valve = $filter->getFilterValueO;if (in_array($key,coneanue.SELT..DAIC PILICK KCYSstrict: true)){X Reject File 0* €, 0lablf Support Daily • in 2h 43 mAAskJiminnyReportActivityServiceT….Defaults100% C•Tue 14 Apr 12:17:39CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..again. Why is there issue with that? Where is it ed to work with that. How is it used inCAskJ1minyReportActivityService. phpL44-66 should be sameed on savedSearch. THe ids in on demand and inLet me read the OnDemandV2Controller to understand how it builds criteria there:Poad OnDemandV?ConwNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php:90-93:0 phpVO\Repository\0nDemandActivitySearch\Criteria::createFromRequest(array merge($request→>allo, ('limit' = $topCount, 'paqe' = 1]).suser->geclimezoneit passes srequest→>all() - wnich Includes sequence_number Trom the URL (e.g. sequence_number=4 Trom your staging URL). so when a user nas beenpaginating on the frontend, sequence_number is naturally non-zero.The full explanationyou didn't ask for themFilterActivityburaclonkandeisFirstRequest in Criteria returns true when sequenceNumber === 0 . When it's the "first request" these implicit defaults kick in automatically even ifActuvltvkecordecOrganiserGroupInDefault on first requestman curation = minonly_recorded = 1User's own aroupEffectUrops u-secone acuvitlesRestricts to user's arourFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest() = false → no implicit defaults →reuins e acuvtles,AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence_number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-only + durationz1 together matchednothing.Why sequence_number=1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionally stripped (that's existing logic in DATE_FILTER _KEYS )3. Aoding imolicit min duration only recorded, ano arouo scone on ton wou d contradict what the saveo search representsSetting sequence_number=1 is the minimal, correct signal: "this is not a fresh session open, don't apply page-load defaults". The criteria is otherwise builtIdentically to now the controller bullas it - same uriteria:: creater romkequest, same getonDemandPagefilterset, same ondemandsearchidsonly — so theresults will now match.0 dl •Itlle wiun changesvapp/Services/Kiosk/AutomatedReports/ [ AskJiminnyReportActivityService.php +2 -1Ask anything (2*L)+ <> CodeClaude Sonnet 4.6Vew allliReject allAccept allwinasun leams52:14uir-o( 4 spaces...
|
NULL
|
|
11173
|
221
|
22
|
2026-04-14T09:17:43.860259+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158263860_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditFV faVsco.jsProjectvViewNavigateCo PhpStormFileEditFV faVsco.jsProjectvViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© DeviceRepository.php© ElasticActivityRepository.pl© EmailMessageRepository.p© GenericAiPromptRepositor:© GroupRepository.php(C) InboxEmailBatchRepositon)C InboxRepository.pnp© InvitationRepository.php© JobRepository.php© LanguageRepository.php© MomentRepository.php© NotificationRepository.php© ParticipantRepository.php© ParticipantSpeechReposito© ParticipantStatsRepository© PlaybookCategoryRepositc© PlaybookRepository.php® PlaylistActivityRepository.fPlaylistRepository.phpPlaylistShareRepository.ph© QuestionRepository.php© RoleChangeEventRepositor© RoleRepository.php© SearchRepository.php© SnapshotRepository.php© SocialAccountRepository.p© StageRepository.php© SubscriptionSetRepository.TaskRepository.php© TeamAiContextRepository.TeamDomainsRepository.p©TeamInsightsRepository.pt©TeamRepository.php©ThemeRepository.php© TimezoneRepository.php© TopicRepository.php© TopicTriggerRepository.ph© TrackRepository.php© TranscriptionModelLocaleF© TranscriptionRepository.phC) TranscriptionSummarvRep© UserRepository.php© VocabularyRepository.pnp> D Rulesv D Services> [ Activity> C AjReports(J AvatarcalendarD ConferenceD Crm>MImport> MInternallv → Kioskv D AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsStTests passed: 1 (8 minutes ago)© ReportController.php© AutomatedReportsCommand.php© JiminnyDebugCommand.php= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console LUlconsole SlAGiNGAskJiminnykeporAcuivilyservice.ong xActiviysearch.php© Criteria.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php© HistoryService.php© AskJiminnyReportActivityServiceTest.phpclass AskJiminnyReportActivityService© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.php© TrackProviderInstalledEvent.php© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedkeportskepo ofA15 V4 A V59114115116117118119120/*** Retrieve all standard (non-Ask Jiminny) M* @param string $sortColumnThe column t< 45* Cparam string ssortDirection The sort dir 46*orerurn coccectonsauromareonedor12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Liminny reports created A55-56* OodrdllusernusenIne User Who: 57* @param string $sortColumnIne coLumn c458* @param string $sortDirection The sort dire59* @return Collection<AutomatedReport>*/14 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = 'desc"): Collection {...J—622 usages/**private function buildSortedQuery(string $sor7e_71* Get all active and enabled reports with ac73* @param string $frequency* dreturn cocLectron<Aucomacedкeрort»23 usagespublic function getActiveReportsByFrequency(£ 80public function__construct(private readonly ActivitySearch SactivitySearch,private readonly ElasticActivityRepository $elasticRepository,private readonly LoggerInterface $logger,) 1..3* Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,* no date constraint is applied - matching the behaviour of getContextForAskAnythingByFilte* Creturn string[] Activity IDs*/14 usagespubuic tunccion getAcuivity.asrorsavedsearchcSearch $savedSearch,user puser,): array €$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);$criteria = Criteria::createFromRequest(array_merge ($requestParams, l'limit' => self::DEFAULT_TOP_ACTIVIT] Accept TRejeage'array_merge (SrequestParams,=> self::DEFAULT_TOP_ACTIVITIES_COUNT,|I'page' => 1.'sequence_number' => 11),nuser-poernezone);$filterSet = $this->activitySearch->get0nDemandPageFilterSet($criteria, $user);$activityIds = $this->elasticRepository->onDemandSearchIds0nly($user, $criteria, $filter$this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search'. ['saved_search_id' => $savedSearch->getId(),'user_id' => Suser-›getid(),'activity_count' => count($activityIds),return $activityIds;lusaeeprivate function buildRequestParamsFromSearch(Search $savedSearch, User $user): array$params = [];$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);foreach ($savedSearch->getFilters() as $filter) €nkey =nurer-poerrurerropery.or$valve = $filter->getFilterValueO;if Cin_array(Skey,continte;nayslacaSeRLLICA ALTOstrict: true)){, 0lablf Support Daily • in 2h 43 mAAskJiminnyReportActivityServiceT….Defaults100% C•Tue 14 Apr 12:17:43CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..again. Why is there issue with that? Where is it ed to work with that. How is it used inCAskJ1minyReportActivityService. phpL44-66 should be sameed on savedSearch. THe ids in on demand and inLet me read the OnDemandV2Controller to understand how it builds criteria there:Poad OnDemandV?ConwNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php:90-93:0 phpVO\Repository\0nDemandActivitySearch\Criteria::createFromRequest(array merge($request→>allo, ('limit' = $topCount, 'paqe' = 11)suser->geclimezoneit passes srequest→>all() - wnich Includes sequence_number Trom the URL (e.g. sequence_number=4 Trom your staging URL). so when a user nas beenpaginating on the frontend, sequence_number is naturally non-zero.The full explanationyou didn't ask for themFilterActivityburaclonkandeisFirstRequest) in Criteriareturns true when sequenceNumber === 0 . When it's the "first request" these implicit defaults kick in automatically even ifOrganiserGroupInDefault on first requestman curation = minonly_recorded = 1User's own aroupEffectUrops u-secone acuvitlesRestricts to user's arourFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest() = false → no implicit defaults →reuins e acuvtles,AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence_number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-only + duration≥1 together matchednothing.Why sequence_number=1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionally stripped (that's existing logic in DATE_FILTER _KEYS )3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representsSetting sequence_number=1 is the minimal, correct signal: "this is not a fresh session open, don't apply page-load defaults". The criteria is otherwise builtIdentically to now the controller bullas it - same uriteria:: creater romkequest, same getondemandPagerilterset, same ondemandSearchidson ly — so theresults will now match.0 dl •Itlle wiun changesvapp/Services/Kiosk/AutomatedReports/ [ AskJiminnyReportActivityService.php +3 -1Ask anything (2*L)+ <> CodeClaude Sonnet 4.6Vew allliReject allAccept allwinasun leams53:11uir-o( 4 spaces...
|
NULL
|
-244575004258272944
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileEditFV faVsco.jsProjectvViewNavigateCo PhpStormFileEditFV faVsco.jsProjectvViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© DeviceRepository.php© ElasticActivityRepository.pl© EmailMessageRepository.p© GenericAiPromptRepositor:© GroupRepository.php(C) InboxEmailBatchRepositon)C InboxRepository.pnp© InvitationRepository.php© JobRepository.php© LanguageRepository.php© MomentRepository.php© NotificationRepository.php© ParticipantRepository.php© ParticipantSpeechReposito© ParticipantStatsRepository© PlaybookCategoryRepositc© PlaybookRepository.php® PlaylistActivityRepository.fPlaylistRepository.phpPlaylistShareRepository.ph© QuestionRepository.php© RoleChangeEventRepositor© RoleRepository.php© SearchRepository.php© SnapshotRepository.php© SocialAccountRepository.p© StageRepository.php© SubscriptionSetRepository.TaskRepository.php© TeamAiContextRepository.TeamDomainsRepository.p©TeamInsightsRepository.pt©TeamRepository.php©ThemeRepository.php© TimezoneRepository.php© TopicRepository.php© TopicTriggerRepository.ph© TrackRepository.php© TranscriptionModelLocaleF© TranscriptionRepository.phC) TranscriptionSummarvRep© UserRepository.php© VocabularyRepository.pnp> D Rulesv D Services> [ Activity> C AjReports(J AvatarcalendarD ConferenceD Crm>MImport> MInternallv → Kioskv D AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsStTests passed: 1 (8 minutes ago)© ReportController.php© AutomatedReportsCommand.php© JiminnyDebugCommand.php= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console LUlconsole SlAGiNGAskJiminnykeporAcuivilyservice.ong xActiviysearch.php© Criteria.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php© HistoryService.php© AskJiminnyReportActivityServiceTest.phpclass AskJiminnyReportActivityService© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.php© TrackProviderInstalledEvent.php© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedkeportskepo ofA15 V4 A V59114115116117118119120/*** Retrieve all standard (non-Ask Jiminny) M* @param string $sortColumnThe column t< 45* Cparam string ssortDirection The sort dir 46*orerurn coccectonsauromareonedor12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Liminny reports created A55-56* OodrdllusernusenIne User Who: 57* @param string $sortColumnIne coLumn c458* @param string $sortDirection The sort dire59* @return Collection<AutomatedReport>*/14 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = 'desc"): Collection {...J—622 usages/**private function buildSortedQuery(string $sor7e_71* Get all active and enabled reports with ac73* @param string $frequency* dreturn cocLectron<Aucomacedкeрort»23 usagespublic function getActiveReportsByFrequency(£ 80public function__construct(private readonly ActivitySearch SactivitySearch,private readonly ElasticActivityRepository $elasticRepository,private readonly LoggerInterface $logger,) 1..3* Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,* no date constraint is applied - matching the behaviour of getContextForAskAnythingByFilte* Creturn string[] Activity IDs*/14 usagespubuic tunccion getAcuivity.asrorsavedsearchcSearch $savedSearch,user puser,): array €$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);$criteria = Criteria::createFromRequest(array_merge ($requestParams, l'limit' => self::DEFAULT_TOP_ACTIVIT] Accept TRejeage'array_merge (SrequestParams,=> self::DEFAULT_TOP_ACTIVITIES_COUNT,|I'page' => 1.'sequence_number' => 11),nuser-poernezone);$filterSet = $this->activitySearch->get0nDemandPageFilterSet($criteria, $user);$activityIds = $this->elasticRepository->onDemandSearchIds0nly($user, $criteria, $filter$this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search'. ['saved_search_id' => $savedSearch->getId(),'user_id' => Suser-›getid(),'activity_count' => count($activityIds),return $activityIds;lusaeeprivate function buildRequestParamsFromSearch(Search $savedSearch, User $user): array$params = [];$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);foreach ($savedSearch->getFilters() as $filter) €nkey =nurer-poerrurerropery.or$valve = $filter->getFilterValueO;if Cin_array(Skey,continte;nayslacaSeRLLICA ALTOstrict: true)){, 0lablf Support Daily • in 2h 43 mAAskJiminnyReportActivityServiceT….Defaults100% C•Tue 14 Apr 12:17:43CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..again. Why is there issue with that? Where is it ed to work with that. How is it used inCAskJ1minyReportActivityService. phpL44-66 should be sameed on savedSearch. THe ids in on demand and inLet me read the OnDemandV2Controller to understand how it builds criteria there:Poad OnDemandV?ConwNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php:90-93:0 phpVO\Repository\0nDemandActivitySearch\Criteria::createFromRequest(array merge($request→>allo, ('limit' = $topCount, 'paqe' = 11)suser->geclimezoneit passes srequest→>all() - wnich Includes sequence_number Trom the URL (e.g. sequence_number=4 Trom your staging URL). so when a user nas beenpaginating on the frontend, sequence_number is naturally non-zero.The full explanationyou didn't ask for themFilterActivityburaclonkandeisFirstRequest) in Criteriareturns true when sequenceNumber === 0 . When it's the "first request" these implicit defaults kick in automatically even ifOrganiserGroupInDefault on first requestman curation = minonly_recorded = 1User's own aroupEffectUrops u-secone acuvitlesRestricts to user's arourFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest() = false → no implicit defaults →reuins e acuvtles,AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence_number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-only + duration≥1 together matchednothing.Why sequence_number=1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionally stripped (that's existing logic in DATE_FILTER _KEYS )3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representsSetting sequence_number=1 is the minimal, correct signal: "this is not a fresh session open, don't apply page-load defaults". The criteria is otherwise builtIdentically to now the controller bullas it - same uriteria:: creater romkequest, same getondemandPagerilterset, same ondemandSearchidson ly — so theresults will now match.0 dl •Itlle wiun changesvapp/Services/Kiosk/AutomatedReports/ [ AskJiminnyReportActivityService.php +3 -1Ask anything (2*L)+ <> CodeClaude Sonnet 4.6Vew allliReject allAccept allwinasun leams53:11uir-o( 4 spaces...
|
11171
|
|
11175
|
221
|
23
|
2026-04-14T09:17:51.367076+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158271367_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditFV faVsco.jsProjectvViewNavigateCo PhpStormFileEditFV faVsco.jsProjectvViewNavigateCodeLaravelRefactorToolsWindowHelp#11894 on JY-18909-automated-reports-ask-iminny K v© DeviceRepository.php© ElasticActivityRepository.pl© EmailMessageRepository.p© GenericAiPromptRepositor:© GroupRepository.php(C) InboxEmailBatchRepositor)InboxRepository.php© InvitationRepository.php© JobRepository.php© LanguageRepository.php© MomentRepository.php© NotificationRepository.php© ParticipantRepository.php© ParticipantSpeechReposito© ParticipantStatsRepository© PlaybookCategoryRepositc© PlaybookRepository.php® PlaylistActivityRepository.fPlaylistRepository.phpPlaylistShareRepository.ph© QuestionRepository.php© RoleChangeEventRepositor© RoleRepository.php© SearchRepository.php© SnapshotRepository.php© SocialAccountRepository.p© StageRepository.php© SubscriptionSetRepository.TaskRepository.php© TeamAiContextRepository.TeamDomainsRepository.p©TeamInsightsRepository.pt©TeamRepository.php©ThemeRepository.php© TimezoneRepository.php© TopicRepository.php© TopicTriggerRepository.ph© TrackRepository.php© TranscriptionModelLocaleF© TranscriptionRepository.phC) TranscriptionSummarvRep© UserRepository.php© VocabularyRepository.pnp› D Rulesv D Services> [ Activity> D AjReports(J AvatarcalendarD ConferenceD Crm>MImport> MInternallv → Kioskv D AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsStTests passed: 1 (8 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console EUiconsole SlAGiNGAskJiminnykeporAcuivilyservice.ong xActiviysearch.php© Criteria.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php© HistoryService.php© AskJiminnyReportActivityServiceTest.phpclass AskJiminnyReportActivityService© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.php(e TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php• ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedkeportskepo ofA15 X4AV59114115116117118119120/*** Retrieve all standard (non-Ask Jiminny) M* @param string $sortColumnThe column t< 45* Cparam string ssortDirection The sort dir 46*orerurn coccectlonsauromcreoreooro12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Liminny reports created $55-56* OodrdllusernusenIne User Who: 57* @param string $sortColumnIne coLumn c458* @param string $sortDirection The sort dire59* @return Collection<AutomatedReport>*/14 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J—62692 usages70private function buildSortedQuery(string $sor71/*** Get all active and enabled reports with ac 73* @param string $frequency* dreturh coLcectzon<aucomacedкeрort>23 usagespublic function getActiveReportsByFrequency(§ 80public function.__construct(private readonly ActivitySearch SactivitySearch,private readonly ElasticActivityRepository $elasticRepository,private readonly LoggerInterface $logger,) 1..3* Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,* no date constraint is applied - matching the behaviour of getContextForAskAnythingByFilte* Creturn string[] Activity IDs*/14 usagespubuic tunccion getAcuivity.asrorsavedsearchcSearch $savedSearch,user puser): array €$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);$criteria = Criteria::createFromRequest(array_mergelsrequescrarams, L'L1mit => seLT:.DEFAULI_TUP_ALTIVLT Accapt TRejlage"array_merge($requestParams, [=> SeLT::DEFAULI_IOP_ACIIVLILES_COUNL.'page"= 1,sequence_numben' => A$user->getTimezone());$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);$activityIds = $this->elasticRepository->onDemandSearchIds0nLy($user, $criteria, $filter$this->logger->info('[AskJiminnxReport] Fetched activity IDs for saved search'. Esaved_searcn_1d => psavedsearch-›gecta).'user_id' => $user-›getId(),'activity_count' => count($activityIds),return $activityIds;1 usageprivate function buildRequestParamsFromSearch(Search $savedSearch, User $user): array$params = [1;marravruurerkevs = "uis-›acuvltvsearch->oerArravrzurerkeys user.foreach ($savedSearch-›getFilters() as $filter) €$key = $filter->getFilterPropertyO;svalue = sfilter-igetiltervalupfiteAccept File %-X Reject File 0* €, 0lablf Support Daily • in 2h 43 mAAskJiminnyReportActivityServiceT….Defaults100% C•Tue 14 Apr 12:17:51CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..again. Why is there issue with that? Where is it ed to work with that. How is it used inCAskJ1minyReportActivityService. phpL44-66 should be sameed on savedSearch. THe ids in on demand and inLet me read the OnDemandV2Controller to understand how it builds criteria there:Poad OnDemandV?ConwNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php:90-93:0 phpVO\Repository\0nDemandActivitySearch\Criteria::createFromRequest(array merge($request→>allo, ('limit' = $topCount, 'paqe' = 1]).suser->geclimezoneit passes srequest→>all() - wnich Includes sequence_number Trom the URL (e.g. sequence_number=4 Trom your staging URL). so when a user nas beenpaginating on the frontend, sequence_number is naturally non-zero.The full explanationyou didn't ask for themFilterActivityburaclonkandeisFirstRequest) in Criteriareturns true when sequenceNumber === 0 . When it's the "first request" these implicit defaults kick in automatically even ifDefault on first requestman curation = minEffectUrops u-secone acuvitlesActuvltvkecordecOrganiserGroupInonly recorded = 1User's own aroupRestricts to user's arourFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest() = false → no implicit defaults →reuins e acuvtles,AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence_number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-only + durationz1 together matchednothing.Why sequence_number=1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionally stripped (that's existing logic in DATE_FILTER _KEYS )3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representsSetting sequence_number=1 is the minimal, correct signal: "this is not a fresh session open, don't apply page-load defaults". The criteria is otherwise builtIdentically to now the controller bullas it - same uriteria:: creater romkequest, same getondemandPagerilterset, same ondemandSearchidson ly — so theresults will now match.0 dl •Itlle wiun changes vapp/Services/Kiosk/AutomatedReports/ [ AskJiminnyReportActivityService.php +5 -1Ask anything (2*L)+ <> Code Claude Sonnet 4.6Vew allliReject allAccept allwinasun leams55:15uir-o( 4 spaces...
|
NULL
|
2931758732608672464
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileEditFV faVsco.jsProjectvViewNavigateCo PhpStormFileEditFV faVsco.jsProjectvViewNavigateCodeLaravelRefactorToolsWindowHelp#11894 on JY-18909-automated-reports-ask-iminny K v© DeviceRepository.php© ElasticActivityRepository.pl© EmailMessageRepository.p© GenericAiPromptRepositor:© GroupRepository.php(C) InboxEmailBatchRepositor)InboxRepository.php© InvitationRepository.php© JobRepository.php© LanguageRepository.php© MomentRepository.php© NotificationRepository.php© ParticipantRepository.php© ParticipantSpeechReposito© ParticipantStatsRepository© PlaybookCategoryRepositc© PlaybookRepository.php® PlaylistActivityRepository.fPlaylistRepository.phpPlaylistShareRepository.ph© QuestionRepository.php© RoleChangeEventRepositor© RoleRepository.php© SearchRepository.php© SnapshotRepository.php© SocialAccountRepository.p© StageRepository.php© SubscriptionSetRepository.TaskRepository.php© TeamAiContextRepository.TeamDomainsRepository.p©TeamInsightsRepository.pt©TeamRepository.php©ThemeRepository.php© TimezoneRepository.php© TopicRepository.php© TopicTriggerRepository.ph© TrackRepository.php© TranscriptionModelLocaleF© TranscriptionRepository.phC) TranscriptionSummarvRep© UserRepository.php© VocabularyRepository.pnp› D Rulesv D Services> [ Activity> D AjReports(J AvatarcalendarD ConferenceD Crm>MImport> MInternallv → Kioskv D AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsStTests passed: 1 (8 minutes ago)© ReportController.php© AutomatedReportsCommand.phpJiminnybeouecommana.ong= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console EUiconsole SlAGiNGAskJiminnykeporAcuivilyservice.ong xActiviysearch.php© Criteria.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php© HistoryService.php© AskJiminnyReportActivityServiceTest.phpclass AskJiminnyReportActivityService© FilterDefinitionCollection.php© RequestGenerateAskJiminnyReportJobTest.php(e TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php• ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedkeportskepo ofA15 X4AV59114115116117118119120/*** Retrieve all standard (non-Ask Jiminny) M* @param string $sortColumnThe column t< 45* Cparam string ssortDirection The sort dir 46*orerurn coccectlonsauromcreoreooro12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Liminny reports created $55-56* OodrdllusernusenIne User Who: 57* @param string $sortColumnIne coLumn c458* @param string $sortDirection The sort dire59* @return Collection<AutomatedReport>*/14 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J—62692 usages70private function buildSortedQuery(string $sor71/*** Get all active and enabled reports with ac 73* @param string $frequency* dreturh coLcectzon<aucomacedкeрort>23 usagespublic function getActiveReportsByFrequency(§ 80public function.__construct(private readonly ActivitySearch SactivitySearch,private readonly ElasticActivityRepository $elasticRepository,private readonly LoggerInterface $logger,) 1..3* Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,* no date constraint is applied - matching the behaviour of getContextForAskAnythingByFilte* Creturn string[] Activity IDs*/14 usagespubuic tunccion getAcuivity.asrorsavedsearchcSearch $savedSearch,user puser): array €$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);$criteria = Criteria::createFromRequest(array_mergelsrequescrarams, L'L1mit => seLT:.DEFAULI_TUP_ALTIVLT Accapt TRejlage"array_merge($requestParams, [=> SeLT::DEFAULI_IOP_ACIIVLILES_COUNL.'page"= 1,sequence_numben' => A$user->getTimezone());$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);$activityIds = $this->elasticRepository->onDemandSearchIds0nLy($user, $criteria, $filter$this->logger->info('[AskJiminnxReport] Fetched activity IDs for saved search'. Esaved_searcn_1d => psavedsearch-›gecta).'user_id' => $user-›getId(),'activity_count' => count($activityIds),return $activityIds;1 usageprivate function buildRequestParamsFromSearch(Search $savedSearch, User $user): array$params = [1;marravruurerkevs = "uis-›acuvltvsearch->oerArravrzurerkeys user.foreach ($savedSearch-›getFilters() as $filter) €$key = $filter->getFilterPropertyO;svalue = sfilter-igetiltervalupfiteAccept File %-X Reject File 0* €, 0lablf Support Daily • in 2h 43 mAAskJiminnyReportActivityServiceT….Defaults100% C•Tue 14 Apr 12:17:51CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..again. Why is there issue with that? Where is it ed to work with that. How is it used inCAskJ1minyReportActivityService. phpL44-66 should be sameed on savedSearch. THe ids in on demand and inLet me read the OnDemandV2Controller to understand how it builds criteria there:Poad OnDemandV?ConwNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php:90-93:0 phpVO\Repository\0nDemandActivitySearch\Criteria::createFromRequest(array merge($request→>allo, ('limit' = $topCount, 'paqe' = 1]).suser->geclimezoneit passes srequest→>all() - wnich Includes sequence_number Trom the URL (e.g. sequence_number=4 Trom your staging URL). so when a user nas beenpaginating on the frontend, sequence_number is naturally non-zero.The full explanationyou didn't ask for themFilterActivityburaclonkandeisFirstRequest) in Criteriareturns true when sequenceNumber === 0 . When it's the "first request" these implicit defaults kick in automatically even ifDefault on first requestman curation = minEffectUrops u-secone acuvitlesActuvltvkecordecOrganiserGroupInonly recorded = 1User's own aroupRestricts to user's arourFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest() = false → no implicit defaults →reuins e acuvtles,AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence_number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-only + durationz1 together matchednothing.Why sequence_number=1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionally stripped (that's existing logic in DATE_FILTER _KEYS )3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representsSetting sequence_number=1 is the minimal, correct signal: "this is not a fresh session open, don't apply page-load defaults". The criteria is otherwise builtIdentically to now the controller bullas it - same uriteria:: creater romkequest, same getondemandPagerilterset, same ondemandSearchidson ly — so theresults will now match.0 dl •Itlle wiun changes vapp/Services/Kiosk/AutomatedReports/ [ AskJiminnyReportActivityService.php +5 -1Ask anything (2*L)+ <> Code Claude Sonnet 4.6Vew allliReject allAccept allwinasun leams55:15uir-o( 4 spaces...
|
NULL
|
|
11176
|
221
|
24
|
2026-04-14T09:17:53.730128+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158273730_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditFV faVsco.jsProjectvViewNavigateCo PhpStormFileEditFV faVsco.jsProjectvViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© DeviceRepository.php© ElasticActivityRepository.pl© EmailMessageRepository.p© GenericAiPromptRepositor:© GroupRepository.php(C) InboxEmailBatchRepositor)InboxRepository.php© InvitationRepository.php© JobRepository.php© LanguageRepository.php© MomentRepository.php© NotificationRepository.php© ParticipantRepository.php© ParticipantSpeechReposito© ParticipantStatsRepository© PlaybookCategoryRepositc© PlaybookRepository.php® PlaylistActivityRepository.fPlaylistRepository.phpPlaylistShareRepository.ph© QuestionRepository.php© RoleChangeEventRepositor© RoleRepository.php© SearchRepository.php© SnapshotRepository.php© SocialAccountRepository.p© StageRepository.php© SubscriptionSetRepository.TaskRepository.php© TeamAiContextRepository.© TeamDomainsRepository.p©TeamInsightsRepository.pt©TeamRepository.php©ThemeRepository.php© TimezoneRepository.php© TopicRepository.php© TopicTriggerRepository.ph© TrackRepository.php© TranscriptionModelLocaleF© TranscriptionRepository.phC) TranscriptionSummarvRep© UserRepository.php© VocabularyRepository.pnp› D Rulesv D Services> [ Activity> D AjReports› D AvatarcalendarD ConferenceD Crm>MImport> MInternallv → Kioskv D AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsStTests passed: 1 (8 minutes ago)© ReportController.php© AutomatedReportsCommand.php© JiminnyDebugCommand.php= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console EUiconsole SlAGiNGAskJiminnykepor Acuivilyservice.ono xACuiVilysearch.onp© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php(e TrackProvidernstallled-vent.ono© OnDemandV2Controller.php© HistoryService.php© FilterDefinitionCollection.php© AskJiminnyReportActivityServiceTest.php© RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityServiceClosingPeriodFilter::KEY_START_DATE,ClosingPeriodFilter::KEY_END_DATE,© Criteria.phpM2A1AY© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:A15 V4 A V59114115116117118119120123/*** Retrieve all standard (non-Ask Jiminny) M39* @param string $sortColumnThe column t(41* @param string $sortDirection The sort dirt 42* @return Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Liminny reports created A52* Oocrdlll UsernusenIne User Who: 54*oparam scrine osorclocunnThe column tc55* Qparam string $sortDirection The sort dir€56* @return Collection<AutomatedReport>*/-5914 usagespublic function getAskJiminnyReportsByUser(61User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J2 usagesprivate function buildSortedQuery(string $sor 68_69/*** Get all active and enabled reports with al71* @param string $frequency* dreturh coLcectzon<aucomacedкeрort>23 usagespublic function getActiveReportsByFrequency(s 771:1 usagepublic function __construct(private readonly ActivitySearch $activitySearch,private readonly ElasticActivityRepository $elasticRepository,private readonly LoggerInterface $logger,) 1...7*** Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,* no date constraint is applied - matching the hehaviour of getContextForASkAnythingByFi7te* @return string[] Activity IDs*/14 usagespublic function getActivityIdsForSavedSearch(Search $savedSearch,User $user,): array {фrequescraralls - sch1s->001lakequescraramsrromsearchlesavedsearch, suser):$criteria = Criteria::createFromRequest(array_merge($requestParams,['limit'=> self::DEFAULT_TOP_ACTIVITIES_COUNT,'page' => 1,'sequence_number' => 1);$user->getTimezone()$filterSet = $this->activitySearch->get0nDemandPageFilterSet($criteria, Suser);$activityIds = $this->elasticRepository→>onDemandSearchIds0nly($user, $criteria, $filter$this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', ['saved_search_id' => $savedSearch-›getId(),'user_id' => $user->getId(),'activity_count' => count($activityIds),1):return $activityIds;usaoeprivate function buildRequestParamsFromSearch(Search $savedSearch, User $user): array$params = []:$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);foreach ($savedSearch->getFilters() as $filter) {, 0lablf Support Daily • in 2h 43 mAAskJiminnyReportActivityServiceT….Defaults100% C•Tue 14 Apr 12:17:53CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Explain it to me again. Why is there issue with thhat? Where is it expected and why do I need to work with that. How is it used inlevzconuroes vasee oll saveuoedichl. Une los m on celllane ane [EMAIL]#L44-66 should be samewLet me read the OnDemandV2Controller to understand how it builds criteria there:Read OnDe0 phpNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php:90-93:VU kepos1tory onbemandAct1vlcysearch uricer1a:: creacerromkequestarrav meroesrequesoaluo.' umir => 00c0unt "oade$user->getTimezone()It passes Srequest->all() - which includes sequence_number from the URL (e.g. sequence_number=4 from your staging URL). So when a user has beenpaginating on the frontend, sequence_number is naturally non-zero.The full explanationyou didn't ask for them:hsiauist kecuestaouncskenererurns true wnen seauenceNumber === u wnenttsine "trstreduestneseumolci detauirs kickinauromaricalveventFiterDefault on first requestEffectActiv1tvburat zonkangelmin_duration = 1 minDroos 0-secono activitiesActivityRecordedonly_recorded = 1Recorded activities onlvOrganiserGroupInUser's own groupRestricts to user's groupFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest = false → no implicit defaults →returns 15 activities.AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-onlv + duration>1 together matchednothing.Why sequence_number=1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionally stripped (that's existing logic in DATE_FILTER_KEYS )3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representssetting sequence number=l Is the minimal, correct signal: "this is not a wresn session open, cont apoly page-load de lauks". Une criterla is otherwise bulltidentically to how the controller builds it - same Criteria::createFromRequest, same getOnDemandPageFilterSet, same onDemandSearchIds0nly - so theresults will now match.Ö ul ...Ask anything (2*L)+ <> Code Claude Sonnet 4.6winasun leams55:13uir-o( 4 spaces...
|
NULL
|
3650328040747253067
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileEditFV faVsco.jsProjectvViewNavigateCo PhpStormFileEditFV faVsco.jsProjectvViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© DeviceRepository.php© ElasticActivityRepository.pl© EmailMessageRepository.p© GenericAiPromptRepositor:© GroupRepository.php(C) InboxEmailBatchRepositor)InboxRepository.php© InvitationRepository.php© JobRepository.php© LanguageRepository.php© MomentRepository.php© NotificationRepository.php© ParticipantRepository.php© ParticipantSpeechReposito© ParticipantStatsRepository© PlaybookCategoryRepositc© PlaybookRepository.php® PlaylistActivityRepository.fPlaylistRepository.phpPlaylistShareRepository.ph© QuestionRepository.php© RoleChangeEventRepositor© RoleRepository.php© SearchRepository.php© SnapshotRepository.php© SocialAccountRepository.p© StageRepository.php© SubscriptionSetRepository.TaskRepository.php© TeamAiContextRepository.© TeamDomainsRepository.p©TeamInsightsRepository.pt©TeamRepository.php©ThemeRepository.php© TimezoneRepository.php© TopicRepository.php© TopicTriggerRepository.ph© TrackRepository.php© TranscriptionModelLocaleF© TranscriptionRepository.phC) TranscriptionSummarvRep© UserRepository.php© VocabularyRepository.pnp› D Rulesv D Services> [ Activity> D AjReports› D AvatarcalendarD ConferenceD Crm>MImport> MInternallv → Kioskv D AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsStTests passed: 1 (8 minutes ago)© ReportController.php© AutomatedReportsCommand.php© JiminnyDebugCommand.php= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console EUiconsole SlAGiNGAskJiminnykepor Acuivilyservice.ono xACuiVilysearch.onp© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.php(e TrackProvidernstallled-vent.ono© OnDemandV2Controller.php© HistoryService.php© FilterDefinitionCollection.php© AskJiminnyReportActivityServiceTest.php© RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityServiceClosingPeriodFilter::KEY_START_DATE,ClosingPeriodFilter::KEY_END_DATE,© Criteria.phpM2A1AY© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:A15 V4 A V59114115116117118119120123/*** Retrieve all standard (non-Ask Jiminny) M39* @param string $sortColumnThe column t(41* @param string $sortDirection The sort dirt 42* @return Collection<AutomatedReport>12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Liminny reports created A52* Oocrdlll UsernusenIne User Who: 54*oparam scrine osorclocunnThe column tc55* Qparam string $sortDirection The sort dir€56* @return Collection<AutomatedReport>*/-5914 usagespublic function getAskJiminnyReportsByUser(61User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J2 usagesprivate function buildSortedQuery(string $sor 68_69/*** Get all active and enabled reports with al71* @param string $frequency* dreturh coLcectzon<aucomacedкeрort>23 usagespublic function getActiveReportsByFrequency(s 771:1 usagepublic function __construct(private readonly ActivitySearch $activitySearch,private readonly ElasticActivityRepository $elasticRepository,private readonly LoggerInterface $logger,) 1...7*** Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,* no date constraint is applied - matching the hehaviour of getContextForASkAnythingByFi7te* @return string[] Activity IDs*/14 usagespublic function getActivityIdsForSavedSearch(Search $savedSearch,User $user,): array {фrequescraralls - sch1s->001lakequescraramsrromsearchlesavedsearch, suser):$criteria = Criteria::createFromRequest(array_merge($requestParams,['limit'=> self::DEFAULT_TOP_ACTIVITIES_COUNT,'page' => 1,'sequence_number' => 1);$user->getTimezone()$filterSet = $this->activitySearch->get0nDemandPageFilterSet($criteria, Suser);$activityIds = $this->elasticRepository→>onDemandSearchIds0nly($user, $criteria, $filter$this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', ['saved_search_id' => $savedSearch-›getId(),'user_id' => $user->getId(),'activity_count' => count($activityIds),1):return $activityIds;usaoeprivate function buildRequestParamsFromSearch(Search $savedSearch, User $user): array$params = []:$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);foreach ($savedSearch->getFilters() as $filter) {, 0lablf Support Daily • in 2h 43 mAAskJiminnyReportActivityServiceT….Defaults100% C•Tue 14 Apr 12:17:53CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Explain it to me again. Why is there issue with thhat? Where is it expected and why do I need to work with that. How is it used inlevzconuroes vasee oll saveuoedichl. Une los m on celllane ane [EMAIL]#L44-66 should be samewLet me read the OnDemandV2Controller to understand how it builds criteria there:Read OnDe0 phpNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php:90-93:VU kepos1tory onbemandAct1vlcysearch uricer1a:: creacerromkequestarrav meroesrequesoaluo.' umir => 00c0unt "oade$user->getTimezone()It passes Srequest->all() - which includes sequence_number from the URL (e.g. sequence_number=4 from your staging URL). So when a user has beenpaginating on the frontend, sequence_number is naturally non-zero.The full explanationyou didn't ask for them:hsiauist kecuestaouncskenererurns true wnen seauenceNumber === u wnenttsine "trstreduestneseumolci detauirs kickinauromaricalveventFiterDefault on first requestEffectActiv1tvburat zonkangelmin_duration = 1 minDroos 0-secono activitiesActivityRecordedonly_recorded = 1Recorded activities onlvOrganiserGroupInUser's own groupRestricts to user's groupFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest = false → no implicit defaults →returns 15 activities.AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-onlv + duration>1 together matchednothing.Why sequence_number=1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionally stripped (that's existing logic in DATE_FILTER_KEYS )3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representssetting sequence number=l Is the minimal, correct signal: "this is not a wresn session open, cont apoly page-load de lauks". Une criterla is otherwise bulltidentically to how the controller builds it - same Criteria::createFromRequest, same getOnDemandPageFilterSet, same onDemandSearchIds0nly - so theresults will now match.Ö ul ...Ask anything (2*L)+ <> Code Claude Sonnet 4.6winasun leams55:13uir-o( 4 spaces...
|
11175
|
|
11178
|
221
|
25
|
2026-04-14T09:18:03.422861+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158283422_m2.jpg...
|
PhpStorm
|
faVsco.js – AskJiminnyReportActivityService.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditFV faVsco.jsProjectvViewNavigateCo PhpStormFileEditFV faVsco.jsProjectvViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© DeviceRepository.php© ElasticActivityRepository.pl© EmailMessageRepository.p© GenericAiPromptRepositor:© GroupRepository.php(C) InboxEmailBatchRepositon)InboxRepository.php© InvitationRepository.php© JobRepository.php© LanguageRepository.php© MomentRepository.php© NotificationRepository.php© ParticipantRepository.php© ParticipantSpeechReposito© ParticipantStatsRepository© PlaybookCategoryRepositc© PlaybookRepository.php® PlaylistActivityRepository.fPlaylistRepository.phpPlaylistShareRepository.ph© QuestionRepository.php© RoleChangeEventRepositor© RoleRepository.php© SearchRepository.php© SnapshotRepository.php© SocialAccountRepository.p© StageRepository.php© SubscriptionSetRepository.TaskRepository.php© TeamAiContextRepository.© TeamDomainsRepository.p©TeamInsightsRepository.pt©TeamRepository.php©ThemeRepository.php© TimezoneRepository.php© TopicRepository.php© TopicTriggerRepository.ph© TrackRepository.php© TranscriptionModelLocaleF© TranscriptionRepository.phC) TranscriptionSummarvRep© UserRepository.php© VocabularyRepository.pnp> D Rulesv D Services> [ Activity> C AjReports(J AvatarcalendarD ConferenceD Crm>MImport> MInternallv → Kioskv D AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsStTests passed: 1 (8 minutes ago)© ReportController.php© AutomatedReportsCommand.php© JiminnyDebugCommand.php= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console EUiconsole SlAGiNGASkJIminnykeportAcuivilyservice.ono xActiviysearch.php© Criteria.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php© HistoryService.php© FilterDetinitionCollection.phpC AsKJiminyReporrActivityService Test,php x© RequestGenerateAskJiminnyReportJobTest.phpsrong(e TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:815 X4 л59114115116117118119120/*** Retrieve all standard (non-Ask Jiminny) m15* @param string $sortColumnThe column to* @param string $sortDirection The sort dire17*orerurn coccectlonsauromcreoreooro12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Liminny reports created :26-27* Oocrdlll UsernusenThe user whos 28*oparam scrine osorclocunnThe column tc29* Oparam string $sortDirection The sort dire* @return Collection<AutomatedReport>*/14 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J2 usagesprivate function buildSortedQuery(string $sor42/*** Get all active and enabled reports with ac44143* @param string $frequency* dreturn cocLectron<Aucomacedкeрort»23 usagespublic function getActiveReportsByFrequency(s51X221^declare(strict_types=1);namespace Jiminny\Services\Kiosk\AutomatedReports;use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityActualDate;use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityUpdatedDate;use Jiminny\Component\ActivitySearch\FilterDefinition\DealInsights\ClosingPeriodFilter;use Jiminny\Component\ActivitySearch\Service\ActivitySearch;use Jiminny\Models\Activity\Search;use Jiminny\Models\User;use Jiminny\Repositories\ElasticActivityRepository;use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;use Psr\Log\LoggerInterface;8 usagesclass AskJiminnyReportActivityService1 usageprivace const int UErAULI_lUr_AClLVLILeS_LOUNI - 1001 usageprivate const array [ENV_SECRET],ActivityActualDate: :PARAM_END_DATE,ActivityUpdatedDate::PARAM_UPDATED_FROM,ActivityUpdatedDate: :PARAM_UPDATED_TO,ClosingPeriodFilter::KEY_START_DATE,ClosingPeriodFilter::KEY_END_DATE,1:usaoepublic function __construct(private readonly ActivitySearch $activitySearch,private readonly ElasticActivityRepository $elasticRepository,private readonly LoggerInterface $logger,)f...3/*** Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,* no dace constraint is applled - mauching che penavrour of geccontextroraskanychingbyrilce* Creturn string[] Activity IDs14 usagespublic function getActivityIdsForSavedSearchCSearch $savedSearch,User $user,): array {$requestParams = Sthis->buildRequestParamsFromSearch($savedSearch, $user);$criteria = Criteria::createFromRequest(array meroe reduestrarams.Support Daily • in 2h 42 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:18:03+D..CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny RepExplain it to me again. Why is there issue with thhat? Where is it expected and why do I need to work with that. How is it used inMllanuvzcontroes vasee oll saveuoedicl Une los m on celllane dile ilOnSkdILmlуnedoT LheLeveLyetVLceronorL44-00 snoule De sallleLet me read the OnDemandV2Controller to understand how it builds criteria there:Read OnDemanavzconNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php: 90-93:0 phpVU kepos1tory onbemandAct1vlcysearch uricer1a:: creacerromkequestarrav meroesrequesoaluor' umir => 00c0unt 'oade"$user->getTimezone()It passes Srequest->all() - which includes sequence_number from the URL (e.g. sequence_number=4 from your staging URL). So when a user has beenpaginating on the frontend, sequence_number is naturally non-zero.The full explanationyou didn't ask for them:hsiauist kecuestaouncskenererurns true wnen seauenceNumber === u wnenttsine "trstreduestneseumolci detauirs kickinauromaricalveventFiterDefault on first requestEffectActiv1tvburat zonkangelmin_duration = 1 minDroos 0-secono activitiesActivityRecordedonly_recorded = 1Recorded activities onlvOrganiserGroupInUser's own groupRestricts to user's groupFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest = false → no implicit defaults →returns 15 activities.AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-onlv + duration>1 together matchednothing.Why sequence_number=1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionally stripped (that's existing logic in DATE_FILTER_KEYS )3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representsSetting sequence number=1 is the minimal, correct signal: "this is not a fresh session open, don't apply page-load defaults". The criteria is otherwise builtidentically to how the controller builds it - same Criteria::createFromRequest, same getOnDemandPageFilterSet, same onDemandSearchIds0nly - so theresults will now match.wÖ ul ...Ask anything (2*L)+ <> Code Claude Sonnet 4.6winasun leams55:13uir-o( 4 spaces...
|
NULL
|
-634611891360958810
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileEditFV faVsco.jsProjectvViewNavigateCo PhpStormFileEditFV faVsco.jsProjectvViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelp© DeviceRepository.php© ElasticActivityRepository.pl© EmailMessageRepository.p© GenericAiPromptRepositor:© GroupRepository.php(C) InboxEmailBatchRepositon)InboxRepository.php© InvitationRepository.php© JobRepository.php© LanguageRepository.php© MomentRepository.php© NotificationRepository.php© ParticipantRepository.php© ParticipantSpeechReposito© ParticipantStatsRepository© PlaybookCategoryRepositc© PlaybookRepository.php® PlaylistActivityRepository.fPlaylistRepository.phpPlaylistShareRepository.ph© QuestionRepository.php© RoleChangeEventRepositor© RoleRepository.php© SearchRepository.php© SnapshotRepository.php© SocialAccountRepository.p© StageRepository.php© SubscriptionSetRepository.TaskRepository.php© TeamAiContextRepository.© TeamDomainsRepository.p©TeamInsightsRepository.pt©TeamRepository.php©ThemeRepository.php© TimezoneRepository.php© TopicRepository.php© TopicTriggerRepository.ph© TrackRepository.php© TranscriptionModelLocaleF© TranscriptionRepository.phC) TranscriptionSummarvRep© UserRepository.php© VocabularyRepository.pnp> D Rulesv D Services> [ Activity> C AjReports(J AvatarcalendarD ConferenceD Crm>MImport> MInternallv → Kioskv D AutomatedReports© ActivityTypeService.© AskJiminnyReportAc© AutomatedReportsCi© AutomatedReportsStTests passed: 1 (8 minutes ago)© ReportController.php© AutomatedReportsCommand.php© JiminnyDebugCommand.php= custom.log= laravel.logA SF [jiminny@localhost]A HS_local [jiminny@localhost]A console [PROD]< console EUiconsole SlAGiNGASkJIminnykeportAcuivilyservice.ono xActiviysearch.php© Criteria.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© Team.php© AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpOnDemandV2Controller.php© HistoryService.php© FilterDetinitionCollection.phpC AsKJiminyReporrActivityService Test,php x© RequestGenerateAskJiminnyReportJobTest.phpsrong(e TrackProvidernstallled-vent.ono© CreateActivityLoggedEvent.php© UserPilotActivityListener.php(©) ActivityLogged.phpAutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.phpRequestGenerateReportJob.php© AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:815 X4 л59114115116117118119120/*** Retrieve all standard (non-Ask Jiminny) m15* @param string $sortColumnThe column to* @param string $sortDirection The sort dire17*orerurn coccectlonsauromcreoreooro12 usagespublic function getAllStandardReports(string $sortColumn = 'created_at',string $sortDirection = 'desc'): Collection {...}/*** Retrieve all Ask Liminny reports created :26-27* Oocrdlll UsernusenThe user whos 28*oparam scrine osorclocunnThe column tc29* Oparam string $sortDirection The sort dire* @return Collection<AutomatedReport>*/14 usagespublic function getAskJiminnyReportsByUser(User $user,string $sortColumn = 'created_at',string ssorcbirection = "desc"): Collection {...J2 usagesprivate function buildSortedQuery(string $sor42/*** Get all active and enabled reports with ac44143* @param string $frequency* dreturn cocLectron<Aucomacedкeрort»23 usagespublic function getActiveReportsByFrequency(s51X221^declare(strict_types=1);namespace Jiminny\Services\Kiosk\AutomatedReports;use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityActualDate;use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityUpdatedDate;use Jiminny\Component\ActivitySearch\FilterDefinition\DealInsights\ClosingPeriodFilter;use Jiminny\Component\ActivitySearch\Service\ActivitySearch;use Jiminny\Models\Activity\Search;use Jiminny\Models\User;use Jiminny\Repositories\ElasticActivityRepository;use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;use Psr\Log\LoggerInterface;8 usagesclass AskJiminnyReportActivityService1 usageprivace const int UErAULI_lUr_AClLVLILeS_LOUNI - 1001 usageprivate const array [ENV_SECRET],ActivityActualDate: :PARAM_END_DATE,ActivityUpdatedDate::PARAM_UPDATED_FROM,ActivityUpdatedDate: :PARAM_UPDATED_TO,ClosingPeriodFilter::KEY_START_DATE,ClosingPeriodFilter::KEY_END_DATE,1:usaoepublic function __construct(private readonly ActivitySearch $activitySearch,private readonly ElasticActivityRepository $elasticRepository,private readonly LoggerInterface $logger,)f...3/*** Fetch activity IDs for a saved search, passing its filters as-is to Criteria.* Date filters stored on the saved search are excluded; if no other filters exist,* no dace constraint is applled - mauching che penavrour of geccontextroraskanychingbyrilce* Creturn string[] Activity IDs14 usagespublic function getActivityIdsForSavedSearchCSearch $savedSearch,User $user,): array {$requestParams = Sthis->buildRequestParamsFromSearch($savedSearch, $user);$criteria = Criteria::createFromRequest(array meroe reduestrarams.Support Daily • in 2h 42 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:18:03+D..CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny RepExplain it to me again. Why is there issue with thhat? Where is it expected and why do I need to work with that. How is it used inMllanuvzcontroes vasee oll saveuoedicl Une los m on celllane dile ilOnSkdILmlуnedoT LheLeveLyetVLceronorL44-00 snoule De sallleLet me read the OnDemandV2Controller to understand how it builds criteria there:Read OnDemanavzconNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php: 90-93:0 phpVU kepos1tory onbemandAct1vlcysearch uricer1a:: creacerromkequestarrav meroesrequesoaluor' umir => 00c0unt 'oade"$user->getTimezone()It passes Srequest->all() - which includes sequence_number from the URL (e.g. sequence_number=4 from your staging URL). So when a user has beenpaginating on the frontend, sequence_number is naturally non-zero.The full explanationyou didn't ask for them:hsiauist kecuestaouncskenererurns true wnen seauenceNumber === u wnenttsine "trstreduestneseumolci detauirs kickinauromaricalveventFiterDefault on first requestEffectActiv1tvburat zonkangelmin_duration = 1 minDroos 0-secono activitiesActivityRecordedonly_recorded = 1Recorded activities onlvOrganiserGroupInUser's own groupRestricts to user's groupFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest = false → no implicit defaults →returns 15 activities.AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-onlv + duration>1 together matchednothing.Why sequence_number=1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionally stripped (that's existing logic in DATE_FILTER_KEYS )3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representsSetting sequence number=1 is the minimal, correct signal: "this is not a fresh session open, don't apply page-load defaults". The criteria is otherwise builtidentically to how the controller builds it - same Criteria::createFromRequest, same getOnDemandPageFilterSet, same onDemandSearchIds0nly - so theresults will now match.wÖ ul ...Ask anything (2*L)+ <> Code Claude Sonnet 4.6winasun leams55:13uir-o( 4 spaces...
|
NULL
|
|
11179
|
221
|
26
|
2026-04-14T09:18:05.870959+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158285870_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileFditViewNavigateCodeLaravelRefactonToo PhpStormFileFditViewNavigateCodeLaravelRefactonToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject vD Unit_ ActionsC ComponentConfigurationM ConsoleM ContractsM DomainD DTO→ Enums_Events_ Exceptions→ fixtures_ HelpersD Http>_Integrations> MinteractionsMJobs> M ActivitvM AiAutomation>_ Audiov _ AutomatedReports©) CreateResultsTest.pl(C) RequestGenerateAs'© RequestGenerateRerC SendReportJobTest.(ch SendRenortMailJobTcallendar!1CrmDeaksksM Mailbox_ Streaming→ Team_ TelephonyU User(c) ImportRecallAlRecordins(c) SqsVisibilityControlTestMListeners→]Mal> MModelsM Notifications› M ObserversM PoliciesProviders→ Repositories> D Rulesv Services_ Activity_ ActivityProvidersI IAvatarcallendarConference! CinmiM InternallKioskv _ AutomatedReports©) ActivityTypeServi(c) AskJiminnyRepor(c) AskJiminnyRepor(c) AutomatedReportlests passed: 1 (8 minutes ago(©) ReportController.phpC JiminnyDebugCommand.php= custom.log= laravel.l0ge SF (iminny@localhostc HS_local fiminny@localhost)& console (PROD]© AutomatedReportsCommand.php< console LUlconsole SlAGiNG© AskJiminnyReportActivityService.phg© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.phpOnDemandV2Controller.phpC) HistoryService.php© FilterDetinitionCollection.php© Criteria.phpC) Team.onp(©) AutomatedReportsRepository.php XC) AskJiminnyReportActivityServiceTest.php XC) RequestGenerateAskJiminnyReportJobTest.php© AutomatedReportsService.phpC CreateHeldActivityEvent.php© TrackProviderInstalledEvent.phpclass AskJiminnyReportActivityServiceTest extends TestCaseprivateLoccerintertacexrockuonect lodder:yusades82 M3 ^ Yc) CreateActivityLoggeacvencpnpC UserPilotActivityListener.php(©) ActivityLogged.php(C) AutomatedReportsCallbackService.php29 0 >© RequestGenerateAskJiminnyReportJob.php(©) RequestGenerateReportJob.php(©) AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:A15 M4 . V9311411511611711811911124011211124123* Retrieve all standard (non-Ask Jiminny) m71 M>* dparam string ssorttolumnIne column tc* dparam string SsortDirection The sort dire1A0 MI* dreturn ColZection<AutomatedReport>12 usagespublic function getAllStandardReportsstring ssortcolumn = 'created_at'string ssortbirection =desc): Collection {...J118 M>156184185 M206 M225 V* Retrieve all Ask Jiminny reports created i* Oodrdll usernusen227Ine user Ynos* @param string $sortColumnThe column tc228229* dparam string SsortDirection The sort dire* dreturn Collection<AutomatedReport>1254*/14 usagespublic function getAskJzminnyReportsByUser(user suser,suring ssortcolumn = "creaced_at",string ssorcbirection = "desc": Collection {...}—233154236237242243— 244|Z usagesprivate function buildSortedQuery(string Ssor 245246— 247* bet att active and enabled reports with ae 248250*dparam string sfrequency251— 252 V* dreturh coLcectzon<aucomacedкeрort>274Zs usadespublic function getActiveReportsByFrequency(sprivate AskJiminnvReportActivityService Sservice:protected function setUpo: voidk...11 usagesprivate function makeFilter(string $key, ?string $value): SearchFilter&Mock0bject{...}8 usagesprivate function makeUser(): User&Mock0bject(...}ousadesprivate function makeSavedSearch(array $filters): Search&MockObiect....public function testGetActivityldsForSavedSearchReturnsidsO: void...hpublic function testGetActivityldsForSavedSearchReturnsEmptyWhenNoResults: voidk...hpublic function testGetActivityldsr1ltersoutDater1lters: vo1di...public function testGetActivityIdsFilters0utClosingPeriodDateFilters(): void{...}public function testGetActivityIdsHandlesArrayFilters(: voidt...}public function testGetActivityIdsHandlesScalarFilters(: voidf...}public function testGetActivityldsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(suser = sthis->makeUsero:ssavedsearch = sth1s->makesavedSearchclJo*$filterSet = $this->createMock( originalClassName: FilterDefinitionCollection::class);$this->activitvSearch->method( constraint: 'aetArravFilterKevs')38willReturn(fl):ncaotureounrera = nuulsthis-›activitySearch->expects(Sthis->onceo)->method constraint: 'getOnDemandPageFilterSet')->willReturnCallback(function (Criteria $criteria) use SfilterSet, &scapturedCristhis->elasticRepos1tory->method( constraint: 'onbemandSearchldsonly')->w1LlReturn(LJ9:sthis->logger->method( constraint: "1nfo');suh1s->service->gecaculvitytasrorsavedsearcn(psavedsearch, suser):nunus->assercrotvulucaoturedurtertaaSthis->assertFalse(ScapturedCriteria->isFirstRequest00:public function testGetActivityldsLogsWithCorrectContext(): voidk...}: Support Daily • in 2 h 42 m100% [2Tue 14 Apr 12:18:05AskJiminnyReportActivityServiceT..Defaults vCascadeFixing ReportControlleiAutomated Report MaiFixing Ask Jiminny RepExplain it to me again. Why is there issue with that? Where is it expected and why do I need to work with that. How is it used irlevzconuroes vasee oll saveuoedichl. Une los I on celllane ane [EMAIL]#L44-66 should be sameLet me read the OnDemandV2Controller to understand how it builds criteria there:Read OnDemanavzconNow look at the key difterence. The controller's getcontextForAskAnythingByFilter at OnDemandV2Controller.php:96-93:" phoVO Repository OnDemandActivitySearch\Criteria:: createFromRequest(arrav meroesrequesaluo.' umir => 00c0unt oadesuser->oerTimezoneIt passes Srequest→>all() - which includes sequence_number trom the URL (e.g. sequence_number=4 from your staging URL). So when a user has beenpaginating on the frontend, sequence number is naturally non-zeroThe full explanationhsiauist kecuestaouncskenererurns true wnen seauenceNumber === u wnenttsine "trstreduestneseumolci detauirs kickinauromaricalveventyou didn't ask for them:FilterDefault on first requestEffectActiv1tvburat zonkangelmin duration = 1 minDroos 0-secono activitiesActivityRecordedonly_recorded = 1Recorded activities onlvUser's own groupRestricts to user's groupFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest = false → no implicit defaults →returns 15 activities.AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-onlv + duration≥1 together matchednothing.Why sequence_number=1 ls the righttixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionallv strioped (that's existing logic in DATE FILTER KEYS )3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representssetting sequence number=l Is the minimal, correct signal: "this is not a wresn session open, cont apoly page-load de lauks". Une criterla is otherwise bulltidentically to how the controller builds it - same Criteria::createFromRequest, same getOnDemandPageFilterSet, same onDemandSearchidsOnly - so theresults will now match.wal .Ask anything (&+L)+ <> Code Claude Sonnet 4.6Winasun leams230:40uir-oia 4 spaces...
|
NULL
|
-4454444027252615428
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileFditViewNavigateCodeLaravelRefactonToo PhpStormFileFditViewNavigateCodeLaravelRefactonToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject vD Unit_ ActionsC ComponentConfigurationM ConsoleM ContractsM DomainD DTO→ Enums_Events_ Exceptions→ fixtures_ HelpersD Http>_Integrations> MinteractionsMJobs> M ActivitvM AiAutomation>_ Audiov _ AutomatedReports©) CreateResultsTest.pl(C) RequestGenerateAs'© RequestGenerateRerC SendReportJobTest.(ch SendRenortMailJobTcallendar!1CrmDeaksksM Mailbox_ Streaming→ Team_ TelephonyU User(c) ImportRecallAlRecordins(c) SqsVisibilityControlTestMListeners→]Mal> MModelsM Notifications› M ObserversM PoliciesProviders→ Repositories> D Rulesv Services_ Activity_ ActivityProvidersI IAvatarcallendarConference! CinmiM InternallKioskv _ AutomatedReports©) ActivityTypeServi(c) AskJiminnyRepor(c) AskJiminnyRepor(c) AutomatedReportlests passed: 1 (8 minutes ago(©) ReportController.phpC JiminnyDebugCommand.php= custom.log= laravel.l0ge SF (iminny@localhostc HS_local fiminny@localhost)& console (PROD]© AutomatedReportsCommand.php< console LUlconsole SlAGiNG© AskJiminnyReportActivityService.phg© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.phpOnDemandV2Controller.phpC) HistoryService.php© FilterDetinitionCollection.php© Criteria.phpC) Team.onp(©) AutomatedReportsRepository.php XC) AskJiminnyReportActivityServiceTest.php XC) RequestGenerateAskJiminnyReportJobTest.php© AutomatedReportsService.phpC CreateHeldActivityEvent.php© TrackProviderInstalledEvent.phpclass AskJiminnyReportActivityServiceTest extends TestCaseprivateLoccerintertacexrockuonect lodder:yusades82 M3 ^ Yc) CreateActivityLoggeacvencpnpC UserPilotActivityListener.php(©) ActivityLogged.php(C) AutomatedReportsCallbackService.php29 0 >© RequestGenerateAskJiminnyReportJob.php(©) RequestGenerateReportJob.php(©) AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:A15 M4 . V9311411511611711811911124011211124123* Retrieve all standard (non-Ask Jiminny) m71 M>* dparam string ssorttolumnIne column tc* dparam string SsortDirection The sort dire1A0 MI* dreturn ColZection<AutomatedReport>12 usagespublic function getAllStandardReportsstring ssortcolumn = 'created_at'string ssortbirection =desc): Collection {...J118 M>156184185 M206 M225 V* Retrieve all Ask Jiminny reports created i* Oodrdll usernusen227Ine user Ynos* @param string $sortColumnThe column tc228229* dparam string SsortDirection The sort dire* dreturn Collection<AutomatedReport>1254*/14 usagespublic function getAskJzminnyReportsByUser(user suser,suring ssortcolumn = "creaced_at",string ssorcbirection = "desc": Collection {...}—233154236237242243— 244|Z usagesprivate function buildSortedQuery(string Ssor 245246— 247* bet att active and enabled reports with ae 248250*dparam string sfrequency251— 252 V* dreturh coLcectzon<aucomacedкeрort>274Zs usadespublic function getActiveReportsByFrequency(sprivate AskJiminnvReportActivityService Sservice:protected function setUpo: voidk...11 usagesprivate function makeFilter(string $key, ?string $value): SearchFilter&Mock0bject{...}8 usagesprivate function makeUser(): User&Mock0bject(...}ousadesprivate function makeSavedSearch(array $filters): Search&MockObiect....public function testGetActivityldsForSavedSearchReturnsidsO: void...hpublic function testGetActivityldsForSavedSearchReturnsEmptyWhenNoResults: voidk...hpublic function testGetActivityldsr1ltersoutDater1lters: vo1di...public function testGetActivityIdsFilters0utClosingPeriodDateFilters(): void{...}public function testGetActivityIdsHandlesArrayFilters(: voidt...}public function testGetActivityIdsHandlesScalarFilters(: voidf...}public function testGetActivityldsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(suser = sthis->makeUsero:ssavedsearch = sth1s->makesavedSearchclJo*$filterSet = $this->createMock( originalClassName: FilterDefinitionCollection::class);$this->activitvSearch->method( constraint: 'aetArravFilterKevs')38willReturn(fl):ncaotureounrera = nuulsthis-›activitySearch->expects(Sthis->onceo)->method constraint: 'getOnDemandPageFilterSet')->willReturnCallback(function (Criteria $criteria) use SfilterSet, &scapturedCristhis->elasticRepos1tory->method( constraint: 'onbemandSearchldsonly')->w1LlReturn(LJ9:sthis->logger->method( constraint: "1nfo');suh1s->service->gecaculvitytasrorsavedsearcn(psavedsearch, suser):nunus->assercrotvulucaoturedurtertaaSthis->assertFalse(ScapturedCriteria->isFirstRequest00:public function testGetActivityldsLogsWithCorrectContext(): voidk...}: Support Daily • in 2 h 42 m100% [2Tue 14 Apr 12:18:05AskJiminnyReportActivityServiceT..Defaults vCascadeFixing ReportControlleiAutomated Report MaiFixing Ask Jiminny RepExplain it to me again. Why is there issue with that? Where is it expected and why do I need to work with that. How is it used irlevzconuroes vasee oll saveuoedichl. Une los I on celllane ane [EMAIL]#L44-66 should be sameLet me read the OnDemandV2Controller to understand how it builds criteria there:Read OnDemanavzconNow look at the key difterence. The controller's getcontextForAskAnythingByFilter at OnDemandV2Controller.php:96-93:" phoVO Repository OnDemandActivitySearch\Criteria:: createFromRequest(arrav meroesrequesaluo.' umir => 00c0unt oadesuser->oerTimezoneIt passes Srequest→>all() - which includes sequence_number trom the URL (e.g. sequence_number=4 from your staging URL). So when a user has beenpaginating on the frontend, sequence number is naturally non-zeroThe full explanationhsiauist kecuestaouncskenererurns true wnen seauenceNumber === u wnenttsine "trstreduestneseumolci detauirs kickinauromaricalveventyou didn't ask for them:FilterDefault on first requestEffectActiv1tvburat zonkangelmin duration = 1 minDroos 0-secono activitiesActivityRecordedonly_recorded = 1Recorded activities onlvUser's own groupRestricts to user's groupFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest = false → no implicit defaults →returns 15 activities.AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-onlv + duration≥1 together matchednothing.Why sequence_number=1 ls the righttixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionallv strioped (that's existing logic in DATE FILTER KEYS )3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representssetting sequence number=l Is the minimal, correct signal: "this is not a wresn session open, cont apoly page-load de lauks". Une criterla is otherwise bulltidentically to how the controller builds it - same Criteria::createFromRequest, same getOnDemandPageFilterSet, same onDemandSearchidsOnly - so theresults will now match.wal .Ask anything (&+L)+ <> Code Claude Sonnet 4.6Winasun leams230:40uir-oia 4 spaces...
|
11178
|
|
11182
|
221
|
27
|
2026-04-14T09:18:08.312244+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158288312_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileFditViewNavigateCodeLaravelRefactonToo PhpStormFileFditViewNavigateCodeLaravelRefactonToolsWindowHelpFV faVsco.js v#11894 on JY-18909-automated-reports-ask-iminny K vProject vD Unit_ ActionsComponentConfigurationM ConsoleM ContractsM DomainD DTO→ Enums_Events_ Exceptions→ fixtures_ HelpersD Http>_Integrations> MinteractionsMJobs> M ActivitvM AiAutomation>_ Audiov _ AutomatedReports©) CreateResultsTest.pl(C) RequestGenerateAs'© RequestGenerateRerC SendReportJobTest.(ch SendRenortMailJobTcallendar!1CrmDeaksksM Mailbox_ Streaming→ Team_ TelephonyU User(c) ImportRecallAlRecordins(c) SqsVisibilityControlTestMListeners→]Mal> MModelsM Notifications› M ObserversM PoliciesProviders→ Repositories> D Rulesv Services_ Activity_ ActivityProvidersI IAvatarcallendarConference! CinmiM InternallKioskv _ AutomatedReports©) ActivityTypeServi(c) AskJiminnyRepor(c) AskJiminnyRepor(c) AutomatedReportlests passed: 1 (8 minutes ago(©) ReportController.phpC JiminnyDebugCommand.php= custom.log= laravel.l0ge SF (iminny@localhostc HS_local fiminny@localhost)& console (PROD]© AutomatedReportsCommand.php< console LUlconsole SlAGiNG© AskJiminnyReportActivityService.phg© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.phpOnDemandV2Controller.php© HistoryService.php© FilterDetinitionCollection.php© Criteria.phpC) Team.onp(©) AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpC) AskJiminnyReportActivityServiceTest.php XC) RequestGenerateAskJiminnyReportJobTest.php© TrackProviderInstalledEvent.phpclass AskJiminnyReportActivityServiceTest extends TestCaseprivateLoccerintertacexrockuonect lodder:yusades62 X3^c) CreateActivityLoggeacvencpnpC UserPilotActivityListener.php(©) ActivityLogged.php(C) AutomatedReportsCallbackService.php29 0 >© RequestGenerateAskJiminnyReportJob.php(©) RequestGenerateReportJob.php(©) AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:A15 M4 . V9311411511611711811911124011211124123* Retrieve all standard (non-Ask Jiminny) m* dparam string ssortcolumnIne column tc* dparam string SsortDirection The sort dire1A0 MI* dreturn ColZection<AutomatedReport>118 M>15612 usagespublic function getAllStandardReportsstring ssortcolumn = 'created_at'string ssortbirection =desc): Collection {...J184185 M206 M225 V* Retrieve all Ask Jiminny reports created i* Oodrdll usernusen227Ine user Ynos* @param string $sortColumnThe column tc228229* dparam string SsortDirection The sort dire* dreturn Collection<AutomatedReport>*/14 usagespublic function getAskJzminnyReportsByUser(user suser,suring ssortcolumn = "creaced_at",string ssorcbirection = "desc": Collection {...}—233154236237242243— 244|Z usagesprivate function buildSortedQuery(string Ssor 245246— 247* bet att active and enabled reports with ae 248250*dparam string sfrequency251* dreturh coLcectzon<aucomacedкeрort>274Zs usadespublic function getActiveReportsByFrequency(sprivate AskJiminnvReportActivityService Sservice:protected function setUpo: voidk...11 usagesprivate function makeFilter(string $key, ?string $value): SearchFilter&Mock0bject{...}8 usagesprivate function makeUser(): User&Mock0bject(...}ousadesprivate function makeSavedSearchlarray $filters): Search&MockObiect...public function testGetActivityldsForSavedSearchReturnsidsO: void...hpublic function testGetActivityldsForSavedSearchReturnsEmptyWhenNoResults: voidk...hpublic function testGetActivityldsF1ltersoutDater1lters: vo1di...hpublic function testGetActivityIdsFilters0utClosingPeriodDateFilters(): void(...}public function testGetActivityIdsHandlesArrayFilters(: voidt...}public function testGetActivityIdsHandlesScalarFilters(: voidf...}public function testGetActivityldsPassesNonZeroSequenceNumberToDisableFirstRequestDefaultssuser = sthis->makeUsero:ssavedsearch = sth1s->makesavedSearchclJo*stilterser = suhls->creacerockl originalclassname: FilterberinlcloncoLleccion:.class):Sthis-›activitySearch->method ( constrant: "getArrayFilterKeys") ->willReturn([);ncaotureounrera = nuulsthis-›activitySearch->expects(Sthis->onceO)->method constraint: 'getOnDemandPageFilterSet')->willReturnCallback(function (Criteria $criteria) use SfilterSet, &scapturedCristhis->elasticRepos1tory->method( constraint: 'onbemandSearchldsonly')->w1LlReturn(LJ9:sthis->logger->method( constraint: "info");suhis->service->gecAcclv1tylasrorsavedsearch(psavedsearch, puser):nunus->assercrotvulucaoturedurtertaaSthis->assertFalse(ScapturedCriteria->isFirstRequest00:public function testGetActivityldsLogsWithCorrectContext(): voidk...}: Support Daily • in 2 h 42 m100% [2Tue 14 Apr 12:18:08AskJiminnyReportActivityServiceT...Defaults vCascadeFixing ReportControlleiAutomated Report MaiFixing Ask Jiminny Rep+0 .Explain it to me again. Why is there issue with that? Where is it expected and why do I need to work with that. How is it used irlevzconuroes vasee oll saveuoedichl. Une los I on celllane ane [EMAIL]#L44-66 should be sameLet me read the OnDemandV2Controller to understand how it builds criteria there:Read OnDemanavzconNow look at the key difterence. The controller's getcontextForAskAnythingByFilter at OnDemandV2Controller.php:96-93:" phoVO Repository OnDemandActivitySearch\Criteria:: createFromRequest(arrav meroesrequesaluo.' umir => 00c0unt oadesuser->oerTimezoneIt passes Srequest→>all() - which includes sequence_number trom the URL (e.g. sequence_number=4 from your staging URL). So when a user has beenpaginating on the frontend, sequence number is naturally non-zeroThe full explanationhsiauist kecuestaouncskenererurns true wnen seauenceNumber === u wnenttsine "trstreduestneseumolci detauirs kickinauromaricalveventyou didn't ask for them:FiterDefault on first requestEffectActiv1tvburat zonkangelmin duration = 1 minDroos 0-secono activitiesActivityRecordedonly_recorded = 1Recorded activities onlvUser's own groupRestricts to user's groupFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest = false → no implicit defaults →returns 15 activities.AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-onlv + duration≥1 together matchednothing.Why sequence_number=1 ls the righttixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionallv strioped (that's existing logic in DATE FILTER KEYS )3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representssetting sequence number=l Is the minimal, correct signal: "this is not a wresn session open, cont apoly page-load de lauks". Une criterla is otherwise bulltidentically to how the controller builds it - same Criteria::createFromRequest, same getOnDemandPageFilterSet, same onDemandSearchidsOnly - so theresults will now match.wal .Ask anything (&+L)+ <> Code Claude Sonnet 4.6Winasun leams230:40uir-oia 4 spaces...
|
NULL
|
-6103413316660577522
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileFditViewNavigateCodeLaravelRefactonToo PhpStormFileFditViewNavigateCodeLaravelRefactonToolsWindowHelpFV faVsco.js v#11894 on JY-18909-automated-reports-ask-iminny K vProject vD Unit_ ActionsComponentConfigurationM ConsoleM ContractsM DomainD DTO→ Enums_Events_ Exceptions→ fixtures_ HelpersD Http>_Integrations> MinteractionsMJobs> M ActivitvM AiAutomation>_ Audiov _ AutomatedReports©) CreateResultsTest.pl(C) RequestGenerateAs'© RequestGenerateRerC SendReportJobTest.(ch SendRenortMailJobTcallendar!1CrmDeaksksM Mailbox_ Streaming→ Team_ TelephonyU User(c) ImportRecallAlRecordins(c) SqsVisibilityControlTestMListeners→]Mal> MModelsM Notifications› M ObserversM PoliciesProviders→ Repositories> D Rulesv Services_ Activity_ ActivityProvidersI IAvatarcallendarConference! CinmiM InternallKioskv _ AutomatedReports©) ActivityTypeServi(c) AskJiminnyRepor(c) AskJiminnyRepor(c) AutomatedReportlests passed: 1 (8 minutes ago(©) ReportController.phpC JiminnyDebugCommand.php= custom.log= laravel.l0ge SF (iminny@localhostc HS_local fiminny@localhost)& console (PROD]© AutomatedReportsCommand.php< console LUlconsole SlAGiNG© AskJiminnyReportActivityService.phg© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.phpOnDemandV2Controller.php© HistoryService.php© FilterDetinitionCollection.php© Criteria.phpC) Team.onp(©) AutomatedReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpC) AskJiminnyReportActivityServiceTest.php XC) RequestGenerateAskJiminnyReportJobTest.php© TrackProviderInstalledEvent.phpclass AskJiminnyReportActivityServiceTest extends TestCaseprivateLoccerintertacexrockuonect lodder:yusades62 X3^c) CreateActivityLoggeacvencpnpC UserPilotActivityListener.php(©) ActivityLogged.php(C) AutomatedReportsCallbackService.php29 0 >© RequestGenerateAskJiminnyReportJob.php(©) RequestGenerateReportJob.php(©) AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:A15 M4 . V9311411511611711811911124011211124123* Retrieve all standard (non-Ask Jiminny) m* dparam string ssortcolumnIne column tc* dparam string SsortDirection The sort dire1A0 MI* dreturn ColZection<AutomatedReport>118 M>15612 usagespublic function getAllStandardReportsstring ssortcolumn = 'created_at'string ssortbirection =desc): Collection {...J184185 M206 M225 V* Retrieve all Ask Jiminny reports created i* Oodrdll usernusen227Ine user Ynos* @param string $sortColumnThe column tc228229* dparam string SsortDirection The sort dire* dreturn Collection<AutomatedReport>*/14 usagespublic function getAskJzminnyReportsByUser(user suser,suring ssortcolumn = "creaced_at",string ssorcbirection = "desc": Collection {...}—233154236237242243— 244|Z usagesprivate function buildSortedQuery(string Ssor 245246— 247* bet att active and enabled reports with ae 248250*dparam string sfrequency251* dreturh coLcectzon<aucomacedкeрort>274Zs usadespublic function getActiveReportsByFrequency(sprivate AskJiminnvReportActivityService Sservice:protected function setUpo: voidk...11 usagesprivate function makeFilter(string $key, ?string $value): SearchFilter&Mock0bject{...}8 usagesprivate function makeUser(): User&Mock0bject(...}ousadesprivate function makeSavedSearchlarray $filters): Search&MockObiect...public function testGetActivityldsForSavedSearchReturnsidsO: void...hpublic function testGetActivityldsForSavedSearchReturnsEmptyWhenNoResults: voidk...hpublic function testGetActivityldsF1ltersoutDater1lters: vo1di...hpublic function testGetActivityIdsFilters0utClosingPeriodDateFilters(): void(...}public function testGetActivityIdsHandlesArrayFilters(: voidt...}public function testGetActivityIdsHandlesScalarFilters(: voidf...}public function testGetActivityldsPassesNonZeroSequenceNumberToDisableFirstRequestDefaultssuser = sthis->makeUsero:ssavedsearch = sth1s->makesavedSearchclJo*stilterser = suhls->creacerockl originalclassname: FilterberinlcloncoLleccion:.class):Sthis-›activitySearch->method ( constrant: "getArrayFilterKeys") ->willReturn([);ncaotureounrera = nuulsthis-›activitySearch->expects(Sthis->onceO)->method constraint: 'getOnDemandPageFilterSet')->willReturnCallback(function (Criteria $criteria) use SfilterSet, &scapturedCristhis->elasticRepos1tory->method( constraint: 'onbemandSearchldsonly')->w1LlReturn(LJ9:sthis->logger->method( constraint: "info");suhis->service->gecAcclv1tylasrorsavedsearch(psavedsearch, puser):nunus->assercrotvulucaoturedurtertaaSthis->assertFalse(ScapturedCriteria->isFirstRequest00:public function testGetActivityldsLogsWithCorrectContext(): voidk...}: Support Daily • in 2 h 42 m100% [2Tue 14 Apr 12:18:08AskJiminnyReportActivityServiceT...Defaults vCascadeFixing ReportControlleiAutomated Report MaiFixing Ask Jiminny Rep+0 .Explain it to me again. Why is there issue with that? Where is it expected and why do I need to work with that. How is it used irlevzconuroes vasee oll saveuoedichl. Une los I on celllane ane [EMAIL]#L44-66 should be sameLet me read the OnDemandV2Controller to understand how it builds criteria there:Read OnDemanavzconNow look at the key difterence. The controller's getcontextForAskAnythingByFilter at OnDemandV2Controller.php:96-93:" phoVO Repository OnDemandActivitySearch\Criteria:: createFromRequest(arrav meroesrequesaluo.' umir => 00c0unt oadesuser->oerTimezoneIt passes Srequest→>all() - which includes sequence_number trom the URL (e.g. sequence_number=4 from your staging URL). So when a user has beenpaginating on the frontend, sequence number is naturally non-zeroThe full explanationhsiauist kecuestaouncskenererurns true wnen seauenceNumber === u wnenttsine "trstreduestneseumolci detauirs kickinauromaricalveventyou didn't ask for them:FiterDefault on first requestEffectActiv1tvburat zonkangelmin duration = 1 minDroos 0-secono activitiesActivityRecordedonly_recorded = 1Recorded activities onlvUser's own groupRestricts to user's groupFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest = false → no implicit defaults →returns 15 activities.AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-onlv + duration≥1 together matchednothing.Why sequence_number=1 ls the righttixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionallv strioped (that's existing logic in DATE FILTER KEYS )3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representssetting sequence number=l Is the minimal, correct signal: "this is not a wresn session open, cont apoly page-load de lauks". Une criterla is otherwise bulltidentically to how the controller builds it - same Criteria::createFromRequest, same getOnDemandPageFilterSet, same onDemandSearchidsOnly - so theresults will now match.wal .Ask anything (&+L)+ <> Code Claude Sonnet 4.6Winasun leams230:40uir-oia 4 spaces...
|
NULL
|
|
11184
|
221
|
28
|
2026-04-14T09:18:16.688972+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158296688_m2.jpg...
|
PhpStorm
|
faVsco.js – AskJiminnyReportActivityServiceTest.ph faVsco.js – AskJiminnyReportActivityServiceTest.php...
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
3
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Services\Kiosk\AutomatedReports;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityActualDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityUpdatedDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\DealInsights\ClosingPeriodFilter;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\User;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
class AskJiminnyReportActivityServiceTest extends TestCase
{
private ActivitySearch&MockObject $activitySearch;
private ElasticActivityRepository&MockObject $elasticRepository;
private LoggerInterface&MockObject $logger;
private AskJiminnyReportActivityService $service;
protected function setUp(): void
{
$this->activitySearch = $this->createMock(ActivitySearch::class);
$this->elasticRepository = $this->createMock(ElasticActivityRepository::class);
$this->logger = $this->createMock(LoggerInterface::class);
$this->service = new AskJiminnyReportActivityService(
$this->activitySearch,
$this->elasticRepository,
$this->logger,
);
}
private function makeFilter(string $key, ?string $value): SearchFilter&MockObject
{
$filter = $this->createMock(SearchFilter::class);
$filter->method('getFilterProperty')->willReturn($key);
$filter->method('getFilterValue')->willReturn($value);
return $filter;
}
private function makeUser(): User&MockObject
{
$tz = new \DateTimeZone('UTC');
$user = $this->createMock(User::class);
$user->method('getTimezone')->willReturn($tz);
$user->method('getId')->willReturn(1);
$user->method('getUuid')->willReturn('user-uuid');
return $user;
}
private function makeSavedSearch(array $filters): Search&MockObject
{
$savedSearch = $this->createMock(Search::class);
$savedSearch->method('getId')->willReturn(42);
$savedSearch->method('getFilters')->willReturn(new \Illuminate\Support\LazyCollection($filters));
return $savedSearch;
}
public function testGetActivityIdsForSavedSearchReturnsIds(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->expects($this->once())
->method('getArrayFilterKeys')
->with($user)
->willReturn([]);
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturn($filterSet);
$this->elasticRepository->expects($this->once())
->method('onDemandSearchIdsOnly')
->willReturn(['id-1', 'id-2', 'id-3']);
$this->logger->expects($this->once())
->method('info')
->with('[AskJiminnyReport] Fetched activity IDs for saved search');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1', 'id-2', 'id-3'], $result);
}
public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->expects($this->once())->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEmpty($result);
}
public function testGetActivityIdsFiltersOutDateFilters(): void
{
$user = $this->makeUser();
$nonDateFilter = $this->makeFilter('owner_id', '123');
$startDateFilter = $this->makeFilter(ActivityActualDate::PARAM_START_DATE, '2025-01-01 00:00:00');
$endDateFilter = $this->makeFilter(ActivityActualDate::PARAM_END_DATE, '2025-01-31 23:59:59');
$updatedFromFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_FROM, '2025-01-01 00:00:00');
$updatedToFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_TO, '2025-01-31 23:59:59');
$savedSearch = $this->makeSavedSearch([
$nonDateFilter,
$startDateFilter,
$endDateFilter,
$updatedFromFilter,
$updatedToFilter,
]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$capturedCriteria = null;
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {
$capturedCriteria = $criteria;
return $filterSet;
});
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->method('info');
$this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertNotNull($capturedCriteria);
}
public function testGetActivityIdsFiltersOutClosingPeriodDateFilters(): void
{
$user = $this->makeUser();
$closingStartFilter = $this->makeFilter(ClosingPeriodFilter::KEY_START_DATE, '2025-01-01');
$closingEndFilter = $this->makeFilter(ClosingPeriodFilter::KEY_END_DATE, '2025-03-31');
$regularFilter = $this->makeFilter('rep_id', '99');
$savedSearch = $this->makeSavedSearch([
$closingStartFilter,
$closingEndFilter,
$regularFilter,
]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1'], $result);
}
public function testGetActivityIdsHandlesArrayFilters(): void
{
$user = $this->makeUser();
$filter1 = $this->makeFilter('outcome', 'positive');
$filter2 = $this->makeFilter('outcome', 'negative');
$savedSearch = $this->makeSavedSearch([$filter1, $filter2]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn(['outcome']);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1'], $result);
}
public function testGetActivityIdsHandlesScalarFilters(): void
{
$user = $this->makeUser();
$filter = $this->makeFilter('direction', 'inbound');
$savedSearch = $this->makeSavedSearch([$filter]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-5']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-5'], $result);
}
public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$capturedCriteria = null;
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {
$capturedCriteria = $criteria;
return $filterSet;
});
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->method('info');
$this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertNotNull($capturedCriteria);
$this->assertFalse($capturedCriteria->isFirstRequest());
}
public function testGetActivityIdsLogsWithCorrectContext(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['a', 'b']);
$this->logger->expects($this->once())
->method('info')
->with(
'[AskJiminnyReport] Fetched activity IDs for saved search',
$this->callback(fn ($context) => $context['saved_search_id'] === 42
&& $context['user_id'] === 1
&& $context['activity_count'] === 2)
);
$this->service->getActivityIdsForSavedSearch($savedSearch, $user);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","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.7589844,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceT…Defaults","depth":6,"bounds":{"left":0.7769531,"top":0.017361112,"width":0.12382813,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.575,"top":0.13055556,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"3","depth":4,"bounds":{"left":0.58671874,"top":0.13055556,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.5980469,"top":0.12916666,"width":0.00859375,"height":0.015972223},"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.60664064,"top":0.12916666,"width":0.008203125,"height":0.015972223},"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\\Services\\Kiosk\\AutomatedReports;\n\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityActualDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityUpdatedDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealInsights\\ClosingPeriodFilter;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AskJiminnyReportActivityService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse PHPUnit\\Framework\\TestCase;\nuse Psr\\Log\\LoggerInterface;\n\nclass AskJiminnyReportActivityServiceTest extends TestCase\n{\n private ActivitySearch&MockObject $activitySearch;\n private ElasticActivityRepository&MockObject $elasticRepository;\n private LoggerInterface&MockObject $logger;\n private AskJiminnyReportActivityService $service;\n\n protected function setUp(): void\n {\n $this->activitySearch = $this->createMock(ActivitySearch::class);\n $this->elasticRepository = $this->createMock(ElasticActivityRepository::class);\n $this->logger = $this->createMock(LoggerInterface::class);\n\n $this->service = new AskJiminnyReportActivityService(\n $this->activitySearch,\n $this->elasticRepository,\n $this->logger,\n );\n }\n\n private function makeFilter(string $key, ?string $value): SearchFilter&MockObject\n {\n $filter = $this->createMock(SearchFilter::class);\n $filter->method('getFilterProperty')->willReturn($key);\n $filter->method('getFilterValue')->willReturn($value);\n\n return $filter;\n }\n\n private function makeUser(): User&MockObject\n {\n $tz = new \\DateTimeZone('UTC');\n $user = $this->createMock(User::class);\n $user->method('getTimezone')->willReturn($tz);\n $user->method('getId')->willReturn(1);\n $user->method('getUuid')->willReturn('user-uuid');\n\n return $user;\n }\n\n private function makeSavedSearch(array $filters): Search&MockObject\n {\n $savedSearch = $this->createMock(Search::class);\n $savedSearch->method('getId')->willReturn(42);\n $savedSearch->method('getFilters')->willReturn(new \\Illuminate\\Support\\LazyCollection($filters));\n\n return $savedSearch;\n }\n\n public function testGetActivityIdsForSavedSearchReturnsIds(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->expects($this->once())\n ->method('getArrayFilterKeys')\n ->with($user)\n ->willReturn([]);\n\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturn($filterSet);\n\n $this->elasticRepository->expects($this->once())\n ->method('onDemandSearchIdsOnly')\n ->willReturn(['id-1', 'id-2', 'id-3']);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with('[AskJiminnyReport] Fetched activity IDs for saved search');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1', 'id-2', 'id-3'], $result);\n }\n\n public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n\n $this->logger->expects($this->once())->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEmpty($result);\n }\n\n public function testGetActivityIdsFiltersOutDateFilters(): void\n {\n $user = $this->makeUser();\n\n $nonDateFilter = $this->makeFilter('owner_id', '123');\n $startDateFilter = $this->makeFilter(ActivityActualDate::PARAM_START_DATE, '2025-01-01 00:00:00');\n $endDateFilter = $this->makeFilter(ActivityActualDate::PARAM_END_DATE, '2025-01-31 23:59:59');\n $updatedFromFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_FROM, '2025-01-01 00:00:00');\n $updatedToFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_TO, '2025-01-31 23:59:59');\n\n $savedSearch = $this->makeSavedSearch([\n $nonDateFilter,\n $startDateFilter,\n $endDateFilter,\n $updatedFromFilter,\n $updatedToFilter,\n ]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n\n $capturedCriteria = null;\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {\n $capturedCriteria = $criteria;\n\n return $filterSet;\n });\n\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n $this->logger->method('info');\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertNotNull($capturedCriteria);\n }\n\n public function testGetActivityIdsFiltersOutClosingPeriodDateFilters(): void\n {\n $user = $this->makeUser();\n\n $closingStartFilter = $this->makeFilter(ClosingPeriodFilter::KEY_START_DATE, '2025-01-01');\n $closingEndFilter = $this->makeFilter(ClosingPeriodFilter::KEY_END_DATE, '2025-03-31');\n $regularFilter = $this->makeFilter('rep_id', '99');\n\n $savedSearch = $this->makeSavedSearch([\n $closingStartFilter,\n $closingEndFilter,\n $regularFilter,\n ]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1'], $result);\n }\n\n public function testGetActivityIdsHandlesArrayFilters(): void\n {\n $user = $this->makeUser();\n\n $filter1 = $this->makeFilter('outcome', 'positive');\n $filter2 = $this->makeFilter('outcome', 'negative');\n\n $savedSearch = $this->makeSavedSearch([$filter1, $filter2]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn(['outcome']);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1'], $result);\n }\n\n public function testGetActivityIdsHandlesScalarFilters(): void\n {\n $user = $this->makeUser();\n\n $filter = $this->makeFilter('direction', 'inbound');\n $savedSearch = $this->makeSavedSearch([$filter]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-5']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-5'], $result);\n }\n\n public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n\n $capturedCriteria = null;\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {\n $capturedCriteria = $criteria;\n\n return $filterSet;\n });\n\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n $this->logger->method('info');\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertNotNull($capturedCriteria);\n $this->assertFalse($capturedCriteria->isFirstRequest());\n }\n\n public function testGetActivityIdsLogsWithCorrectContext(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['a', 'b']);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with(\n '[AskJiminnyReport] Fetched activity IDs for saved search',\n $this->callback(fn ($context) => $context['saved_search_id'] === 42\n && $context['user_id'] === 1\n && $context['activity_count'] === 2)\n );\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n }\n}","depth":4,"bounds":{"left":0.32617188,"top":0.0,"width":0.3347656,"height":1.0},"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Services\\Kiosk\\AutomatedReports;\n\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityActualDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityUpdatedDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealInsights\\ClosingPeriodFilter;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AskJiminnyReportActivityService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse PHPUnit\\Framework\\TestCase;\nuse Psr\\Log\\LoggerInterface;\n\nclass AskJiminnyReportActivityServiceTest extends TestCase\n{\n private ActivitySearch&MockObject $activitySearch;\n private ElasticActivityRepository&MockObject $elasticRepository;\n private LoggerInterface&MockObject $logger;\n private AskJiminnyReportActivityService $service;\n\n protected function setUp(): void\n {\n $this->activitySearch = $this->createMock(ActivitySearch::class);\n $this->elasticRepository = $this->createMock(ElasticActivityRepository::class);\n $this->logger = $this->createMock(LoggerInterface::class);\n\n $this->service = new AskJiminnyReportActivityService(\n $this->activitySearch,\n $this->elasticRepository,\n $this->logger,\n );\n }\n\n private function makeFilter(string $key, ?string $value): SearchFilter&MockObject\n {\n $filter = $this->createMock(SearchFilter::class);\n $filter->method('getFilterProperty')->willReturn($key);\n $filter->method('getFilterValue')->willReturn($value);\n\n return $filter;\n }\n\n private function makeUser(): User&MockObject\n {\n $tz = new \\DateTimeZone('UTC');\n $user = $this->createMock(User::class);\n $user->method('getTimezone')->willReturn($tz);\n $user->method('getId')->willReturn(1);\n $user->method('getUuid')->willReturn('user-uuid');\n\n return $user;\n }\n\n private function makeSavedSearch(array $filters): Search&MockObject\n {\n $savedSearch = $this->createMock(Search::class);\n $savedSearch->method('getId')->willReturn(42);\n $savedSearch->method('getFilters')->willReturn(new \\Illuminate\\Support\\LazyCollection($filters));\n\n return $savedSearch;\n }\n\n public function testGetActivityIdsForSavedSearchReturnsIds(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->expects($this->once())\n ->method('getArrayFilterKeys')\n ->with($user)\n ->willReturn([]);\n\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturn($filterSet);\n\n $this->elasticRepository->expects($this->once())\n ->method('onDemandSearchIdsOnly')\n ->willReturn(['id-1', 'id-2', 'id-3']);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with('[AskJiminnyReport] Fetched activity IDs for saved search');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1', 'id-2', 'id-3'], $result);\n }\n\n public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n\n $this->logger->expects($this->once())->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEmpty($result);\n }\n\n public function testGetActivityIdsFiltersOutDateFilters(): void\n {\n $user = $this->makeUser();\n\n $nonDateFilter = $this->makeFilter('owner_id', '123');\n $startDateFilter = $this->makeFilter(ActivityActualDate::PARAM_START_DATE, '2025-01-01 00:00:00');\n $endDateFilter = $this->makeFilter(ActivityActualDate::PARAM_END_DATE, '2025-01-31 23:59:59');\n $updatedFromFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_FROM, '2025-01-01 00:00:00');\n $updatedToFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_TO, '2025-01-31 23:59:59');\n\n $savedSearch = $this->makeSavedSearch([\n $nonDateFilter,\n $startDateFilter,\n $endDateFilter,\n $updatedFromFilter,\n $updatedToFilter,\n ]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n\n $capturedCriteria = null;\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {\n $capturedCriteria = $criteria;\n\n return $filterSet;\n });\n\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n $this->logger->method('info');\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertNotNull($capturedCriteria);\n }\n\n public function testGetActivityIdsFiltersOutClosingPeriodDateFilters(): void\n {\n $user = $this->makeUser();\n\n $closingStartFilter = $this->makeFilter(ClosingPeriodFilter::KEY_START_DATE, '2025-01-01');\n $closingEndFilter = $this->makeFilter(ClosingPeriodFilter::KEY_END_DATE, '2025-03-31');\n $regularFilter = $this->makeFilter('rep_id', '99');\n\n $savedSearch = $this->makeSavedSearch([\n $closingStartFilter,\n $closingEndFilter,\n $regularFilter,\n ]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1'], $result);\n }\n\n public function testGetActivityIdsHandlesArrayFilters(): void\n {\n $user = $this->makeUser();\n\n $filter1 = $this->makeFilter('outcome', 'positive');\n $filter2 = $this->makeFilter('outcome', 'negative');\n\n $savedSearch = $this->makeSavedSearch([$filter1, $filter2]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn(['outcome']);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1'], $result);\n }\n\n public function testGetActivityIdsHandlesScalarFilters(): void\n {\n $user = $this->makeUser();\n\n $filter = $this->makeFilter('direction', 'inbound');\n $savedSearch = $this->makeSavedSearch([$filter]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-5']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-5'], $result);\n }\n\n public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n\n $capturedCriteria = null;\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {\n $capturedCriteria = $criteria;\n\n return $filterSet;\n });\n\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n $this->logger->method('info');\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertNotNull($capturedCriteria);\n $this->assertFalse($capturedCriteria->isFirstRequest());\n }\n\n public function testGetActivityIdsLogsWithCorrectContext(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['a', 'b']);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with(\n '[AskJiminnyReport] Fetched activity IDs for saved search',\n $this->callback(fn ($context) => $context['saved_search_id'] === 42\n && $context['user_id'] === 1\n && $context['activity_count'] === 2)\n );\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"15","depth":4,"bounds":{"left":0.2589844,"top":0.28125,"width":0.011328125,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.27265626,"top":0.28125,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.28398436,"top":0.27986112,"width":0.00859375,"height":0.015972223},"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.29257813,"top":0.27986112,"width":0.008203125,"height":0.015972223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
409850090631519174
|
938142628803978660
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
3
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Services\Kiosk\AutomatedReports;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityActualDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityUpdatedDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\DealInsights\ClosingPeriodFilter;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\User;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
class AskJiminnyReportActivityServiceTest extends TestCase
{
private ActivitySearch&MockObject $activitySearch;
private ElasticActivityRepository&MockObject $elasticRepository;
private LoggerInterface&MockObject $logger;
private AskJiminnyReportActivityService $service;
protected function setUp(): void
{
$this->activitySearch = $this->createMock(ActivitySearch::class);
$this->elasticRepository = $this->createMock(ElasticActivityRepository::class);
$this->logger = $this->createMock(LoggerInterface::class);
$this->service = new AskJiminnyReportActivityService(
$this->activitySearch,
$this->elasticRepository,
$this->logger,
);
}
private function makeFilter(string $key, ?string $value): SearchFilter&MockObject
{
$filter = $this->createMock(SearchFilter::class);
$filter->method('getFilterProperty')->willReturn($key);
$filter->method('getFilterValue')->willReturn($value);
return $filter;
}
private function makeUser(): User&MockObject
{
$tz = new \DateTimeZone('UTC');
$user = $this->createMock(User::class);
$user->method('getTimezone')->willReturn($tz);
$user->method('getId')->willReturn(1);
$user->method('getUuid')->willReturn('user-uuid');
return $user;
}
private function makeSavedSearch(array $filters): Search&MockObject
{
$savedSearch = $this->createMock(Search::class);
$savedSearch->method('getId')->willReturn(42);
$savedSearch->method('getFilters')->willReturn(new \Illuminate\Support\LazyCollection($filters));
return $savedSearch;
}
public function testGetActivityIdsForSavedSearchReturnsIds(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->expects($this->once())
->method('getArrayFilterKeys')
->with($user)
->willReturn([]);
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturn($filterSet);
$this->elasticRepository->expects($this->once())
->method('onDemandSearchIdsOnly')
->willReturn(['id-1', 'id-2', 'id-3']);
$this->logger->expects($this->once())
->method('info')
->with('[AskJiminnyReport] Fetched activity IDs for saved search');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1', 'id-2', 'id-3'], $result);
}
public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->expects($this->once())->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEmpty($result);
}
public function testGetActivityIdsFiltersOutDateFilters(): void
{
$user = $this->makeUser();
$nonDateFilter = $this->makeFilter('owner_id', '123');
$startDateFilter = $this->makeFilter(ActivityActualDate::PARAM_START_DATE, '2025-01-01 00:00:00');
$endDateFilter = $this->makeFilter(ActivityActualDate::PARAM_END_DATE, '2025-01-31 23:59:59');
$updatedFromFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_FROM, '2025-01-01 00:00:00');
$updatedToFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_TO, '2025-01-31 23:59:59');
$savedSearch = $this->makeSavedSearch([
$nonDateFilter,
$startDateFilter,
$endDateFilter,
$updatedFromFilter,
$updatedToFilter,
]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$capturedCriteria = null;
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {
$capturedCriteria = $criteria;
return $filterSet;
});
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->method('info');
$this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertNotNull($capturedCriteria);
}
public function testGetActivityIdsFiltersOutClosingPeriodDateFilters(): void
{
$user = $this->makeUser();
$closingStartFilter = $this->makeFilter(ClosingPeriodFilter::KEY_START_DATE, '2025-01-01');
$closingEndFilter = $this->makeFilter(ClosingPeriodFilter::KEY_END_DATE, '2025-03-31');
$regularFilter = $this->makeFilter('rep_id', '99');
$savedSearch = $this->makeSavedSearch([
$closingStartFilter,
$closingEndFilter,
$regularFilter,
]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1'], $result);
}
public function testGetActivityIdsHandlesArrayFilters(): void
{
$user = $this->makeUser();
$filter1 = $this->makeFilter('outcome', 'positive');
$filter2 = $this->makeFilter('outcome', 'negative');
$savedSearch = $this->makeSavedSearch([$filter1, $filter2]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn(['outcome']);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1'], $result);
}
public function testGetActivityIdsHandlesScalarFilters(): void
{
$user = $this->makeUser();
$filter = $this->makeFilter('direction', 'inbound');
$savedSearch = $this->makeSavedSearch([$filter]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-5']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-5'], $result);
}
public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$capturedCriteria = null;
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {
$capturedCriteria = $criteria;
return $filterSet;
});
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->method('info');
$this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertNotNull($capturedCriteria);
$this->assertFalse($capturedCriteria->isFirstRequest());
}
public function testGetActivityIdsLogsWithCorrectContext(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['a', 'b']);
$this->logger->expects($this->once())
->method('info')
->with(
'[AskJiminnyReport] Fetched activity IDs for saved search',
$this->callback(fn ($context) => $context['saved_search_id'] === 42
&& $context['user_id'] === 1
&& $context['activity_count'] === 2)
);
$this->service->getActivityIdsForSavedSearch($savedSearch, $user);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
15
4
Previous Highlighted Error
Next Highlighted Error...
|
11182
|
|
11186
|
221
|
29
|
2026-04-14T09:18:18.160255+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158298160_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileFditViewNavigateCodeLaravelRefactonToo PhpStormFileFditViewNavigateCodeLaravelRefactonToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject vD Unit_ ActionsC ComponentConfigurationM ConsoleM ContractsM DomainD DTO→ Enums_ Events_ Exceptions→ fixtures_ HelpersD Http>_Integrations> Minteractions• D Jobs> M ActivitvM AiAutomation>_ Audiov _ AutomatedReports©) CreateResultsTest.pl(C) RequestGenerateAs'© RequestGenerateRerC SendReportJobTest.(ch SendRenortMailJobTcallendar!1CrmDeaksksM Mailbox_ Streaming→ Team_ TelephonyU User(c) ImportRecallAlRecordins(c) SqsVisibilityControlTestMListeners→]Mal> M ModelsM Notifications> MObserversPoliciesProviders→ Repositories> D Rulesv Services_ Activity_ ActivityProvidersI IAvatarcallendarConference! CinmiM InternallKioskv _ AutomatedReports©) ActivityTypeServi(c) AskJiminnyRepor(c) AskJiminnyRepor(c) AutomatedReportlests passed:1 (g minutes ago(©) ReportController.phpC JiminnyDebugCommand.php= custom.log= laravel.l0ge SF (iminny@localhostc HS_local fiminny@localhost)& console (PROD]© AutomatedReportsCommand.php< console LUlconsole SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.phpOnDemandV2Controller.php© HistoryService.php© FilterDetinitionCollection.php© Criteria.phpC) Team.onp(©) AutomatedReportsRepository.php XC) AskJiminnyReportActivityServiceTest.php XC) RequestGenerateAskJiminnyReportJobTest.php© AutomatedReportsService.phpC CreateHeldActivityEvent.php© TrackProviderInstalledEvent.phpclass AskJiminnyReportActivityServiceTest extends TestCaseprivateLoccerintertacexrockuonect lodder:yusades82 M3 ^ Yc) CreateActivityLoggeacvencpnpC UserPilotActivityListener.php(©) ActivityLogged.php(C) AutomatedReportsCallbackService.php29 0 >© RequestGenerateAskJiminnyReportJob.php(©) RequestGenerateReportJob.php(©) AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:A15 M4 . V9311411511611711811911124011211124123* Retrieve all standard (non-Ask Jiminny) m* dparam string ssortcolumnIne column tc* dparam string SsortDirection The sort dire1A0 MI* dreturn ColZection<AutomatedReport>12 usagespublic function getAllStandardReportsstring ssortcolumn = 'created_at'string ssortbirection =desc): Collection {...}118 M>156184185 M206 M225 V* Retrieve all Ask Jiminny reports created i* Oodrdll usernusen227Ine user Ynos* @param string SsortColumnThe column tc228229* dparam string SsortDirection The sort dire* dreturn Collection<AutomatedReport>*/14 usagespublic function getAskJzminnyReportsByUser(user suser,suring ssortcolumn = "creaced_at",string ssorcbirection = "desc": Collection {...}254— 233154236237242243— 244|Z usagesprivate function buildSortedQuery(string Ssor 245246— 247* bet att active and enabled reports with ae 248250*dparam string sfrequency251— 252 V* dreturh coLcectzon<aucomacedкeрort>274Zs usadespublic function getActiveReportsByFrequency(sprivate AskJiminnvReportActivityService Sservice:protected function setUpo: voidk...11 usagesprivate function makeFilter(string $key, ?string $value): SearchFilter&Mock0bject{...}8 usagesprivate runcuion makeuser: userdmockudjectl....o usagesprivate function makeSavedSearch(array Sfilters): Search&MockObiect....public function testGetActivityIdsForSavedSearchReturnsidsO: void ...rpublic function testGetActivityldsForSavedSearchReturnsEmptyWhenNoResults: voidi...hpublic function testGetActivityldsF1ltersoutbater1lterso: vo1di...hpublic function testGetActivityIdsFilters0utClosingPeriodDateFilters(): void{...}public function testGetActivityIdsHandlesArrayFilters(: voidt...}public function testGetActivityIdsHandlesScalarFilters(: voidt...public function testGetActivityldsPassesNonZeroSequenceNumberToDisableFirstRequestDefaultssuser = sthis->makeUsero:ssavedsearch = sth1s->makesavedSearchclJo*stilterser = schls->creacerock, originalclassname: FilterberinlcloncoLlecclon:.class):$this-sactivitySearch-sethodf constraint: "getArpavEiltenkevs')-swillPeturncFl):ncaotureounrera = nuulsthis-›activitySearch->expects(Sthis->onceO)->method constraint:'getOnDemandPageFilterSet')->willReturnCallbackfunction (Criteria $criteria) use SfilterSet, &ScapturedCristhis->elasticRepos1tory->method( constraint: 'onDemandSearchlasonly')->w1llReturn(LJ)*sthis->logger->method( constraint: "info");suhis->service->gecAcclv1tylasrorsavedsearch(psavedsearch, puser):nunus->assercrotvulucaoturedurtertaaSthis->assertFalse(ScapturedCriteria->isFirstRequest00:public function testGetActivityldsLogsWithCorrectContext(): voidk...}: Support Daily • in 2 h 42 m100% [2Tue 14 Apr 12:18:17AskJiminnyReportActivityServiceT...Defaults vCascadeFixing ReportControlleiAutomated Report MaiFixing Ask Jiminny Rep+0 .Explain it to me again. Why is there issue with that? Where is it expected and why do I need to work with that. How is it used irlevzconuroes vasee oll saveuoedichl Ine los m on celllane ane [EMAIL]#L44-66 should be sameLet me read the OnDemandV2Controller to understand how it builds criteria there:Read OnDemanavzconNow look at the key difterence. The controller's getcontextForAskAnythingByFilter at OnDemandV2Controller.php:96-93:" phoVU kepos1tory onbemandAct1vlcysearch uricer1a:: creacerromkequescarrav meroesrequesoaluor' umir => 00c0unt 'oade"suser->oerTimezoneIt passes Srequest→>all() - which includes sequence_number trom the URL (e.g. sequence_number=4 from your staging URL). So when a user has beenpaginating on the frontend, sequence number is naturally non-zeroThe full explanationhsiauist kecuestaouncskenererurns true wnen seauenceNumber === u wnenttsine "trstreduestneseumolci detauirs kickinauromaricalveventyou didn't ask for them:FiterDefault on first requestEffectActiv1tvburat zonkangelmin duration = 1 minDroos 0-secono activitiesActivityRecordedonly_recorded = 1Recorded activities onlvUser's own groupRestricts to user's groupFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest = false → no implicit defaults →returns 15 activities.AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-onlv + duration≥1 together matchednothing.Why sequence_number=1 ls the righttixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionallv strioped (that's existing logic in DATE FILTER KEYS )3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representssetting sequence number=1 IS the minimal, correct signal: "this is not a wresn session open, don t apply page-load derauks". Une criterla is otnerwise bulltidentically to how the controller builds it - same Criteria::createFromRequest, same getOnDemandPageFilterSet, same onDemandSearchidsOnly - so theresults will now match.wal .Ask anything (&+L)+ <> Code Claude Sonnet 4.6winasun leamsuir-oia 4 spaces...
|
NULL
|
3152301224817141227
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileFditViewNavigateCodeLaravelRefactonToo PhpStormFileFditViewNavigateCodeLaravelRefactonToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject vD Unit_ ActionsC ComponentConfigurationM ConsoleM ContractsM DomainD DTO→ Enums_ Events_ Exceptions→ fixtures_ HelpersD Http>_Integrations> Minteractions• D Jobs> M ActivitvM AiAutomation>_ Audiov _ AutomatedReports©) CreateResultsTest.pl(C) RequestGenerateAs'© RequestGenerateRerC SendReportJobTest.(ch SendRenortMailJobTcallendar!1CrmDeaksksM Mailbox_ Streaming→ Team_ TelephonyU User(c) ImportRecallAlRecordins(c) SqsVisibilityControlTestMListeners→]Mal> M ModelsM Notifications> MObserversPoliciesProviders→ Repositories> D Rulesv Services_ Activity_ ActivityProvidersI IAvatarcallendarConference! CinmiM InternallKioskv _ AutomatedReports©) ActivityTypeServi(c) AskJiminnyRepor(c) AskJiminnyRepor(c) AutomatedReportlests passed:1 (g minutes ago(©) ReportController.phpC JiminnyDebugCommand.php= custom.log= laravel.l0ge SF (iminny@localhostc HS_local fiminny@localhost)& console (PROD]© AutomatedReportsCommand.php< console LUlconsole SlAGiNG© AskJiminnyReportActivityService.php© ActivitySearch.php© AutomatedReportsSendCommand.php© AddLayoutEntities.phpOnDemandV2Controller.php© HistoryService.php© FilterDetinitionCollection.php© Criteria.phpC) Team.onp(©) AutomatedReportsRepository.php XC) AskJiminnyReportActivityServiceTest.php XC) RequestGenerateAskJiminnyReportJobTest.php© AutomatedReportsService.phpC CreateHeldActivityEvent.php© TrackProviderInstalledEvent.phpclass AskJiminnyReportActivityServiceTest extends TestCaseprivateLoccerintertacexrockuonect lodder:yusades82 M3 ^ Yc) CreateActivityLoggeacvencpnpC UserPilotActivityListener.php(©) ActivityLogged.php(C) AutomatedReportsCallbackService.php29 0 >© RequestGenerateAskJiminnyReportJob.php(©) RequestGenerateReportJob.php(©) AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:A15 M4 . V9311411511611711811911124011211124123* Retrieve all standard (non-Ask Jiminny) m* dparam string ssortcolumnIne column tc* dparam string SsortDirection The sort dire1A0 MI* dreturn ColZection<AutomatedReport>12 usagespublic function getAllStandardReportsstring ssortcolumn = 'created_at'string ssortbirection =desc): Collection {...}118 M>156184185 M206 M225 V* Retrieve all Ask Jiminny reports created i* Oodrdll usernusen227Ine user Ynos* @param string SsortColumnThe column tc228229* dparam string SsortDirection The sort dire* dreturn Collection<AutomatedReport>*/14 usagespublic function getAskJzminnyReportsByUser(user suser,suring ssortcolumn = "creaced_at",string ssorcbirection = "desc": Collection {...}254— 233154236237242243— 244|Z usagesprivate function buildSortedQuery(string Ssor 245246— 247* bet att active and enabled reports with ae 248250*dparam string sfrequency251— 252 V* dreturh coLcectzon<aucomacedкeрort>274Zs usadespublic function getActiveReportsByFrequency(sprivate AskJiminnvReportActivityService Sservice:protected function setUpo: voidk...11 usagesprivate function makeFilter(string $key, ?string $value): SearchFilter&Mock0bject{...}8 usagesprivate runcuion makeuser: userdmockudjectl....o usagesprivate function makeSavedSearch(array Sfilters): Search&MockObiect....public function testGetActivityIdsForSavedSearchReturnsidsO: void ...rpublic function testGetActivityldsForSavedSearchReturnsEmptyWhenNoResults: voidi...hpublic function testGetActivityldsF1ltersoutbater1lterso: vo1di...hpublic function testGetActivityIdsFilters0utClosingPeriodDateFilters(): void{...}public function testGetActivityIdsHandlesArrayFilters(: voidt...}public function testGetActivityIdsHandlesScalarFilters(: voidt...public function testGetActivityldsPassesNonZeroSequenceNumberToDisableFirstRequestDefaultssuser = sthis->makeUsero:ssavedsearch = sth1s->makesavedSearchclJo*stilterser = schls->creacerock, originalclassname: FilterberinlcloncoLlecclon:.class):$this-sactivitySearch-sethodf constraint: "getArpavEiltenkevs')-swillPeturncFl):ncaotureounrera = nuulsthis-›activitySearch->expects(Sthis->onceO)->method constraint:'getOnDemandPageFilterSet')->willReturnCallbackfunction (Criteria $criteria) use SfilterSet, &ScapturedCristhis->elasticRepos1tory->method( constraint: 'onDemandSearchlasonly')->w1llReturn(LJ)*sthis->logger->method( constraint: "info");suhis->service->gecAcclv1tylasrorsavedsearch(psavedsearch, puser):nunus->assercrotvulucaoturedurtertaaSthis->assertFalse(ScapturedCriteria->isFirstRequest00:public function testGetActivityldsLogsWithCorrectContext(): voidk...}: Support Daily • in 2 h 42 m100% [2Tue 14 Apr 12:18:17AskJiminnyReportActivityServiceT...Defaults vCascadeFixing ReportControlleiAutomated Report MaiFixing Ask Jiminny Rep+0 .Explain it to me again. Why is there issue with that? Where is it expected and why do I need to work with that. How is it used irlevzconuroes vasee oll saveuoedichl Ine los m on celllane ane [EMAIL]#L44-66 should be sameLet me read the OnDemandV2Controller to understand how it builds criteria there:Read OnDemanavzconNow look at the key difterence. The controller's getcontextForAskAnythingByFilter at OnDemandV2Controller.php:96-93:" phoVU kepos1tory onbemandAct1vlcysearch uricer1a:: creacerromkequescarrav meroesrequesoaluor' umir => 00c0unt 'oade"suser->oerTimezoneIt passes Srequest→>all() - which includes sequence_number trom the URL (e.g. sequence_number=4 from your staging URL). So when a user has beenpaginating on the frontend, sequence number is naturally non-zeroThe full explanationhsiauist kecuestaouncskenererurns true wnen seauenceNumber === u wnenttsine "trstreduestneseumolci detauirs kickinauromaricalveventyou didn't ask for them:FiterDefault on first requestEffectActiv1tvburat zonkangelmin duration = 1 minDroos 0-secono activitiesActivityRecordedonly_recorded = 1Recorded activities onlvUser's own groupRestricts to user's groupFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest = false → no implicit defaults →returns 15 activities.AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-onlv + duration≥1 together matchednothing.Why sequence_number=1 ls the righttixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionallv strioped (that's existing logic in DATE FILTER KEYS )3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representssetting sequence number=1 IS the minimal, correct signal: "this is not a wresn session open, don t apply page-load derauks". Une criterla is otnerwise bulltidentically to how the controller builds it - same Criteria::createFromRequest, same getOnDemandPageFilterSet, same onDemandSearchidsOnly - so theresults will now match.wal .Ask anything (&+L)+ <> Code Claude Sonnet 4.6winasun leamsuir-oia 4 spaces...
|
NULL
|
|
11188
|
221
|
30
|
2026-04-14T09:18:20.272230+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158300272_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileFditViewNavigateCodeLaravelRetactonToo PhpStormFileFditViewNavigateCodeLaravelRetactonToolsWindowHelpFV faVsco.js v#11894 on JY-18909-automated-reports-ask-iminny K vProject vD Unit>DActionsComponentConfigurationM ConsoleM ContractsM DomainD DTO→ Enums_Events_ Exceptions→ fixtures_ HelpersD Http>_Integrations> Minteractions• D Jobs> M ActivitvM AiAutomation>_ Audiov _ AutomatedReports©) CreateResultsTest.pl(C) RequestGenerateAs'© RequestGenerateRerC SendReportJobTest.(ch SendRenortMailJobTcallendar!1CrmDeaksksM Mailbox_ Streaming→ Team_ TelephonyU User(c) ImportRecallAlRecordins(c) SqsVisibilityControlTestMListeners→]Mal> MModelsM Notifications> MObserversM PoliciesProviders→ Repositories> D Rulesv Services_ Activity_ ActivityProvidersI IAvatarcallendarConference! CinmiM InternallKioskv _ AutomatedReports©) ActivityTypeServi(c) AskJiminnyRepor(c) AskJiminnyRepor(c) AutomatedReportlests passed:1 (g minutes ago(©) ReportController.phpJiminnybeouecommana.ong= custom.log= laravel.l0ge SF (iminny@localhostc HS_local fiminny@localhost)& console (PROD]© AutomatedReportsCommand.php< console EUiconsole SlAGiNG© AskJiminnyReportActivityService.phg© ActivitySearch.php© AutomatedReportsSendCommand.phpC AddLayoutEntities.phpOnDemandV2Controller.phpC) HistoryService.php© FilterDetinitionCollection.php© Criteria.phpC) Team.onp© AutomattgdReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpC) AskJiminnyReportActivityServiceTest.php XC) RequestGenerateAskJiminnyReportJobTest.php(e) TrackProviderinstallled=vent.onoclass AskJiminnyReportActivityServiceTest extends TestCaseprivateLoccerintertacexrockuonect lodder:yusades62 X3^c) CreateActivityLoggeacvenconpC UserPilotActivityListener.php(©) ActivityLogged.php(C) AutomatedReportsCallbackService.php29 0 >© RequestGenerateAskJiminnyReportJob.php(©) RequestGenerateReportJob.php(©) AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:A15 M4 . V9311411511611711811911124011211124123* Retrieve all standard (non-Ask Jiminny) m71 M >* dparam string ssorttolumnIne column tc* dparam string SsortDirection The sort dire190 MAI* dreturn ColZection<AutomatedReport>118 M>15612 usagespublic function getAllStandardReportsstring ssortcolumn = 'created_at'string ssortbirection =desc): Collection {...J184185 M206 M225 V* Retrieve all Ask Jiminny reports created i* Oodrdll usernusen227Ine user Ynos* @param string $sortColumnThe column tc228229* dparam string SsortDirection The sort dire* dreturn Collection<AutomatedReport>*/14 usagespublic function getAskJzminnyReportsByUser(user suser,suring ssortcolumn = "creaced_at",string ssorcbirection = "desc": Collection {...}1254—233154236237242243— 244|Z usagesprivate function buildSortedQuery(string Ssor 245246— 247* bet att active and enabled reports with ae 248250*dparam string sfrequency251— 252 V* dreturh coLcectzon<aucomacedкeрort>274Zs usadespublic function getActiveReportsByFrequency(sprivate AskJiminnvReportActivityService Sservice:protected function setUpo: voidk...11 usagesprivate function makeFilter(string $key, ?string $value): SearchFilter&Mock0bject{...}8 usagesprivate function makeUser(): User&Mock0bject(...}ousadesprivate function makeSavedSearchlarray $filters): Search&MockObiect...public function testGetActivityldsForSavedSearchReturnsidsO: void...hpublic function testGetActivityldsForSavedSearchReturnsEmptyWhenNoResults: voidk...hpublic function testGetActivityIdsFilters0utDateFilters(: void{...}public function testGetActivityIdsFilters0utClosingPeriodDateFilters(): void(...}public function testGetActivityIdsHandlesArrayFilters(: voidt...}public function testGetActivityIdsHandlesScalarFilters(: voidf...}public function testGetActivityldsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(suser = sthis->makeUsero:ssavedsearch = sth1s->makesavedSearchclJo*$filterSet = $this->createMock( originalClassName: FilterDefinitionCollection::class)nunus-›acuvlrvsearch->neunoo constraint 'detArravrtuterkevs'->Muureturnuo.ncaotureounrera = nuulsthis-›activitySearch->expects(Sthis->onceO)->method constraint: 'getOnDemandPageFilterSet')->willReturnCallbackfunction (Criteria $criteria) use SfilterSet, &ScapturedCristhis->elasticRepos1tory->method( constraint: 'onDemandSearchlasonly')->w1llReturn(LJ)*sthis->logger->method( constraint: "info");suh1s->service->gecaculvitytasrorsavedsearcn(psavedsearch, suser):nunus->assercrotvulucaoturedurtertaaSthis->assertFalse(ScapturedCriteria->isFirstRequest00:public function testGetActivityldsLoqsWithCorrectContextO: voidk...h: Support Daily • in 2 h 42 m100% [2Tue 14 Apr 12:18:19AskJiminnyReportActivityServiceT...Defaults vCascadeFixing ReportControlleiAutomated Report MaiFixing Ask Jiminny RepExplain it to me again. Why is there issue with that? Where is it expected and why do I need to work with that. How is it used irlevzconuroes vasee oll saveuoedichl. Une los I on celllane ane [EMAIL]#L44-66 should be sameLet me read the OnDemandV2Controller to understand how it builds criteria there:Read OnDemanavzconNow look at the key difterence. The controller's getcontextForAskAnythingByFilter at OnDemandV2Controller-php: 96-93:" phoVO Repository OnDemandActivitySearch\Criteria:: createFromRequest(arrav meroesrequesoaluu.' umir => r00c0unt oadesuser->oerTimezoneIt passes Srequest→>all() - which includes sequence_number trom the URL (e.g. sequence_number=4 from your staging URL). So when a user has beenpaginating on the frontend, sequence number is naturally non-zeroThe full explanationhsiauist kecuestaouncskenererurns true wnen seauenceNumber === u wnenttsine "trstreduestneseumolci detauirs kickinauromaricalveventyou didn't ask for them:FilterDefault on first requestEffectActiv1tvburat zonkangelmin duration = 1 minDroos 0-secono activitiesActivityRecordedonly_recorded = 1Recorded activities onlvUser's own groupRestricts to user's groupFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest = false → no implicit defaults →returns 15 activities.AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-onlv + duration≥1 together matchednothing.Why sequence_number=1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionallv strioped (that's existing logic in DATE FILTER KEYS )3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representsSetting sequence number=1 is the minimal, correct signal: "this is not a fresh session open, don't apply page-load defaults". The criteria is otherwise builtidentically to how the controller builds it - same Criteria:: createFromRequest, same getOnDemandPageFilterSet, same onDemandSearchldsOnly - so theresults will now match.wal .Ask anything (&+L)+ ‹> CodeClaude Sonnet 4.6Winasun leams230:40uir-oia 4 spaces...
|
NULL
|
-2855165097480013156
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileFditViewNavigateCodeLaravelRetactonToo PhpStormFileFditViewNavigateCodeLaravelRetactonToolsWindowHelpFV faVsco.js v#11894 on JY-18909-automated-reports-ask-iminny K vProject vD Unit>DActionsComponentConfigurationM ConsoleM ContractsM DomainD DTO→ Enums_Events_ Exceptions→ fixtures_ HelpersD Http>_Integrations> Minteractions• D Jobs> M ActivitvM AiAutomation>_ Audiov _ AutomatedReports©) CreateResultsTest.pl(C) RequestGenerateAs'© RequestGenerateRerC SendReportJobTest.(ch SendRenortMailJobTcallendar!1CrmDeaksksM Mailbox_ Streaming→ Team_ TelephonyU User(c) ImportRecallAlRecordins(c) SqsVisibilityControlTestMListeners→]Mal> MModelsM Notifications> MObserversM PoliciesProviders→ Repositories> D Rulesv Services_ Activity_ ActivityProvidersI IAvatarcallendarConference! CinmiM InternallKioskv _ AutomatedReports©) ActivityTypeServi(c) AskJiminnyRepor(c) AskJiminnyRepor(c) AutomatedReportlests passed:1 (g minutes ago(©) ReportController.phpJiminnybeouecommana.ong= custom.log= laravel.l0ge SF (iminny@localhostc HS_local fiminny@localhost)& console (PROD]© AutomatedReportsCommand.php< console EUiconsole SlAGiNG© AskJiminnyReportActivityService.phg© ActivitySearch.php© AutomatedReportsSendCommand.phpC AddLayoutEntities.phpOnDemandV2Controller.phpC) HistoryService.php© FilterDetinitionCollection.php© Criteria.phpC) Team.onp© AutomattgdReportsRepository.php X© AutomatedReportsService.phpC CreateHeldActivityEvent.phpC) AskJiminnyReportActivityServiceTest.php XC) RequestGenerateAskJiminnyReportJobTest.php(e) TrackProviderinstallled=vent.onoclass AskJiminnyReportActivityServiceTest extends TestCaseprivateLoccerintertacexrockuonect lodder:yusades62 X3^c) CreateActivityLoggeacvenconpC UserPilotActivityListener.php(©) ActivityLogged.php(C) AutomatedReportsCallbackService.php29 0 >© RequestGenerateAskJiminnyReportJob.php(©) RequestGenerateReportJob.php(©) AutomatedReportResult.php(C) AutomatedReport.phpclass Automacedкeрortskepo o:A15 M4 . V9311411511611711811911124011211124123* Retrieve all standard (non-Ask Jiminny) m71 M >* dparam string ssorttolumnIne column tc* dparam string SsortDirection The sort dire190 MAI* dreturn ColZection<AutomatedReport>118 M>15612 usagespublic function getAllStandardReportsstring ssortcolumn = 'created_at'string ssortbirection =desc): Collection {...J184185 M206 M225 V* Retrieve all Ask Jiminny reports created i* Oodrdll usernusen227Ine user Ynos* @param string $sortColumnThe column tc228229* dparam string SsortDirection The sort dire* dreturn Collection<AutomatedReport>*/14 usagespublic function getAskJzminnyReportsByUser(user suser,suring ssortcolumn = "creaced_at",string ssorcbirection = "desc": Collection {...}1254—233154236237242243— 244|Z usagesprivate function buildSortedQuery(string Ssor 245246— 247* bet att active and enabled reports with ae 248250*dparam string sfrequency251— 252 V* dreturh coLcectzon<aucomacedкeрort>274Zs usadespublic function getActiveReportsByFrequency(sprivate AskJiminnvReportActivityService Sservice:protected function setUpo: voidk...11 usagesprivate function makeFilter(string $key, ?string $value): SearchFilter&Mock0bject{...}8 usagesprivate function makeUser(): User&Mock0bject(...}ousadesprivate function makeSavedSearchlarray $filters): Search&MockObiect...public function testGetActivityldsForSavedSearchReturnsidsO: void...hpublic function testGetActivityldsForSavedSearchReturnsEmptyWhenNoResults: voidk...hpublic function testGetActivityIdsFilters0utDateFilters(: void{...}public function testGetActivityIdsFilters0utClosingPeriodDateFilters(): void(...}public function testGetActivityIdsHandlesArrayFilters(: voidt...}public function testGetActivityIdsHandlesScalarFilters(: voidf...}public function testGetActivityldsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(suser = sthis->makeUsero:ssavedsearch = sth1s->makesavedSearchclJo*$filterSet = $this->createMock( originalClassName: FilterDefinitionCollection::class)nunus-›acuvlrvsearch->neunoo constraint 'detArravrtuterkevs'->Muureturnuo.ncaotureounrera = nuulsthis-›activitySearch->expects(Sthis->onceO)->method constraint: 'getOnDemandPageFilterSet')->willReturnCallbackfunction (Criteria $criteria) use SfilterSet, &ScapturedCristhis->elasticRepos1tory->method( constraint: 'onDemandSearchlasonly')->w1llReturn(LJ)*sthis->logger->method( constraint: "info");suh1s->service->gecaculvitytasrorsavedsearcn(psavedsearch, suser):nunus->assercrotvulucaoturedurtertaaSthis->assertFalse(ScapturedCriteria->isFirstRequest00:public function testGetActivityldsLoqsWithCorrectContextO: voidk...h: Support Daily • in 2 h 42 m100% [2Tue 14 Apr 12:18:19AskJiminnyReportActivityServiceT...Defaults vCascadeFixing ReportControlleiAutomated Report MaiFixing Ask Jiminny RepExplain it to me again. Why is there issue with that? Where is it expected and why do I need to work with that. How is it used irlevzconuroes vasee oll saveuoedichl. Une los I on celllane ane [EMAIL]#L44-66 should be sameLet me read the OnDemandV2Controller to understand how it builds criteria there:Read OnDemanavzconNow look at the key difterence. The controller's getcontextForAskAnythingByFilter at OnDemandV2Controller-php: 96-93:" phoVO Repository OnDemandActivitySearch\Criteria:: createFromRequest(arrav meroesrequesoaluu.' umir => r00c0unt oadesuser->oerTimezoneIt passes Srequest→>all() - which includes sequence_number trom the URL (e.g. sequence_number=4 from your staging URL). So when a user has beenpaginating on the frontend, sequence number is naturally non-zeroThe full explanationhsiauist kecuestaouncskenererurns true wnen seauenceNumber === u wnenttsine "trstreduestneseumolci detauirs kickinauromaricalveventyou didn't ask for them:FilterDefault on first requestEffectActiv1tvburat zonkangelmin duration = 1 minDroos 0-secono activitiesActivityRecordedonly_recorded = 1Recorded activities onlvUser's own groupRestricts to user's groupFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest = false → no implicit defaults →returns 15 activities.AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-onlv + duration≥1 together matchednothing.Why sequence_number=1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionallv strioped (that's existing logic in DATE FILTER KEYS )3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representsSetting sequence number=1 is the minimal, correct signal: "this is not a fresh session open, don't apply page-load defaults". The criteria is otherwise builtidentically to how the controller builds it - same Criteria:: createFromRequest, same getOnDemandPageFilterSet, same onDemandSearchldsOnly - so theresults will now match.wal .Ask anything (&+L)+ ‹> CodeClaude Sonnet 4.6Winasun leams230:40uir-oia 4 spaces...
|
11186
|
|
11190
|
221
|
31
|
2026-04-14T09:18:23.573266+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158303573_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileFV faVsco.js vViewNavigateCodeLaravelR PhpStormFileFV faVsco.js vViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-liminny k vToolsWindowHelpProject vProphetAiv D Reports© AutomatedReportsCl© AutomatedReportsRe© AutomatedReportsSt© CreateMockAskJimir© DeleteReportComma© GenerateMarketingR© Team.php© Usage.phpD Slack_leamsD TracksO TranscriptionO TwilioD UsersVocabularyDZoom© CoachingFeedbacksUpr© Command.phpcreateDatabaseusers.pc Daraoase oecountoi© DeleteOldAiCrmNotesC:© DeleteS3LeftoversComiDevPostmanCommand./© DiarizeViaAiParticipantk© EncryptTokensComman© EngagementStatsRegen©FeatureFlagsHelper.php© FixCrossTenantlssues.p(c) -ushro espermissionsc(e) Generatelnterna wepho• GroupSetDefaultLangua© HelperTruncateCoachin© HubspotJournalPollingC© HubspotWebhookServic©ImportRecording.php© ImportUsersFromCsvFil© IterateUsersCommand.f© JiminnyCacheClearCom© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoCommMakeslackLvecoaching(c Manacescimror eam.o© MarkBranchForEnvironn© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesCom(e Recalculatebealkisksco(c) Removebe eremarkersc(e) Remove-xoiredNudoesc removeunusecrarcloC ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© ReportController.phpAulomaleakeporissendcommand.onoJiminnybeouecommana.ong© AddLayoutEntities.php) AutomatedReportsService.php© CreateActivityLoggedEvent.phpAutomatedReportsCommand.php xleam.ono© CreateHeldActivityEvent.php© UserPilotActivityListener.php© RequestGenerateReportJob.php© AutomatedReportResult.phpc) Automatedreport.onoclass AutomatedReportsCommand extends CommandA2^1031041051061071081091101111121131114115116117118119120121122123124125126127128129130131132133134137138139140141142143144145146147148149150151private function processReports(string $frequency): void$this->logger->info(self::LOG_PREFIX . " Processing $frequency reports");$reportId = $this->›option( key: 'report-id');if ($reportId !== null) {$reports = $this->getReportById($reportId);1 else {// Get all enabled, not deleted reports with active teams for the speci 51$reports = $this->reportRepository->getActiveReportsByFrequency($freque 61$this->logger->info(self::LOG_PREFIX ." Found ($reports->count()} $frequer 7071%/** @var AutomatedReport $report */foreach ($reports as $report) {100 ₽$this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report jC117'reportUvid' = $report->getUvid(),118€'teamId' => $report->getTeamId(),'frequency' => $report->getFrequency(),157 8 >'type' => $report->getType(),1):185 %$job = $report->isAskJiminnyReport()? new RequestGenerateAskJiminnyReportJob($report->getUvid()):new RequestGenerateReportJob($report->getUvid()):$this->dispatcher->dispatch($job);$this->dispatcher->dispatchSync($job);206 ₽ >224225 ₽226228230private function getReportById(string $reportId): Collection1254$report = $this->reportRepository->findById0rUvid($reportId);if ($report === null) {$this->logger->warning(self::LOG_PREFIX'Report not found for --repf237$this->warn( string: "Report not found: {$reportId}");236242243return collect();if (! $report->getStatus()) {$this->Logger->warning(self::LOG_PREFIX'reportId' => SreportId.'reportUvid' => $report->getUvid(),Report is inactive, proces:2481):249250mantial nuon 250g= custom.log= laravel.logA SF [jiminny@localhost]Hs local liminnyalocalnostconsole PRODL console [EUlA console [STAGING]© ActivitySearch.php© AskJiminnyReportActivityService.php•OnDemandV2Controller.php© HistoryService.phprilterDerinitioncollection.ongcriiera.onpCh Ask. liminnvRenortActivitvServiceTest.ohn X© RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityServiceTof26private LoggerInterface&MockUbject Logger;9 usagesBLMSAYprivate AskJiminnvReportActivityService Sservice:29 6t >Eprotected function setup(): voidf...}11 usagesprivate function makeFilter(string $key, ?string $valve):8 usagesprivate function makeUser(): User&Mock0bjectf...}8 usagesprivate function makeSavedSearch(array $filters): Searchspublic function testGetActivityIdsForSavedSearchReturnsIcpublic function testGetActivityIdsForSavedSearchReturnsEnpublic function testGetActivityIdsFilters0utDateFiltersOpublic function testGetActivityIdsFilters0utClosingPeriocpubLic tunction cescbecactivicyLashandLesarrayr1lterscpublic function testGetActivityIdsHandLesScalarFilters:public function testGetActivityIdsPassesNonZeroSequenceNLsusen = sthis->makelcenD$savedSearch = $this->makeSavedSearch([]);$filterSet = $this->createMock( originalClassName: Filtern$this->activitySearch->method( constraint:detArravr$capturedCriteria = null;$this->activitySearch->expects($this->once))->method ( constraint: 'getOnDemandPageFilterSet')->willReturnCallback(function (Criteria $criteria$this->elasticRepository->method( constraint: 'onDeman$this->logger->method( constraint:anto')"sthis->service->aetActivitvldsForSavedSearch/SsavedS$this->assertNotNull($capturedCriteria);$this->assertFalse($capturedCriteria->isFirstRequest(Support Daily • in 2h 42 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:18:23CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Explain it to me again. Why is there issue with thhat? Where is it expected and why do I need to work with that. How is it used inDelllaluvzcontroes vasee oll saveuoedichl. Une los m on celllane ane iiOnSkdImbуnedoT LheLeveLyoetVaceronorL44-0e snoule de sallitwLet me read the OnDemandV2Controller to understand how it builds criteria there:Read OnDemanavzconNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php: 90-93:0 phpVO Repository OnDemandActivitySearch\Criteria::createFromRequest(arrav meroesrequesoaluor' umir => 00c0unt 'oade"$user->getTimezone()It passes Srequest->all() - which includes sequence_number from the URL (e.g. sequence_number=4 from your staging URL). So when a user has beenpaginating on the frontend, sequence_number is naturally non-zero.The full explanationyou didn't ask for them:FilterActiv1tvburat zonkangelhsiauist kecuestaouncskenererurns true wnen seauenceNumber === u wnenttsine "trstreduestneseumolci detauirs kickinauromaricalveventDefault on first requestmin_duration = 1 minEffectDroos 0-secono activitiesActivityRecordedonly_recorded = 1Recorded activities onlvUser's own groupRestricts to user's groupFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest = false → no implicit defaults →returns 15 activities.AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence_number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-onlv + duration>1 together matchednothing.Why sequence_number=1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionally stripped (that's existing logic in DATE_FILTER_KEYS )3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representsSetting sequence number=1 is the minimal, correct signal: "this is not a fresh session open, don't apply page-load defaults". The criteria is otherwise builtidentically to how the controller builds it - same Criteria::createFromRequest, same get0nDemandPageFilterSet, same onDemandSearchIds0nly - so theresults will now match.Ö ul ...Ask anything (2*L)+ <> Code Claude Sonnet 4.6Winasun leamsuir-o( 4 spaces...
|
NULL
|
-7285880554883731765
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileFV faVsco.js vViewNavigateCodeLaravelR PhpStormFileFV faVsco.js vViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-liminny k vToolsWindowHelpProject vProphetAiv D Reports© AutomatedReportsCl© AutomatedReportsRe© AutomatedReportsSt© CreateMockAskJimir© DeleteReportComma© GenerateMarketingR© Team.php© Usage.phpD Slack_leamsD TracksO TranscriptionO TwilioD UsersVocabularyDZoom© CoachingFeedbacksUpr© Command.phpcreateDatabaseusers.pc Daraoase oecountoi© DeleteOldAiCrmNotesC:© DeleteS3LeftoversComiDevPostmanCommand./© DiarizeViaAiParticipantk© EncryptTokensComman© EngagementStatsRegen©FeatureFlagsHelper.php© FixCrossTenantlssues.p(c) -ushro espermissionsc(e) Generatelnterna wepho• GroupSetDefaultLangua© HelperTruncateCoachin© HubspotJournalPollingC© HubspotWebhookServic©ImportRecording.php© ImportUsersFromCsvFil© IterateUsersCommand.f© JiminnyCacheClearCom© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoCommMakeslackLvecoaching(c Manacescimror eam.o© MarkBranchForEnvironn© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesCom(e Recalculatebealkisksco(c) Removebe eremarkersc(e) Remove-xoiredNudoesc removeunusecrarcloC ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© ReportController.phpAulomaleakeporissendcommand.onoJiminnybeouecommana.ong© AddLayoutEntities.php) AutomatedReportsService.php© CreateActivityLoggedEvent.phpAutomatedReportsCommand.php xleam.ono© CreateHeldActivityEvent.php© UserPilotActivityListener.php© RequestGenerateReportJob.php© AutomatedReportResult.phpc) Automatedreport.onoclass AutomatedReportsCommand extends CommandA2^1031041051061071081091101111121131114115116117118119120121122123124125126127128129130131132133134137138139140141142143144145146147148149150151private function processReports(string $frequency): void$this->logger->info(self::LOG_PREFIX . " Processing $frequency reports");$reportId = $this->›option( key: 'report-id');if ($reportId !== null) {$reports = $this->getReportById($reportId);1 else {// Get all enabled, not deleted reports with active teams for the speci 51$reports = $this->reportRepository->getActiveReportsByFrequency($freque 61$this->logger->info(self::LOG_PREFIX ." Found ($reports->count()} $frequer 7071%/** @var AutomatedReport $report */foreach ($reports as $report) {100 ₽$this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report jC117'reportUvid' = $report->getUvid(),118€'teamId' => $report->getTeamId(),'frequency' => $report->getFrequency(),157 8 >'type' => $report->getType(),1):185 %$job = $report->isAskJiminnyReport()? new RequestGenerateAskJiminnyReportJob($report->getUvid()):new RequestGenerateReportJob($report->getUvid()):$this->dispatcher->dispatch($job);$this->dispatcher->dispatchSync($job);206 ₽ >224225 ₽226228230private function getReportById(string $reportId): Collection1254$report = $this->reportRepository->findById0rUvid($reportId);if ($report === null) {$this->logger->warning(self::LOG_PREFIX'Report not found for --repf237$this->warn( string: "Report not found: {$reportId}");236242243return collect();if (! $report->getStatus()) {$this->Logger->warning(self::LOG_PREFIX'reportId' => SreportId.'reportUvid' => $report->getUvid(),Report is inactive, proces:2481):249250mantial nuon 250g= custom.log= laravel.logA SF [jiminny@localhost]Hs local liminnyalocalnostconsole PRODL console [EUlA console [STAGING]© ActivitySearch.php© AskJiminnyReportActivityService.php•OnDemandV2Controller.php© HistoryService.phprilterDerinitioncollection.ongcriiera.onpCh Ask. liminnvRenortActivitvServiceTest.ohn X© RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityServiceTof26private LoggerInterface&MockUbject Logger;9 usagesBLMSAYprivate AskJiminnvReportActivityService Sservice:29 6t >Eprotected function setup(): voidf...}11 usagesprivate function makeFilter(string $key, ?string $valve):8 usagesprivate function makeUser(): User&Mock0bjectf...}8 usagesprivate function makeSavedSearch(array $filters): Searchspublic function testGetActivityIdsForSavedSearchReturnsIcpublic function testGetActivityIdsForSavedSearchReturnsEnpublic function testGetActivityIdsFilters0utDateFiltersOpublic function testGetActivityIdsFilters0utClosingPeriocpubLic tunction cescbecactivicyLashandLesarrayr1lterscpublic function testGetActivityIdsHandLesScalarFilters:public function testGetActivityIdsPassesNonZeroSequenceNLsusen = sthis->makelcenD$savedSearch = $this->makeSavedSearch([]);$filterSet = $this->createMock( originalClassName: Filtern$this->activitySearch->method( constraint:detArravr$capturedCriteria = null;$this->activitySearch->expects($this->once))->method ( constraint: 'getOnDemandPageFilterSet')->willReturnCallback(function (Criteria $criteria$this->elasticRepository->method( constraint: 'onDeman$this->logger->method( constraint:anto')"sthis->service->aetActivitvldsForSavedSearch/SsavedS$this->assertNotNull($capturedCriteria);$this->assertFalse($capturedCriteria->isFirstRequest(Support Daily • in 2h 42 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:18:23CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Explain it to me again. Why is there issue with thhat? Where is it expected and why do I need to work with that. How is it used inDelllaluvzcontroes vasee oll saveuoedichl. Une los m on celllane ane iiOnSkdImbуnedoT LheLeveLyoetVaceronorL44-0e snoule de sallitwLet me read the OnDemandV2Controller to understand how it builds criteria there:Read OnDemanavzconNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php: 90-93:0 phpVO Repository OnDemandActivitySearch\Criteria::createFromRequest(arrav meroesrequesoaluor' umir => 00c0unt 'oade"$user->getTimezone()It passes Srequest->all() - which includes sequence_number from the URL (e.g. sequence_number=4 from your staging URL). So when a user has beenpaginating on the frontend, sequence_number is naturally non-zero.The full explanationyou didn't ask for them:FilterActiv1tvburat zonkangelhsiauist kecuestaouncskenererurns true wnen seauenceNumber === u wnenttsine "trstreduestneseumolci detauirs kickinauromaricalveventDefault on first requestmin_duration = 1 minEffectDroos 0-secono activitiesActivityRecordedonly_recorded = 1Recorded activities onlvUser's own groupRestricts to user's groupFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest = false → no implicit defaults →returns 15 activities.AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence_number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-onlv + duration>1 together matchednothing.Why sequence_number=1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionally stripped (that's existing logic in DATE_FILTER_KEYS )3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representsSetting sequence number=1 is the minimal, correct signal: "this is not a fresh session open, don't apply page-load defaults". The criteria is otherwise builtidentically to how the controller builds it - same Criteria::createFromRequest, same get0nDemandPageFilterSet, same onDemandSearchIds0nly - so theresults will now match.Ö ul ...Ask anything (2*L)+ <> Code Claude Sonnet 4.6Winasun leamsuir-o( 4 spaces...
|
NULL
|
|
11192
|
221
|
32
|
2026-04-14T09:18:31.378273+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158311378_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditViewFV faVsco.js vProject vNavigat PhpStormFileEditViewFV faVsco.js vProject vNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelpDProphetAiv D Reports© AutomatedReportsCl© AutomatedReportsRe© AutomatedReportsSt© CreateMockAskJimir© DeleteReportComma© GenerateMarketingR© Team.php© Usage.phpD Slack_leamsD TracksO TranscriptionO TwilioD UsersVocabularyDZoom© CoachingFeedbacksUpr© Command.php© CreateDatabaseUsers.pc Daraoase oecountoi© DeleteOldAiCrmNotesC:© DeleteS3LeftoversComiDevPostmanCommand./© DiarizeViaAiParticipantk© EncryptTokensComman© EngagementStatsRegen© FeatureFlagsHelper.php© FixCrossTenantlssues.p(c) -ushro espermissionsa(e) Generatelnterna wepho• GroupSetDefaultLangua© HelperTruncateCoachin© HubspotJournalPollingC© HubspotWebhookServic©ImportRecording.php© ImportUsersFromCsvFil© IterateUsersCommand.p© JiminnyCacheClearCom© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoCommMakeslackLvecoaching(c Manacescimror eam.oc мarkbranchrorenvironh© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesCom(e Recalculatebealkisksco(c) Removebe eremarkersc(e) Remove-xoiredNudoesc removeunusecrarcloC ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© ReportController.phpAulomaleakeporissendcommand.onoJiminnybeouecommana.ong© AddLayoutEntities.php) AutomatedReportsService.php© CreateActivityLoggedEvent.phpAutomatedReportsCommand.php x= custom.log= laravel.logA SF [jiminny@localhost]leam.onoHs local liminnyalocalnostconsole PRODL console [EUl© CreateHeldActivityEvent.php© UserPilotActivityListener.phpA console [STAGING]© ActivitySearch.php© AskJiminnyReportActivityService.php•OnDemandV2Controller.php© HistoryService.phprilterDerinitioncollection.ongcrilena.onp© RequestGenerateReportJob.phpCh Ask. liminnvRenortActivitvServiceTest.ohn X(©) AutomatedReportResult.php© AutomatedReport.php© RequestGenerateAskJiminnyReportJobTest.phpclass AutomatedReportsCommand extends CommandA2 ^public function handle(): intNNclass AskJiminnyReportActivityServiceTofprivate LoggerInterface&MockUbject Logger;I/ Process quarterly reports on the first day of January, April, July, and9 usagesif ($isFirstDay0fMonth && $isQuarterlyMonth) {private AskJiminnvReportActivitvService Sservice:$this->processReports ( frequency: AutomatedReportsService: :FREQUENCY_QUAR 28BLMSAY1001011031041051061071081091101111121131114111.11811912012112212312412512612712812913013113213313413529 6t >$this->logger->info(self::LOG_PREFIX . ' Completed');rerurn or* Process reports for a specific frequency.* @param string $frequency71>* @return void100%private function processReports(string $frequency): void117118€$this->logger->info(self::LOG_PREFIX . " Processing $frequency reports");156157 % >$reportId = $this->option( key: 'report-id');if ($reportId !== null) ($reports = $this->getReportById($reportId);7 else {185 %206 ₽ >// Get all enabled, not deleted reports with active teams for the speci224geports = $this->reportRepository->getActiveReportsByFrequency($freque225 P226227$this->logger->info(self::LOG_PREFIX . " Found {$reports->count()} $frequer 228229230/** @var AutomatedReport $report */foreach ($reports as $report) {$this->logger->info(self::LOG_PREFIXDispatching Generate Report jc232'reportUuid'→> $report->getUvid(),233'teamId' => $report->getTeamId(),'frequency'=> $report->getFrequency(),'type' = $report->getType(),1):n00 =sreoorre>sasko.mnnvreoort? new RequestGenerateAskJiminnyReportJob($report->getUuid()):new RequestGenerateReportJob($report->getUvid()):$this->dispatcher->dispatch($job);$this->dispatcher->dispatchSync($job);249252protected function setUp(): voidf...}11 usagesprivate function makeFilter(string $key, ?string $valve):8 usagesprivate function makeUser(): User&Mock0bjectf...}8 usagesprivate function makeSavedSearch(array $filters): Searchspublic function testGetActivityIdsForSavedSearchReturnsIcpublic function testGetActivityIdsForSavedSearchReturnsEnpublic function testGetActivityIdsFilters0utDateFiltersOpublic function testGetActivityIdsFilters0utClosingPeriocpubLic tunction cescbecactivicyLashandLesarrayr1lterscpublic function testGetActivityIdsHandLesScalarFilters:public function testGetActivityIdsPassesNonZeroSequenceNL$user = $this->makeUser();SsavedSearch = $this->makeSavedSearch([]):$filterSet = $this->createMock( originalClassName: Filtern$this->activitySearch->method( constraint:detArravr$capturedCriteria = null;$this->activitySearch->expects($this->once())->method ( constraint: 'getOnDemandPageFilterSet')->willReturnCallback(function (Criteria $criteria$this->elasticRepository->method( constraint: 'onDemansthns-> lodden->method constraint: "into")"sthis->service->aetActivitvldsForSavedSearch(SsavedS$this->assertNotNull($capturedCriteria);$this->assertFalse($capturedCriteria->isFirstRequest(Support Daily • in 2h 42 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:18:31CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Explain it to me again. Why is there issue with thhat? Where is it expected and why do I need to work with that. How is it used inDelllaluvzcontroes vasee oll saveuoedichl. Une los m on celllane ane iiOnSkdImbуnedoT LheLeveLyoetVaceronorL44-0e snoule de sallitwLet me read the OnDemandV2Controller to understand how it builds criteria there:Read OnDemanavzcontNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php: 90-93:0 phpVO Repository OnDemandActivitySearch\Criteria:: createFromRequest(arrav meroesrequesoaluor' umir => 00c0unt 'oade"$user->getTimezone()It passes Srequest->all() - which includes sequence_number from the URL (e.g. sequence_number=4 from your staging URL). So when a user has beenpaginating on the frontend, sequence_number is naturally non-zero.The full explanationyou didn't ask for them:FilterActiv1tvburat zonkangelhsiauist kecuestaouncskenererurns true wnen seauenceNumber === u wnenttsine "trstreduestneseumolci detauirs kickinauromaricalveventDefault on first requestmin_duration = 1 minEffectDroos 0-secono activitiesActivityRecordedonly_recorded = 1Recorded activities onlvUser's own groupRestricts to user's groupFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest = false → no implicit defaults →returns 15 activities.AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence_number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-onlv + duration>1 together matchednothing.Why sequence_number=1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionally stripped (that's existing logic in DATE_FILTER_KEYS )3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representsSetting sequence number=1 is the minimal, correct signal: "this is not a fresh session open, don't apply page-load defaults". The criteria is otherwise builtidentically to how the controller builds it - same Criteria::createFromRequest, same get0nDemandPageFilterSet, same onDemandSearchIds0nly - so theresults will now match.Ö ul ...Ask anything (2*L)+ <> Code Claude Sonnet 4.6Winasun leamsuir-o( 4 spaces...
|
NULL
|
6643753981202508460
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileEditViewFV faVsco.js vProject vNavigat PhpStormFileEditViewFV faVsco.js vProject vNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelpDProphetAiv D Reports© AutomatedReportsCl© AutomatedReportsRe© AutomatedReportsSt© CreateMockAskJimir© DeleteReportComma© GenerateMarketingR© Team.php© Usage.phpD Slack_leamsD TracksO TranscriptionO TwilioD UsersVocabularyDZoom© CoachingFeedbacksUpr© Command.php© CreateDatabaseUsers.pc Daraoase oecountoi© DeleteOldAiCrmNotesC:© DeleteS3LeftoversComiDevPostmanCommand./© DiarizeViaAiParticipantk© EncryptTokensComman© EngagementStatsRegen© FeatureFlagsHelper.php© FixCrossTenantlssues.p(c) -ushro espermissionsa(e) Generatelnterna wepho• GroupSetDefaultLangua© HelperTruncateCoachin© HubspotJournalPollingC© HubspotWebhookServic©ImportRecording.php© ImportUsersFromCsvFil© IterateUsersCommand.p© JiminnyCacheClearCom© JiminnyDebugCommanc© JiminnySetEncryptedTo© JiminnyTokenInfoCommMakeslackLvecoaching(c Manacescimror eam.oc мarkbranchrorenvironh© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesCom(e Recalculatebealkisksco(c) Removebe eremarkersc(e) Remove-xoiredNudoesc removeunusecrarcloC ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© ReportController.phpAulomaleakeporissendcommand.onoJiminnybeouecommana.ong© AddLayoutEntities.php) AutomatedReportsService.php© CreateActivityLoggedEvent.phpAutomatedReportsCommand.php x= custom.log= laravel.logA SF [jiminny@localhost]leam.onoHs local liminnyalocalnostconsole PRODL console [EUl© CreateHeldActivityEvent.php© UserPilotActivityListener.phpA console [STAGING]© ActivitySearch.php© AskJiminnyReportActivityService.php•OnDemandV2Controller.php© HistoryService.phprilterDerinitioncollection.ongcrilena.onp© RequestGenerateReportJob.phpCh Ask. liminnvRenortActivitvServiceTest.ohn X(©) AutomatedReportResult.php© AutomatedReport.php© RequestGenerateAskJiminnyReportJobTest.phpclass AutomatedReportsCommand extends CommandA2 ^public function handle(): intNNclass AskJiminnyReportActivityServiceTofprivate LoggerInterface&MockUbject Logger;I/ Process quarterly reports on the first day of January, April, July, and9 usagesif ($isFirstDay0fMonth && $isQuarterlyMonth) {private AskJiminnvReportActivitvService Sservice:$this->processReports ( frequency: AutomatedReportsService: :FREQUENCY_QUAR 28BLMSAY1001011031041051061071081091101111121131114111.11811912012112212312412512612712812913013113213313413529 6t >$this->logger->info(self::LOG_PREFIX . ' Completed');rerurn or* Process reports for a specific frequency.* @param string $frequency71>* @return void100%private function processReports(string $frequency): void117118€$this->logger->info(self::LOG_PREFIX . " Processing $frequency reports");156157 % >$reportId = $this->option( key: 'report-id');if ($reportId !== null) ($reports = $this->getReportById($reportId);7 else {185 %206 ₽ >// Get all enabled, not deleted reports with active teams for the speci224geports = $this->reportRepository->getActiveReportsByFrequency($freque225 P226227$this->logger->info(self::LOG_PREFIX . " Found {$reports->count()} $frequer 228229230/** @var AutomatedReport $report */foreach ($reports as $report) {$this->logger->info(self::LOG_PREFIXDispatching Generate Report jc232'reportUuid'→> $report->getUvid(),233'teamId' => $report->getTeamId(),'frequency'=> $report->getFrequency(),'type' = $report->getType(),1):n00 =sreoorre>sasko.mnnvreoort? new RequestGenerateAskJiminnyReportJob($report->getUuid()):new RequestGenerateReportJob($report->getUvid()):$this->dispatcher->dispatch($job);$this->dispatcher->dispatchSync($job);249252protected function setUp(): voidf...}11 usagesprivate function makeFilter(string $key, ?string $valve):8 usagesprivate function makeUser(): User&Mock0bjectf...}8 usagesprivate function makeSavedSearch(array $filters): Searchspublic function testGetActivityIdsForSavedSearchReturnsIcpublic function testGetActivityIdsForSavedSearchReturnsEnpublic function testGetActivityIdsFilters0utDateFiltersOpublic function testGetActivityIdsFilters0utClosingPeriocpubLic tunction cescbecactivicyLashandLesarrayr1lterscpublic function testGetActivityIdsHandLesScalarFilters:public function testGetActivityIdsPassesNonZeroSequenceNL$user = $this->makeUser();SsavedSearch = $this->makeSavedSearch([]):$filterSet = $this->createMock( originalClassName: Filtern$this->activitySearch->method( constraint:detArravr$capturedCriteria = null;$this->activitySearch->expects($this->once())->method ( constraint: 'getOnDemandPageFilterSet')->willReturnCallback(function (Criteria $criteria$this->elasticRepository->method( constraint: 'onDemansthns-> lodden->method constraint: "into")"sthis->service->aetActivitvldsForSavedSearch(SsavedS$this->assertNotNull($capturedCriteria);$this->assertFalse($capturedCriteria->isFirstRequest(Support Daily • in 2h 42 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:18:31CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Explain it to me again. Why is there issue with thhat? Where is it expected and why do I need to work with that. How is it used inDelllaluvzcontroes vasee oll saveuoedichl. Une los m on celllane ane iiOnSkdImbуnedoT LheLeveLyoetVaceronorL44-0e snoule de sallitwLet me read the OnDemandV2Controller to understand how it builds criteria there:Read OnDemanavzcontNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php: 90-93:0 phpVO Repository OnDemandActivitySearch\Criteria:: createFromRequest(arrav meroesrequesoaluor' umir => 00c0unt 'oade"$user->getTimezone()It passes Srequest->all() - which includes sequence_number from the URL (e.g. sequence_number=4 from your staging URL). So when a user has beenpaginating on the frontend, sequence_number is naturally non-zero.The full explanationyou didn't ask for them:FilterActiv1tvburat zonkangelhsiauist kecuestaouncskenererurns true wnen seauenceNumber === u wnenttsine "trstreduestneseumolci detauirs kickinauromaricalveventDefault on first requestmin_duration = 1 minEffectDroos 0-secono activitiesActivityRecordedonly_recorded = 1Recorded activities onlvUser's own groupRestricts to user's groupFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest = false → no implicit defaults →returns 15 activities.AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence_number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-onlv + duration>1 together matchednothing.Why sequence_number=1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionally stripped (that's existing logic in DATE_FILTER_KEYS )3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representsSetting sequence number=1 is the minimal, correct signal: "this is not a fresh session open, don't apply page-load defaults". The criteria is otherwise builtidentically to how the controller builds it - same Criteria::createFromRequest, same get0nDemandPageFilterSet, same onDemandSearchIds0nly - so theresults will now match.Ö ul ...Ask anything (2*L)+ <> Code Claude Sonnet 4.6Winasun leamsuir-o( 4 spaces...
|
11190
|
|
11194
|
221
|
33
|
2026-04-14T09:18:35.514937+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158315514_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileFV faVsco.js vProject vViewNavigateCod PhpStormFileFV faVsco.js vProject vViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-liminny k vToolsWindowHelpProphetAiv D Reports© AutomatedReportsCl© AutomatedReportsRe© AutomatedReportsSt© CreateMockAskJimir© DeleteReportComma© GenerateMarketingR© Team.php© Usage.phpD Slack_leamsD TracksO TranscriptionO TwilioD UsersVocabularyDZoom© CoachingFeedbacksUpr© Command.phpcreateDatabaseusers.pc Daraoase oecountoi© DeleteOldAiCrmNotesC:© DeleteS3LeftoversComiDevPostmanCommand./© DiarizeViaAiParticipantk© EncryptTokensComman© EngagementStatsRegen© FeatureFlagsHelper.php© FixCrossTenantissues.p© FlushRolesPermissionsC© GeneratelnternalWebho• GroupSetDefaultLangua© HelperTruncateCoachin© HubspotJournalPollingC© HubspotWebhookServic©ImportRecording.php@ Imnortli|sercFromCcvEil© IterateUsersCommand.gcJiminnvcacheclearcom(c) minnv Deouacommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoaching© ManageScimForTeam.p© MarkBranchForEnvironn© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php(©) PurgeSoftDeletedOppol© PurgeSyncBatchesCom© RecalculateDealRisksCaC) RemoveDeleteMarkersd© RemoveExpiredNudgest© RemoveUnusedParticip:© ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCorTests passed: 1 (9 minutes ago)© ReportController.phpAulomaleakeporissendcommand.onoJiminnybeouecommana.ong© AddLayoutEntities.php) AutomatedReportsService.phpAutomatedReportsCommand.php x= custom.log= laravel.logA SF [jiminny@localhost]leam.onpHs local liminnyalocalnostconsole PRODL console [EUlCrealenctivityLoggeaevent.ong© CreateHeldActivityEvent.php© UserPilotActivityListener.phpA console [STAGING]© ActivitySearch.php© AskJiminnyReportActivityService.php•OnDemandV2Controller.php© HistoryService.phprilterDerinitioncollection.ongcrilena.onp© RequestGenerateReportJob.phpCh Ask. liminnvRenortActivitvServiceTest.ohn X(©) AutomatedReportResult.phpc) Automatedreport.ono© RequestGenerateAskJiminnyReportJobTest.phpclass AutomatedReportsCommand extends Command103A2^private function processReports(string $frequency): void20class AskJiminnyReportActivityServiceTofBLMSAYprivate LoggerInterface&MockUbject Logger;109$reports = $this->getReportById($reportId);9 usages110felse {private AskJiminnvReportActivityService Sservice:111ber aul cndoeo, nor celereo reoorts vun aculve ceals tor tie soec112Sreports = $this->reportRepository->qetActiveReportsByFrequency(Sfreque29 6t >protected function setUp(): voidf...}11311411 usages115$this->logger->info(self::LOG_PREFIX . " Found {$reports->count()} $frequerprivate function makeFilter(string $key, ?string $valve):116117/** @var AutomatedReport $report */8 usages118foreach ($reports as $report) {private function makeUser(): User&Mock0bjectf...}119$this->Logger->info(self::L0G_PREFIX . ' Dispatching Generate Report jc 61120'reportuuid' = $report->getUvid(),8 usagesprivate function makeSavedSearch(array $filters): Searchs121122'teamId' => $report->getTeamId(,'frequency' →> $report->getFrequency(),123'type' => $report→>getType(),71%public function testGetActivityIdsForSavedSearchReturnsIc124I):125100 %public function testGetActivityIdsForSavedSearchReturnsEn126$job = $report->isAskJiminnyReport()117127? new RequestGenerateAskJiminnyReportJob($report->getUuid())118€public function testGetActivityIdsFilters0utDateFiltersO128: new RequestGenerateReportJob($report->getUvid());156157129public function testGetActivityIdsFilters0utClosingPerioc130131//this->dispatcher->dispatch($job);$this->dispatcher->dispatchSync($job);185 %pubLic tunction cescbecactivicyLashandLesarrayr1ltersc132133134135private function getReportById(string $reportId): Collection206 ₽ >224225 ₽226public function testGetActivityIdsHandLesScalarFilters:public function testGetActivityIdsPassesNonZeroSequenceNL136137$report = $this->reportRepository->findById0rUuid($reportId);susen = sthis->makelcan$savedSearch = $this->makeSavedSearch([]);13813911491141142if ($report === null) {$this->Logger->warning(self::LOG_PREFIX . ' Report not found for --nepc230$this->warn( string: "Report not found: {$reportId}");$filterSet = $this->createMock( originalClassName: Filtern$this->activitySearch->method( constraint:'getArrayFi143return collect();144145146147148149234235if (! $report->getStatus()) {236$this->logger->warning(self::LOG_PREFIX ' Report is inactive, process237'reportId' => $reportId,242'reportUuid' => $report->getUuid(),$capturedCriteria = null;$this->activitySearch->expects($this->once))->method ( constraint: 'getOnDemandPageFilterSet')->willReturnCallback(function (Criteria $criteria$this->elasticRepository->method( constraint: 'onDemansthns-> lodden->method constraint: "into')"1501):151sthis->warn( string: 'Report 1s lnactive - processing anyway (manual oversthis->service->aetActivitvldsForSavedSearch/SsavedS152154155156157$team = $report->getTeam();if ($team->getStatus() !== Team: :STATUS_ACTIVE) {248249$this->Logger->warning(self::LOG_PREFIXTeam is not active, process 256'reportId' => $reportId,$this->assertNotNull($capturedCriteria);$this->assertFalse($capturedCriteria->isFirstRequest(Support Daily • in 2h 42 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:18:35CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Explain it to me again. Why is there issue with thhat? Where is it expected and why do I need to work with that. How is it used inDelllaluvzcontroes vasee oll saveuoedichl Ine los m on celllane ane ilOnSkdILmbуnedoT LheLeveLyoetVeceronorL44-0o snoule de salllewLet me read the OnDemandV2Controller to understand how it builds criteria there:Read OnDemanavzcontNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php: 90-93:0 phpVO Repository OnDemandActivitySearch\Criteria::createFromRequest(arrav meroesrequesoaluor' umir => 00c0unt "oade$user->getTimezone()It passes Srequest->all() - which includes sequence_number from the URL (e.g. sequence_number=4 from your staging URL). So when a user has beenpaginating on the frontend, sequence_number is naturally non-zero.The full explanationyou didn't ask for them:FilterActiv1tvburat zonkangelhsiauist kecuestaouncskenererurns true wnen seauenceNumber === u wnenttsine "trstreduestneseumolci detauirs kickinauromaricalveventDefault on first requestmin_duration = 1 minEffectDroos 0-secono activitiesActivityRecordedonly_recorded = 1Recorded activities onlvUser's own groupRestricts to user's groupFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest = false → no implicit defaults →returns 15 activities.AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence_number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-onlv + duration>1 together matchednothing.Why sequence_number=1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionally stripped (that's existing logic in DATE_FILTER_KEYS )3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representsSetting sequence number=1 is the minimal, correct signal: "this is not a fresh session open, don't apply page-load defaults". The criteria is otherwise builtidentically to how the controller builds it - same Criteria::createFromRequest, same get0nDemandPageFilterSet, same onDemandSearchIdsOnly - so theresults will now match.Ö ul ...Ask anything (2*L)+ <> Code Claude Sonnet 4.6winasun leams112:14uir-o( 4 spaces...
|
NULL
|
4891540024753990974
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileFV faVsco.js vProject vViewNavigateCod PhpStormFileFV faVsco.js vProject vViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-liminny k vToolsWindowHelpProphetAiv D Reports© AutomatedReportsCl© AutomatedReportsRe© AutomatedReportsSt© CreateMockAskJimir© DeleteReportComma© GenerateMarketingR© Team.php© Usage.phpD Slack_leamsD TracksO TranscriptionO TwilioD UsersVocabularyDZoom© CoachingFeedbacksUpr© Command.phpcreateDatabaseusers.pc Daraoase oecountoi© DeleteOldAiCrmNotesC:© DeleteS3LeftoversComiDevPostmanCommand./© DiarizeViaAiParticipantk© EncryptTokensComman© EngagementStatsRegen© FeatureFlagsHelper.php© FixCrossTenantissues.p© FlushRolesPermissionsC© GeneratelnternalWebho• GroupSetDefaultLangua© HelperTruncateCoachin© HubspotJournalPollingC© HubspotWebhookServic©ImportRecording.php@ Imnortli|sercFromCcvEil© IterateUsersCommand.gcJiminnvcacheclearcom(c) minnv Deouacommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoaching© ManageScimForTeam.p© MarkBranchForEnvironn© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php(©) PurgeSoftDeletedOppol© PurgeSyncBatchesCom© RecalculateDealRisksCaC) RemoveDeleteMarkersd© RemoveExpiredNudgest© RemoveUnusedParticip:© ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCorTests passed: 1 (9 minutes ago)© ReportController.phpAulomaleakeporissendcommand.onoJiminnybeouecommana.ong© AddLayoutEntities.php) AutomatedReportsService.phpAutomatedReportsCommand.php x= custom.log= laravel.logA SF [jiminny@localhost]leam.onpHs local liminnyalocalnostconsole PRODL console [EUlCrealenctivityLoggeaevent.ong© CreateHeldActivityEvent.php© UserPilotActivityListener.phpA console [STAGING]© ActivitySearch.php© AskJiminnyReportActivityService.php•OnDemandV2Controller.php© HistoryService.phprilterDerinitioncollection.ongcrilena.onp© RequestGenerateReportJob.phpCh Ask. liminnvRenortActivitvServiceTest.ohn X(©) AutomatedReportResult.phpc) Automatedreport.ono© RequestGenerateAskJiminnyReportJobTest.phpclass AutomatedReportsCommand extends Command103A2^private function processReports(string $frequency): void20class AskJiminnyReportActivityServiceTofBLMSAYprivate LoggerInterface&MockUbject Logger;109$reports = $this->getReportById($reportId);9 usages110felse {private AskJiminnvReportActivityService Sservice:111ber aul cndoeo, nor celereo reoorts vun aculve ceals tor tie soec112Sreports = $this->reportRepository->qetActiveReportsByFrequency(Sfreque29 6t >protected function setUp(): voidf...}11311411 usages115$this->logger->info(self::LOG_PREFIX . " Found {$reports->count()} $frequerprivate function makeFilter(string $key, ?string $valve):116117/** @var AutomatedReport $report */8 usages118foreach ($reports as $report) {private function makeUser(): User&Mock0bjectf...}119$this->Logger->info(self::L0G_PREFIX . ' Dispatching Generate Report jc 61120'reportuuid' = $report->getUvid(),8 usagesprivate function makeSavedSearch(array $filters): Searchs121122'teamId' => $report->getTeamId(,'frequency' →> $report->getFrequency(),123'type' => $report→>getType(),71%public function testGetActivityIdsForSavedSearchReturnsIc124I):125100 %public function testGetActivityIdsForSavedSearchReturnsEn126$job = $report->isAskJiminnyReport()117127? new RequestGenerateAskJiminnyReportJob($report->getUuid())118€public function testGetActivityIdsFilters0utDateFiltersO128: new RequestGenerateReportJob($report->getUvid());156157129public function testGetActivityIdsFilters0utClosingPerioc130131//this->dispatcher->dispatch($job);$this->dispatcher->dispatchSync($job);185 %pubLic tunction cescbecactivicyLashandLesarrayr1ltersc132133134135private function getReportById(string $reportId): Collection206 ₽ >224225 ₽226public function testGetActivityIdsHandLesScalarFilters:public function testGetActivityIdsPassesNonZeroSequenceNL136137$report = $this->reportRepository->findById0rUuid($reportId);susen = sthis->makelcan$savedSearch = $this->makeSavedSearch([]);13813911491141142if ($report === null) {$this->Logger->warning(self::LOG_PREFIX . ' Report not found for --nepc230$this->warn( string: "Report not found: {$reportId}");$filterSet = $this->createMock( originalClassName: Filtern$this->activitySearch->method( constraint:'getArrayFi143return collect();144145146147148149234235if (! $report->getStatus()) {236$this->logger->warning(self::LOG_PREFIX ' Report is inactive, process237'reportId' => $reportId,242'reportUuid' => $report->getUuid(),$capturedCriteria = null;$this->activitySearch->expects($this->once))->method ( constraint: 'getOnDemandPageFilterSet')->willReturnCallback(function (Criteria $criteria$this->elasticRepository->method( constraint: 'onDemansthns-> lodden->method constraint: "into')"1501):151sthis->warn( string: 'Report 1s lnactive - processing anyway (manual oversthis->service->aetActivitvldsForSavedSearch/SsavedS152154155156157$team = $report->getTeam();if ($team->getStatus() !== Team: :STATUS_ACTIVE) {248249$this->Logger->warning(self::LOG_PREFIXTeam is not active, process 256'reportId' => $reportId,$this->assertNotNull($capturedCriteria);$this->assertFalse($capturedCriteria->isFirstRequest(Support Daily • in 2h 42 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:18:35CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Explain it to me again. Why is there issue with thhat? Where is it expected and why do I need to work with that. How is it used inDelllaluvzcontroes vasee oll saveuoedichl Ine los m on celllane ane ilOnSkdILmbуnedoT LheLeveLyoetVeceronorL44-0o snoule de salllewLet me read the OnDemandV2Controller to understand how it builds criteria there:Read OnDemanavzcontNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php: 90-93:0 phpVO Repository OnDemandActivitySearch\Criteria::createFromRequest(arrav meroesrequesoaluor' umir => 00c0unt "oade$user->getTimezone()It passes Srequest->all() - which includes sequence_number from the URL (e.g. sequence_number=4 from your staging URL). So when a user has beenpaginating on the frontend, sequence_number is naturally non-zero.The full explanationyou didn't ask for them:FilterActiv1tvburat zonkangelhsiauist kecuestaouncskenererurns true wnen seauenceNumber === u wnenttsine "trstreduestneseumolci detauirs kickinauromaricalveventDefault on first requestmin_duration = 1 minEffectDroos 0-secono activitiesActivityRecordedonly_recorded = 1Recorded activities onlvUser's own groupRestricts to user's groupFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest = false → no implicit defaults →returns 15 activities.AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence_number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-onlv + duration>1 together matchednothing.Why sequence_number=1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionally stripped (that's existing logic in DATE_FILTER_KEYS )3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representsSetting sequence number=1 is the minimal, correct signal: "this is not a fresh session open, don't apply page-load defaults". The criteria is otherwise builtidentically to how the controller builds it - same Criteria::createFromRequest, same get0nDemandPageFilterSet, same onDemandSearchIdsOnly - so theresults will now match.Ö ul ...Ask anything (2*L)+ <> Code Claude Sonnet 4.6winasun leams112:14uir-o( 4 spaces...
|
NULL
|
|
11196
|
221
|
34
|
2026-04-14T09:18:55.441547+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158335441_m2.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReportsCommand.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
3
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Services\Kiosk\AutomatedReports;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityActualDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityUpdatedDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\DealInsights\ClosingPeriodFilter;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\User;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
class AskJiminnyReportActivityServiceTest extends TestCase
{
private ActivitySearch&MockObject $activitySearch;
private ElasticActivityRepository&MockObject $elasticRepository;
private LoggerInterface&MockObject $logger;
private AskJiminnyReportActivityService $service;
protected function setUp(): void
{
$this->activitySearch = $this->createMock(ActivitySearch::class);
$this->elasticRepository = $this->createMock(ElasticActivityRepository::class);
$this->logger = $this->createMock(LoggerInterface::class);
$this->service = new AskJiminnyReportActivityService(
$this->activitySearch,
$this->elasticRepository,
$this->logger,
);
}
private function makeFilter(string $key, ?string $value): SearchFilter&MockObject
{
$filter = $this->createMock(SearchFilter::class);
$filter->method('getFilterProperty')->willReturn($key);
$filter->method('getFilterValue')->willReturn($value);
return $filter;
}
private function makeUser(): User&MockObject
{
$tz = new \DateTimeZone('UTC');
$user = $this->createMock(User::class);
$user->method('getTimezone')->willReturn($tz);
$user->method('getId')->willReturn(1);
$user->method('getUuid')->willReturn('user-uuid');
return $user;
}
private function makeSavedSearch(array $filters): Search&MockObject
{
$savedSearch = $this->createMock(Search::class);
$savedSearch->method('getId')->willReturn(42);
$savedSearch->method('getFilters')->willReturn(new \Illuminate\Support\LazyCollection($filters));
return $savedSearch;
}
public function testGetActivityIdsForSavedSearchReturnsIds(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->expects($this->once())
->method('getArrayFilterKeys')
->with($user)
->willReturn([]);
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturn($filterSet);
$this->elasticRepository->expects($this->once())
->method('onDemandSearchIdsOnly')
->willReturn(['id-1', 'id-2', 'id-3']);
$this->logger->expects($this->once())
->method('info')
->with('[AskJiminnyReport] Fetched activity IDs for saved search');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1', 'id-2', 'id-3'], $result);
}
public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->expects($this->once())->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEmpty($result);
}
public function testGetActivityIdsFiltersOutDateFilters(): void
{
$user = $this->makeUser();
$nonDateFilter = $this->makeFilter('owner_id', '123');
$startDateFilter = $this->makeFilter(ActivityActualDate::PARAM_START_DATE, '2025-01-01 00:00:00');
$endDateFilter = $this->makeFilter(ActivityActualDate::PARAM_END_DATE, '2025-01-31 23:59:59');
$updatedFromFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_FROM, '2025-01-01 00:00:00');
$updatedToFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_TO, '2025-01-31 23:59:59');
$savedSearch = $this->makeSavedSearch([
$nonDateFilter,
$startDateFilter,
$endDateFilter,
$updatedFromFilter,
$updatedToFilter,
]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$capturedCriteria = null;
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {
$capturedCriteria = $criteria;
return $filterSet;
});
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->method('info');
$this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertNotNull($capturedCriteria);
}
public function testGetActivityIdsFiltersOutClosingPeriodDateFilters(): void
{
$user = $this->makeUser();
$closingStartFilter = $this->makeFilter(ClosingPeriodFilter::KEY_START_DATE, '2025-01-01');
$closingEndFilter = $this->makeFilter(ClosingPeriodFilter::KEY_END_DATE, '2025-03-31');
$regularFilter = $this->makeFilter('rep_id', '99');
$savedSearch = $this->makeSavedSearch([
$closingStartFilter,
$closingEndFilter,
$regularFilter,
]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1'], $result);
}
public function testGetActivityIdsHandlesArrayFilters(): void
{
$user = $this->makeUser();
$filter1 = $this->makeFilter('outcome', 'positive');
$filter2 = $this->makeFilter('outcome', 'negative');
$savedSearch = $this->makeSavedSearch([$filter1, $filter2]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn(['outcome']);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1'], $result);
}
public function testGetActivityIdsHandlesScalarFilters(): void
{
$user = $this->makeUser();
$filter = $this->makeFilter('direction', 'inbound');
$savedSearch = $this->makeSavedSearch([$filter]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-5']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-5'], $result);
}
public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$capturedCriteria = null;
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {
$capturedCriteria = $criteria;
return $filterSet;
});
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->method('info');
$this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertNotNull($capturedCriteria);
$this->assertFalse($capturedCriteria->isFirstRequest());
}
public function testGetActivityIdsLogsWithCorrectContext(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['a', 'b']);
$this->logger->expects($this->once())
->method('info')
->with(
'[AskJiminnyReport] Fetched activity IDs for saved search',
$this->callback(fn ($context) => $context['saved_search_id'] === 42
&& $context['user_id'] === 1
&& $context['activity_count'] === 2)
);
$this->service->getActivityIdsForSavedSearch($savedSearch, $user);
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands\Reports;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Contracts\Bus\Dispatcher as BusDispatcher;
use Illuminate\Support\Collection;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\RequestGenerateReportJob;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\Team;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Psr\Log\LoggerInterface;
class AutomatedReportsCommand extends Command
{
/**
* Log prefix for all log messages
*/
private const string LOG_PREFIX = '[automated-reports]';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'automated-reports {--report-id= : Process a specific report by ID or UUID (bypasses frequency scheduling)}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly). Use --report-id to manually trigger a specific report by ID or UUID.';
public function __construct(
private readonly LoggerInterface $logger,
private readonly BusDispatcher $dispatcher,
private readonly AutomatedReportsRepository $reportRepository
) {
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle(): int
{
$this->logger->info(self::LOG_PREFIX . ' Started');
$now = Carbon::now();
$isMonday = $now->isMonday();
$isFirstDayOfMonth = $now->day === 1;
$currentMonth = $now->month;
// Check if the current month is a quarterly month (January, April, July, October)
$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);
$this->logger->info(self::LOG_PREFIX . ' Checking conditions', [
'isMonday' => $isMonday,
'isFirstDayOfMonth' => $isFirstDayOfMonth,
'currentMonth' => $currentMonth,
'isQuarterlyMonth' => $isQuarterlyMonth,
]);
// Process daily reports
$this->processReports(AutomatedReportsService::FREQUENCY_DAILY);
// Process weekly reports on Mondays
if ($isMonday) {
$this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);
}
// Process monthly reports on the first day of the month
if ($isFirstDayOfMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);
}
// Process quarterly reports on the first day of January, April, July, and October
if ($isFirstDayOfMonth && $isQuarterlyMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);
}
$this->logger->info(self::LOG_PREFIX . ' Completed');
return 0;
}
/**
* Process reports for a specific frequency.
*
* @param string $frequency
*
* @return void
*/
private function processReports(string $frequency): void
{
$this->logger->info(self::LOG_PREFIX . " Processing $frequency reports");
$reportId = $this->option('report-id');
if ($reportId !== null) {
$reports = $this->getReportById($reportId);
} else {
// Get all enabled, not deleted reports with active teams for the specified frequency
$reports = $this->reportRepository->getActiveReportsByFrequency($frequency);
}
$this->logger->info(self::LOG_PREFIX . " Found {$reports->count()} $frequency reports to process");
/** @var AutomatedReport $report */
foreach ($reports as $report) {
$this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [
'reportUuid' => $report->getUuid(),
'teamId' => $report->getTeamId(),
'frequency' => $report->getFrequency(),
'type' => $report->getType(),
]);
$job = $report->isAskJiminnyReport()
? new RequestGenerateAskJiminnyReportJob($report->getUuid())
: new RequestGenerateReportJob($report->getUuid());
$this->dispatcher->dispatch($job);
}
}
private function getReportById(string $reportId): Collection
{
$report = $this->reportRepository->findByIdOrUuid($reportId);
if ($report === null) {
$this->logger->warning(self::LOG_PREFIX . ' Report not found for --report-id', ['reportId' => $reportId]);
$this->warn("Report not found: {$reportId}");
return collect();
}
if (! $report->getStatus()) {
$this->logger->warning(self::LOG_PREFIX . ' Report is inactive, processing anyway (manual override)', [
'reportId' => $reportId,
'reportUuid' => $report->getUuid(),
]);
$this->warn('Report is inactive — processing anyway (manual override).');
}
$team = $report->getTeam();
if ($team->getStatus() !== Team::STATUS_ACTIVE) {
$this->logger->warning(self::LOG_PREFIX . ' Team is not active, processing anyway (manual override)', [
'reportId' => $reportId,
'reportUuid' => $report->getUuid(),
'teamId' => $report->getTeamId(),
'teamStatus' => $team->getStatus(),
]);
$this->warn("Team #{$report->getTeamId()} is not active — processing anyway (manual override).");
}
if ($report->isExpired()) {
$this->logger->warning(self::LOG_PREFIX . ' Report is expired, processing anyway (manual override)', [
'reportId' => $reportId,
'reportUuid' => $report->getUuid(),
'expiresAt' => $report->getExpiresAt()?->toDateString(),
]);
$this->warn('Report is expired (expires_at: ' . $report->getExpiresAt()?->toDateString() . ') — processing anyway (manual override).');
}
return collect([$report]);
}
}
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.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","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.7589844,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceT…Defaults","depth":6,"bounds":{"left":0.7769531,"top":0.017361112,"width":0.12382813,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.575,"top":0.19513889,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"3","depth":4,"bounds":{"left":0.58671874,"top":0.19513889,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.5980469,"top":0.19375,"width":0.00859375,"height":0.015972223},"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.60664064,"top":0.19375,"width":0.008203125,"height":0.015972223},"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\\Services\\Kiosk\\AutomatedReports;\n\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityActualDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityUpdatedDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealInsights\\ClosingPeriodFilter;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AskJiminnyReportActivityService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse PHPUnit\\Framework\\TestCase;\nuse Psr\\Log\\LoggerInterface;\n\nclass AskJiminnyReportActivityServiceTest extends TestCase\n{\n private ActivitySearch&MockObject $activitySearch;\n private ElasticActivityRepository&MockObject $elasticRepository;\n private LoggerInterface&MockObject $logger;\n private AskJiminnyReportActivityService $service;\n\n protected function setUp(): void\n {\n $this->activitySearch = $this->createMock(ActivitySearch::class);\n $this->elasticRepository = $this->createMock(ElasticActivityRepository::class);\n $this->logger = $this->createMock(LoggerInterface::class);\n\n $this->service = new AskJiminnyReportActivityService(\n $this->activitySearch,\n $this->elasticRepository,\n $this->logger,\n );\n }\n\n private function makeFilter(string $key, ?string $value): SearchFilter&MockObject\n {\n $filter = $this->createMock(SearchFilter::class);\n $filter->method('getFilterProperty')->willReturn($key);\n $filter->method('getFilterValue')->willReturn($value);\n\n return $filter;\n }\n\n private function makeUser(): User&MockObject\n {\n $tz = new \\DateTimeZone('UTC');\n $user = $this->createMock(User::class);\n $user->method('getTimezone')->willReturn($tz);\n $user->method('getId')->willReturn(1);\n $user->method('getUuid')->willReturn('user-uuid');\n\n return $user;\n }\n\n private function makeSavedSearch(array $filters): Search&MockObject\n {\n $savedSearch = $this->createMock(Search::class);\n $savedSearch->method('getId')->willReturn(42);\n $savedSearch->method('getFilters')->willReturn(new \\Illuminate\\Support\\LazyCollection($filters));\n\n return $savedSearch;\n }\n\n public function testGetActivityIdsForSavedSearchReturnsIds(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->expects($this->once())\n ->method('getArrayFilterKeys')\n ->with($user)\n ->willReturn([]);\n\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturn($filterSet);\n\n $this->elasticRepository->expects($this->once())\n ->method('onDemandSearchIdsOnly')\n ->willReturn(['id-1', 'id-2', 'id-3']);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with('[AskJiminnyReport] Fetched activity IDs for saved search');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1', 'id-2', 'id-3'], $result);\n }\n\n public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n\n $this->logger->expects($this->once())->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEmpty($result);\n }\n\n public function testGetActivityIdsFiltersOutDateFilters(): void\n {\n $user = $this->makeUser();\n\n $nonDateFilter = $this->makeFilter('owner_id', '123');\n $startDateFilter = $this->makeFilter(ActivityActualDate::PARAM_START_DATE, '2025-01-01 00:00:00');\n $endDateFilter = $this->makeFilter(ActivityActualDate::PARAM_END_DATE, '2025-01-31 23:59:59');\n $updatedFromFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_FROM, '2025-01-01 00:00:00');\n $updatedToFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_TO, '2025-01-31 23:59:59');\n\n $savedSearch = $this->makeSavedSearch([\n $nonDateFilter,\n $startDateFilter,\n $endDateFilter,\n $updatedFromFilter,\n $updatedToFilter,\n ]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n\n $capturedCriteria = null;\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {\n $capturedCriteria = $criteria;\n\n return $filterSet;\n });\n\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n $this->logger->method('info');\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertNotNull($capturedCriteria);\n }\n\n public function testGetActivityIdsFiltersOutClosingPeriodDateFilters(): void\n {\n $user = $this->makeUser();\n\n $closingStartFilter = $this->makeFilter(ClosingPeriodFilter::KEY_START_DATE, '2025-01-01');\n $closingEndFilter = $this->makeFilter(ClosingPeriodFilter::KEY_END_DATE, '2025-03-31');\n $regularFilter = $this->makeFilter('rep_id', '99');\n\n $savedSearch = $this->makeSavedSearch([\n $closingStartFilter,\n $closingEndFilter,\n $regularFilter,\n ]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1'], $result);\n }\n\n public function testGetActivityIdsHandlesArrayFilters(): void\n {\n $user = $this->makeUser();\n\n $filter1 = $this->makeFilter('outcome', 'positive');\n $filter2 = $this->makeFilter('outcome', 'negative');\n\n $savedSearch = $this->makeSavedSearch([$filter1, $filter2]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn(['outcome']);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1'], $result);\n }\n\n public function testGetActivityIdsHandlesScalarFilters(): void\n {\n $user = $this->makeUser();\n\n $filter = $this->makeFilter('direction', 'inbound');\n $savedSearch = $this->makeSavedSearch([$filter]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-5']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-5'], $result);\n }\n\n public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n\n $capturedCriteria = null;\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {\n $capturedCriteria = $criteria;\n\n return $filterSet;\n });\n\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n $this->logger->method('info');\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertNotNull($capturedCriteria);\n $this->assertFalse($capturedCriteria->isFirstRequest());\n }\n\n public function testGetActivityIdsLogsWithCorrectContext(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['a', 'b']);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with(\n '[AskJiminnyReport] Fetched activity IDs for saved search',\n $this->callback(fn ($context) => $context['saved_search_id'] === 42\n && $context['user_id'] === 1\n && $context['activity_count'] === 2)\n );\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n }\n}","depth":4,"bounds":{"left":0.4296875,"top":0.0,"width":0.3347656,"height":1.0},"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Services\\Kiosk\\AutomatedReports;\n\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityActualDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityUpdatedDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealInsights\\ClosingPeriodFilter;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AskJiminnyReportActivityService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse PHPUnit\\Framework\\TestCase;\nuse Psr\\Log\\LoggerInterface;\n\nclass AskJiminnyReportActivityServiceTest extends TestCase\n{\n private ActivitySearch&MockObject $activitySearch;\n private ElasticActivityRepository&MockObject $elasticRepository;\n private LoggerInterface&MockObject $logger;\n private AskJiminnyReportActivityService $service;\n\n protected function setUp(): void\n {\n $this->activitySearch = $this->createMock(ActivitySearch::class);\n $this->elasticRepository = $this->createMock(ElasticActivityRepository::class);\n $this->logger = $this->createMock(LoggerInterface::class);\n\n $this->service = new AskJiminnyReportActivityService(\n $this->activitySearch,\n $this->elasticRepository,\n $this->logger,\n );\n }\n\n private function makeFilter(string $key, ?string $value): SearchFilter&MockObject\n {\n $filter = $this->createMock(SearchFilter::class);\n $filter->method('getFilterProperty')->willReturn($key);\n $filter->method('getFilterValue')->willReturn($value);\n\n return $filter;\n }\n\n private function makeUser(): User&MockObject\n {\n $tz = new \\DateTimeZone('UTC');\n $user = $this->createMock(User::class);\n $user->method('getTimezone')->willReturn($tz);\n $user->method('getId')->willReturn(1);\n $user->method('getUuid')->willReturn('user-uuid');\n\n return $user;\n }\n\n private function makeSavedSearch(array $filters): Search&MockObject\n {\n $savedSearch = $this->createMock(Search::class);\n $savedSearch->method('getId')->willReturn(42);\n $savedSearch->method('getFilters')->willReturn(new \\Illuminate\\Support\\LazyCollection($filters));\n\n return $savedSearch;\n }\n\n public function testGetActivityIdsForSavedSearchReturnsIds(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->expects($this->once())\n ->method('getArrayFilterKeys')\n ->with($user)\n ->willReturn([]);\n\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturn($filterSet);\n\n $this->elasticRepository->expects($this->once())\n ->method('onDemandSearchIdsOnly')\n ->willReturn(['id-1', 'id-2', 'id-3']);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with('[AskJiminnyReport] Fetched activity IDs for saved search');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1', 'id-2', 'id-3'], $result);\n }\n\n public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n\n $this->logger->expects($this->once())->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEmpty($result);\n }\n\n public function testGetActivityIdsFiltersOutDateFilters(): void\n {\n $user = $this->makeUser();\n\n $nonDateFilter = $this->makeFilter('owner_id', '123');\n $startDateFilter = $this->makeFilter(ActivityActualDate::PARAM_START_DATE, '2025-01-01 00:00:00');\n $endDateFilter = $this->makeFilter(ActivityActualDate::PARAM_END_DATE, '2025-01-31 23:59:59');\n $updatedFromFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_FROM, '2025-01-01 00:00:00');\n $updatedToFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_TO, '2025-01-31 23:59:59');\n\n $savedSearch = $this->makeSavedSearch([\n $nonDateFilter,\n $startDateFilter,\n $endDateFilter,\n $updatedFromFilter,\n $updatedToFilter,\n ]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n\n $capturedCriteria = null;\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {\n $capturedCriteria = $criteria;\n\n return $filterSet;\n });\n\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n $this->logger->method('info');\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertNotNull($capturedCriteria);\n }\n\n public function testGetActivityIdsFiltersOutClosingPeriodDateFilters(): void\n {\n $user = $this->makeUser();\n\n $closingStartFilter = $this->makeFilter(ClosingPeriodFilter::KEY_START_DATE, '2025-01-01');\n $closingEndFilter = $this->makeFilter(ClosingPeriodFilter::KEY_END_DATE, '2025-03-31');\n $regularFilter = $this->makeFilter('rep_id', '99');\n\n $savedSearch = $this->makeSavedSearch([\n $closingStartFilter,\n $closingEndFilter,\n $regularFilter,\n ]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1'], $result);\n }\n\n public function testGetActivityIdsHandlesArrayFilters(): void\n {\n $user = $this->makeUser();\n\n $filter1 = $this->makeFilter('outcome', 'positive');\n $filter2 = $this->makeFilter('outcome', 'negative');\n\n $savedSearch = $this->makeSavedSearch([$filter1, $filter2]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn(['outcome']);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1'], $result);\n }\n\n public function testGetActivityIdsHandlesScalarFilters(): void\n {\n $user = $this->makeUser();\n\n $filter = $this->makeFilter('direction', 'inbound');\n $savedSearch = $this->makeSavedSearch([$filter]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-5']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-5'], $result);\n }\n\n public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n\n $capturedCriteria = null;\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {\n $capturedCriteria = $criteria;\n\n return $filterSet;\n });\n\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n $this->logger->method('info');\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertNotNull($capturedCriteria);\n $this->assertFalse($capturedCriteria->isFirstRequest());\n }\n\n public function testGetActivityIdsLogsWithCorrectContext(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['a', 'b']);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with(\n '[AskJiminnyReport] Fetched activity IDs for saved search',\n $this->callback(fn ($context) => $context['saved_search_id'] === 42\n && $context['user_id'] === 1\n && $context['activity_count'] === 2)\n );\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.3761719,"top":0.19513889,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.3875,"top":0.19375,"width":0.00859375,"height":0.015972223},"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.39609376,"top":0.19375,"width":0.008203125,"height":0.015972223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands\\Reports;\n\nuse Carbon\\Carbon;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Bus\\Dispatcher as BusDispatcher;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateReportJob;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Psr\\Log\\LoggerInterface;\n\nclass AutomatedReportsCommand extends Command\n{\n /**\n * Log prefix for all log messages\n */\n private const string LOG_PREFIX = '[automated-reports]';\n\n /**\n * The name and signature of the console command.\n *\n * @var string\n */\n protected $signature = 'automated-reports {--report-id= : Process a specific report by ID or UUID (bypasses frequency scheduling)}';\n\n /**\n * The console command description.\n *\n * @var string\n */\n protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly). Use --report-id to manually trigger a specific report by ID or UUID.';\n\n\n public function __construct(\n private readonly LoggerInterface $logger,\n private readonly BusDispatcher $dispatcher,\n private readonly AutomatedReportsRepository $reportRepository\n ) {\n parent::__construct();\n }\n\n /**\n * Execute the console command.\n *\n * @return int\n */\n public function handle(): int\n {\n $this->logger->info(self::LOG_PREFIX . ' Started');\n\n $now = Carbon::now();\n $isMonday = $now->isMonday();\n $isFirstDayOfMonth = $now->day === 1;\n $currentMonth = $now->month;\n\n // Check if the current month is a quarterly month (January, April, July, October)\n $isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);\n\n $this->logger->info(self::LOG_PREFIX . ' Checking conditions', [\n 'isMonday' => $isMonday,\n 'isFirstDayOfMonth' => $isFirstDayOfMonth,\n 'currentMonth' => $currentMonth,\n 'isQuarterlyMonth' => $isQuarterlyMonth,\n ]);\n\n // Process daily reports\n $this->processReports(AutomatedReportsService::FREQUENCY_DAILY);\n\n // Process weekly reports on Mondays\n if ($isMonday) {\n $this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);\n }\n\n // Process monthly reports on the first day of the month\n if ($isFirstDayOfMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);\n }\n\n // Process quarterly reports on the first day of January, April, July, and October\n if ($isFirstDayOfMonth && $isQuarterlyMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);\n }\n\n $this->logger->info(self::LOG_PREFIX . ' Completed');\n\n return 0;\n }\n\n /**\n * Process reports for a specific frequency.\n *\n * @param string $frequency\n *\n * @return void\n */\n private function processReports(string $frequency): void\n {\n $this->logger->info(self::LOG_PREFIX . \" Processing $frequency reports\");\n\n $reportId = $this->option('report-id');\n if ($reportId !== null) {\n $reports = $this->getReportById($reportId);\n } else {\n // Get all enabled, not deleted reports with active teams for the specified frequency\n $reports = $this->reportRepository->getActiveReportsByFrequency($frequency);\n }\n\n $this->logger->info(self::LOG_PREFIX . \" Found {$reports->count()} $frequency reports to process\");\n\n /** @var AutomatedReport $report */\n foreach ($reports as $report) {\n $this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [\n 'reportUuid' => $report->getUuid(),\n 'teamId' => $report->getTeamId(),\n 'frequency' => $report->getFrequency(),\n 'type' => $report->getType(),\n ]);\n\n $job = $report->isAskJiminnyReport()\n ? new RequestGenerateAskJiminnyReportJob($report->getUuid())\n : new RequestGenerateReportJob($report->getUuid());\n\n $this->dispatcher->dispatch($job);\n }\n }\n\n private function getReportById(string $reportId): Collection\n {\n $report = $this->reportRepository->findByIdOrUuid($reportId);\n\n if ($report === null) {\n $this->logger->warning(self::LOG_PREFIX . ' Report not found for --report-id', ['reportId' => $reportId]);\n $this->warn(\"Report not found: {$reportId}\");\n\n return collect();\n }\n\n if (! $report->getStatus()) {\n $this->logger->warning(self::LOG_PREFIX . ' Report is inactive, processing anyway (manual override)', [\n 'reportId' => $reportId,\n 'reportUuid' => $report->getUuid(),\n ]);\n $this->warn('Report is inactive — processing anyway (manual override).');\n }\n\n $team = $report->getTeam();\n if ($team->getStatus() !== Team::STATUS_ACTIVE) {\n $this->logger->warning(self::LOG_PREFIX . ' Team is not active, processing anyway (manual override)', [\n 'reportId' => $reportId,\n 'reportUuid' => $report->getUuid(),\n 'teamId' => $report->getTeamId(),\n 'teamStatus' => $team->getStatus(),\n ]);\n $this->warn(\"Team #{$report->getTeamId()} is not active — processing anyway (manual override).\");\n }\n\n if ($report->isExpired()) {\n $this->logger->warning(self::LOG_PREFIX . ' Report is expired, processing anyway (manual override)', [\n 'reportId' => $reportId,\n 'reportUuid' => $report->getUuid(),\n 'expiresAt' => $report->getExpiresAt()?->toDateString(),\n ]);\n $this->warn('Report is expired (expires_at: ' . $report->getExpiresAt()?->toDateString() . ') — processing anyway (manual override).');\n }\n\n return collect([$report]);\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands\\Reports;\n\nuse Carbon\\Carbon;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Bus\\Dispatcher as BusDispatcher;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateReportJob;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Psr\\Log\\LoggerInterface;\n\nclass AutomatedReportsCommand extends Command\n{\n /**\n * Log prefix for all log messages\n */\n private const string LOG_PREFIX = '[automated-reports]';\n\n /**\n * The name and signature of the console command.\n *\n * @var string\n */\n protected $signature = 'automated-reports {--report-id= : Process a specific report by ID or UUID (bypasses frequency scheduling)}';\n\n /**\n * The console command description.\n *\n * @var string\n */\n protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly). Use --report-id to manually trigger a specific report by ID or UUID.';\n\n\n public function __construct(\n private readonly LoggerInterface $logger,\n private readonly BusDispatcher $dispatcher,\n private readonly AutomatedReportsRepository $reportRepository\n ) {\n parent::__construct();\n }\n\n /**\n * Execute the console command.\n *\n * @return int\n */\n public function handle(): int\n {\n $this->logger->info(self::LOG_PREFIX . ' Started');\n\n $now = Carbon::now();\n $isMonday = $now->isMonday();\n $isFirstDayOfMonth = $now->day === 1;\n $currentMonth = $now->month;\n\n // Check if the current month is a quarterly month (January, April, July, October)\n $isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);\n\n $this->logger->info(self::LOG_PREFIX . ' Checking conditions', [\n 'isMonday' => $isMonday,\n 'isFirstDayOfMonth' => $isFirstDayOfMonth,\n 'currentMonth' => $currentMonth,\n 'isQuarterlyMonth' => $isQuarterlyMonth,\n ]);\n\n // Process daily reports\n $this->processReports(AutomatedReportsService::FREQUENCY_DAILY);\n\n // Process weekly reports on Mondays\n if ($isMonday) {\n $this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);\n }\n\n // Process monthly reports on the first day of the month\n if ($isFirstDayOfMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);\n }\n\n // Process quarterly reports on the first day of January, April, July, and October\n if ($isFirstDayOfMonth && $isQuarterlyMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);\n }\n\n $this->logger->info(self::LOG_PREFIX . ' Completed');\n\n return 0;\n }\n\n /**\n * Process reports for a specific frequency.\n *\n * @param string $frequency\n *\n * @return void\n */\n private function processReports(string $frequency): void\n {\n $this->logger->info(self::LOG_PREFIX . \" Processing $frequency reports\");\n\n $reportId = $this->option('report-id');\n if ($reportId !== null) {\n $reports = $this->getReportById($reportId);\n } else {\n // Get all enabled, not deleted reports with active teams for the specified frequency\n $reports = $this->reportRepository->getActiveReportsByFrequency($frequency);\n }\n\n $this->logger->info(self::LOG_PREFIX . \" Found {$reports->count()} $frequency reports to process\");\n\n /** @var AutomatedReport $report */\n foreach ($reports as $report) {\n $this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [\n 'reportUuid' => $report->getUuid(),\n 'teamId' => $report->getTeamId(),\n 'frequency' => $report->getFrequency(),\n 'type' => $report->getType(),\n ]);\n\n $job = $report->isAskJiminnyReport()\n ? new RequestGenerateAskJiminnyReportJob($report->getUuid())\n : new RequestGenerateReportJob($report->getUuid());\n\n $this->dispatcher->dispatch($job);\n }\n }\n\n private function getReportById(string $reportId): Collection\n {\n $report = $this->reportRepository->findByIdOrUuid($reportId);\n\n if ($report === null) {\n $this->logger->warning(self::LOG_PREFIX . ' Report not found for --report-id', ['reportId' => $reportId]);\n $this->warn(\"Report not found: {$reportId}\");\n\n return collect();\n }\n\n if (! $report->getStatus()) {\n $this->logger->warning(self::LOG_PREFIX . ' Report is inactive, processing anyway (manual override)', [\n 'reportId' => $reportId,\n 'reportUuid' => $report->getUuid(),\n ]);\n $this->warn('Report is inactive — processing anyway (manual override).');\n }\n\n $team = $report->getTeam();\n if ($team->getStatus() !== Team::STATUS_ACTIVE) {\n $this->logger->warning(self::LOG_PREFIX . ' Team is not active, processing anyway (manual override)', [\n 'reportId' => $reportId,\n 'reportUuid' => $report->getUuid(),\n 'teamId' => $report->getTeamId(),\n 'teamStatus' => $team->getStatus(),\n ]);\n $this->warn(\"Team #{$report->getTeamId()} is not active — processing anyway (manual override).\");\n }\n\n if ($report->isExpired()) {\n $this->logger->warning(self::LOG_PREFIX . ' Report is expired, processing anyway (manual override)', [\n 'reportId' => $reportId,\n 'reportUuid' => $report->getUuid(),\n 'expiresAt' => $report->getExpiresAt()?->toDateString(),\n ]);\n $this->warn('Report is expired (expires_at: ' . $report->getExpiresAt()?->toDateString() . ') — processing anyway (manual override).');\n }\n\n return collect([$report]);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.0140625,"top":0.041666668,"width":0.028515626,"height":0.021527778},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
2353231120370746233
|
2960206221971779892
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
3
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Services\Kiosk\AutomatedReports;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityActualDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityUpdatedDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\DealInsights\ClosingPeriodFilter;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\User;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
class AskJiminnyReportActivityServiceTest extends TestCase
{
private ActivitySearch&MockObject $activitySearch;
private ElasticActivityRepository&MockObject $elasticRepository;
private LoggerInterface&MockObject $logger;
private AskJiminnyReportActivityService $service;
protected function setUp(): void
{
$this->activitySearch = $this->createMock(ActivitySearch::class);
$this->elasticRepository = $this->createMock(ElasticActivityRepository::class);
$this->logger = $this->createMock(LoggerInterface::class);
$this->service = new AskJiminnyReportActivityService(
$this->activitySearch,
$this->elasticRepository,
$this->logger,
);
}
private function makeFilter(string $key, ?string $value): SearchFilter&MockObject
{
$filter = $this->createMock(SearchFilter::class);
$filter->method('getFilterProperty')->willReturn($key);
$filter->method('getFilterValue')->willReturn($value);
return $filter;
}
private function makeUser(): User&MockObject
{
$tz = new \DateTimeZone('UTC');
$user = $this->createMock(User::class);
$user->method('getTimezone')->willReturn($tz);
$user->method('getId')->willReturn(1);
$user->method('getUuid')->willReturn('user-uuid');
return $user;
}
private function makeSavedSearch(array $filters): Search&MockObject
{
$savedSearch = $this->createMock(Search::class);
$savedSearch->method('getId')->willReturn(42);
$savedSearch->method('getFilters')->willReturn(new \Illuminate\Support\LazyCollection($filters));
return $savedSearch;
}
public function testGetActivityIdsForSavedSearchReturnsIds(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->expects($this->once())
->method('getArrayFilterKeys')
->with($user)
->willReturn([]);
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturn($filterSet);
$this->elasticRepository->expects($this->once())
->method('onDemandSearchIdsOnly')
->willReturn(['id-1', 'id-2', 'id-3']);
$this->logger->expects($this->once())
->method('info')
->with('[AskJiminnyReport] Fetched activity IDs for saved search');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1', 'id-2', 'id-3'], $result);
}
public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->expects($this->once())->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEmpty($result);
}
public function testGetActivityIdsFiltersOutDateFilters(): void
{
$user = $this->makeUser();
$nonDateFilter = $this->makeFilter('owner_id', '123');
$startDateFilter = $this->makeFilter(ActivityActualDate::PARAM_START_DATE, '2025-01-01 00:00:00');
$endDateFilter = $this->makeFilter(ActivityActualDate::PARAM_END_DATE, '2025-01-31 23:59:59');
$updatedFromFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_FROM, '2025-01-01 00:00:00');
$updatedToFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_TO, '2025-01-31 23:59:59');
$savedSearch = $this->makeSavedSearch([
$nonDateFilter,
$startDateFilter,
$endDateFilter,
$updatedFromFilter,
$updatedToFilter,
]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$capturedCriteria = null;
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {
$capturedCriteria = $criteria;
return $filterSet;
});
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->method('info');
$this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertNotNull($capturedCriteria);
}
public function testGetActivityIdsFiltersOutClosingPeriodDateFilters(): void
{
$user = $this->makeUser();
$closingStartFilter = $this->makeFilter(ClosingPeriodFilter::KEY_START_DATE, '2025-01-01');
$closingEndFilter = $this->makeFilter(ClosingPeriodFilter::KEY_END_DATE, '2025-03-31');
$regularFilter = $this->makeFilter('rep_id', '99');
$savedSearch = $this->makeSavedSearch([
$closingStartFilter,
$closingEndFilter,
$regularFilter,
]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1'], $result);
}
public function testGetActivityIdsHandlesArrayFilters(): void
{
$user = $this->makeUser();
$filter1 = $this->makeFilter('outcome', 'positive');
$filter2 = $this->makeFilter('outcome', 'negative');
$savedSearch = $this->makeSavedSearch([$filter1, $filter2]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn(['outcome']);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1'], $result);
}
public function testGetActivityIdsHandlesScalarFilters(): void
{
$user = $this->makeUser();
$filter = $this->makeFilter('direction', 'inbound');
$savedSearch = $this->makeSavedSearch([$filter]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-5']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-5'], $result);
}
public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$capturedCriteria = null;
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {
$capturedCriteria = $criteria;
return $filterSet;
});
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->method('info');
$this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertNotNull($capturedCriteria);
$this->assertFalse($capturedCriteria->isFirstRequest());
}
public function testGetActivityIdsLogsWithCorrectContext(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['a', 'b']);
$this->logger->expects($this->once())
->method('info')
->with(
'[AskJiminnyReport] Fetched activity IDs for saved search',
$this->callback(fn ($context) => $context['saved_search_id'] === 42
&& $context['user_id'] === 1
&& $context['activity_count'] === 2)
);
$this->service->getActivityIdsForSavedSearch($savedSearch, $user);
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands\Reports;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Contracts\Bus\Dispatcher as BusDispatcher;
use Illuminate\Support\Collection;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\RequestGenerateReportJob;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\Team;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Psr\Log\LoggerInterface;
class AutomatedReportsCommand extends Command
{
/**
* Log prefix for all log messages
*/
private const string LOG_PREFIX = '[automated-reports]';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'automated-reports {--report-id= : Process a specific report by ID or UUID (bypasses frequency scheduling)}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly). Use --report-id to manually trigger a specific report by ID or UUID.';
public function __construct(
private readonly LoggerInterface $logger,
private readonly BusDispatcher $dispatcher,
private readonly AutomatedReportsRepository $reportRepository
) {
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle(): int
{
$this->logger->info(self::LOG_PREFIX . ' Started');
$now = Carbon::now();
$isMonday = $now->isMonday();
$isFirstDayOfMonth = $now->day === 1;
$currentMonth = $now->month;
// Check if the current month is a quarterly month (January, April, July, October)
$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);
$this->logger->info(self::LOG_PREFIX . ' Checking conditions', [
'isMonday' => $isMonday,
'isFirstDayOfMonth' => $isFirstDayOfMonth,
'currentMonth' => $currentMonth,
'isQuarterlyMonth' => $isQuarterlyMonth,
]);
// Process daily reports
$this->processReports(AutomatedReportsService::FREQUENCY_DAILY);
// Process weekly reports on Mondays
if ($isMonday) {
$this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);
}
// Process monthly reports on the first day of the month
if ($isFirstDayOfMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);
}
// Process quarterly reports on the first day of January, April, July, and October
if ($isFirstDayOfMonth && $isQuarterlyMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);
}
$this->logger->info(self::LOG_PREFIX . ' Completed');
return 0;
}
/**
* Process reports for a specific frequency.
*
* @param string $frequency
*
* @return void
*/
private function processReports(string $frequency): void
{
$this->logger->info(self::LOG_PREFIX . " Processing $frequency reports");
$reportId = $this->option('report-id');
if ($reportId !== null) {
$reports = $this->getReportById($reportId);
} else {
// Get all enabled, not deleted reports with active teams for the specified frequency
$reports = $this->reportRepository->getActiveReportsByFrequency($frequency);
}
$this->logger->info(self::LOG_PREFIX . " Found {$reports->count()} $frequency reports to process");
/** @var AutomatedReport $report */
foreach ($reports as $report) {
$this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [
'reportUuid' => $report->getUuid(),
'teamId' => $report->getTeamId(),
'frequency' => $report->getFrequency(),
'type' => $report->getType(),
]);
$job = $report->isAskJiminnyReport()
? new RequestGenerateAskJiminnyReportJob($report->getUuid())
: new RequestGenerateReportJob($report->getUuid());
$this->dispatcher->dispatch($job);
}
}
private function getReportById(string $reportId): Collection
{
$report = $this->reportRepository->findByIdOrUuid($reportId);
if ($report === null) {
$this->logger->warning(self::LOG_PREFIX . ' Report not found for --report-id', ['reportId' => $reportId]);
$this->warn("Report not found: {$reportId}");
return collect();
}
if (! $report->getStatus()) {
$this->logger->warning(self::LOG_PREFIX . ' Report is inactive, processing anyway (manual override)', [
'reportId' => $reportId,
'reportUuid' => $report->getUuid(),
]);
$this->warn('Report is inactive — processing anyway (manual override).');
}
$team = $report->getTeam();
if ($team->getStatus() !== Team::STATUS_ACTIVE) {
$this->logger->warning(self::LOG_PREFIX . ' Team is not active, processing anyway (manual override)', [
'reportId' => $reportId,
'reportUuid' => $report->getUuid(),
'teamId' => $report->getTeamId(),
'teamStatus' => $team->getStatus(),
]);
$this->warn("Team #{$report->getTeamId()} is not active — processing anyway (manual override).");
}
if ($report->isExpired()) {
$this->logger->warning(self::LOG_PREFIX . ' Report is expired, processing anyway (manual override)', [
'reportId' => $reportId,
'reportUuid' => $report->getUuid(),
'expiresAt' => $report->getExpiresAt()?->toDateString(),
]);
$this->warn('Report is expired (expires_at: ' . $report->getExpiresAt()?->toDateString() . ') — processing anyway (manual override).');
}
return collect([$report]);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
11194
|
|
11198
|
221
|
35
|
2026-04-14T09:19:05.875224+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158345875_m2.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReportsCommand.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","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.7589844,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceT…Defaults","depth":6,"bounds":{"left":0.7769531,"top":0.017361112,"width":0.12382813,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-6884388984026562300
|
-8636777060039973950
|
click
|
hybrid
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
PhpStormFileFV faVsco.js vViewNavigateCodeLaravelRefactor#11894 on JY-18909-automated-reports-ask-iminny K vToolsWindowHelpProject vProphetAiv D Reports© AutomatedReportsCl© AutomatedReportsRe© AutomatedReportsSt© CreateMockAskJimir© DeleteReportComma© GenerateMarketingR© Team.php© Usage.phpD Slack• TeamsD TracksO TranscriptionO TwilioD UsersVocabularyDZoom© CoachingFeedbacksUpr© Command.php© CreateDatabaseUsers.pc Daraoase oecountoi© DeleteOldAiCrmNotesC:© DeleteS3LeftoversComiDevPostmanCommand./© DiarizeViaAiParticipantk© EncryptTokensComman© EngagementStatsRegen© FeatureFlagsHelper.php© FixCrossTenantissues.p© FlushRolesPermissionsC© GeneratelnternalWebho• GroupSetDefaultLangua© HelperTruncateCoachin© HubspotJournalPollingC© HubspotWebhookServic© ImportRecording.php@ Imnortl|sercFromCcvEill( Iteratel IsersCommandr(C) JiminnvCacheClearCom(e) lminnv Deouacommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoaching© ManageScimForTeam.p© MarkBranchForEnvironn© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php(©) PurgeSoftDeletedOppol© PurgeSyncBatchesCom© RecalculateDealRisksCa© RemoveDeleteMarkersC© RemoveExpiredNudgest© RemoveUnusedParticip:© ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCorTests passed: 1 (9 minutes ago)© ReportController.phpAulomaleakeporissendcommand.ongJiminnybeouecommana.ong© AddLayoutEntities.php) AutomatedReportsService.phpAutomatedReportsCommand.phpXleam.onpCrealenctivityLoggeaevent.ong© CreateHeldActivityEvent.php© UserPilotActivityListener.php© RequestGenerateReportJob.php© AutomatedReportResult.phpc) Automatedreport.onoclass AutomatedReportsCommand extends Command103private function processReports(string $frequency): void123'type' => $report->getType(),124I):l125126127128$job = $report->isAskJiminnyReport()?new RequestGenerateAskJiminnyReportJob($report->getUvid()): new RequestGenerateReportJob($report->getUvid());129130$this->dispatcher->dispatch($job);131132133A2^136137138139140141142143144145146147148149150151152153155156157158159160161162163164166167168169private function getReportById(string $reportid): Collection$report = $this->reportRepository->findById0rUuid($reportId);71%if ($report === null) {100 % ›$this->Logger->warning(self::LOG_PREFIX .' Report not found for --repc117$this->warn( string: "Report not found: {$reportId}");118€return collect();157 >if (! $report->getStatus()) {sthis->logger->warning(seLf::LOG_PREFIX . ' Report is inactive, proces: 206 %%'reportId' => $reportId,'reportUuid' => $report->getUuid(),185 %224225 ₽1):$this->warn( string:'Report is inactive - processing anyway (manual over$team = $report->getTeam();if ($team->getStatus() !== Team: :STATUS_ACTIVE) (sthis->Logger->warning(self::LOG_PREFIX.renortd => sSrenortid.recorcuue' so sredori-sceru.lo'teamId' => $report->getTeamId(),'teamStatus' => $team->getStatus(),23012542551):237$this->warn( string: "Team #{$report->getTeamId()} is not active - proces242243if ($report->isExpired()) {$this->logger->warning(self::LOG_PREFIX . ' Report is expired, processi245'reportId' = SreportId,'reportuuld' => sreport->getuuido,'expiresAt' => $report->getExpiresAt()?->toDateString(),1248249I);$this->warn( string: 'Report is expired (expires_at: ' . $report->getExpi252= custom.log= laravel.logA SF [jiminny@localhost]Hs local liminnyalocalnostconsole PRODIL console [EUlA console [STAGING]© ActivitySearch.php© AskJiminnyReportActivityService.php•OnDemandV2Controller.php© HistoryService.phprilterDerinitioncollection.ongcriiera.onpCh Ask. liminnvRenortActivitvServiceTest.ohn X© RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityServiceTofprivate LoggerInterface&MockUbject Logger;9 usagesBLMSAYprivate AskJiminnvReportActivitvService Sservice:29 6t >protected function setUp(): voidf...}11 usagesprivate function makeFilter(string $key, ?string $valve):8 usagesprivate function makeUser(): User&Mock0bjectf...}8 usagesprivate function makeSavedSearch(array $filters): Searchspublic function testGetActivityIdsForSavedSearchReturnsIcpublic function testGetActivityIdsForSavedSearchReturnsEnpublic function testGetActivityIdsFilters0utDateFiltersOpublic function testGetActivityIdsFilters0utClosingPeriocpubLic tunction cescbecactivicyLashandLesarrayr1lcersc.public function testGetActivityIdsHandLesScalarFilters:public function testGetActivityIdsPassesNonZeroSequenceNL$user = $this-›makeUser();$savedSearch = $this->makeSavedSearch([]);atllterser s suus-crearerock orcinacassname: rlte.nunus-vacuvlrvsearch->necnoo constraintdetarravra$capturedCriteria = null;$this->activitySearch->expects($this->once))->method ( constraint: 'getOnDemandPageFilterSet')->willReturnCallback(function (Criteria $criteria$this->elasticRepository->method( constraint: 'onDeman$this->logger->method( constraint: 'info');$this->service->getActivityIdsForSavedSearch($savedSeSthis->assertNotNull(ScapturedCriteria):$this->assertFalse($capturedCriteria->isFirstRequest(j Support Daily • in 2h 41 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:19:05CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Explain it to me again. Why is there issue with thhat? Where is it expected and why do I need to work with that. How is it used inDelllaluvzcontroes vasee oll saveuoedichl. Une los m on celllane ane iiOnSkdImbуnedoT LheLeveLyoetVaceronorL44-0e snoule de sallitwLet me read the OnDemandV2Controller to understand how it builds criteria there:Read OnDemanavzcontNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php: 90-93:0 phpVO Repository OnDemandActivitySearch\Criteria:: createFromRequest(arrav meroesrequesoaluor' umir => 00c0unt 'oade"$user->getTimezone()It passes Srequest->all() - which includes sequence_number from the URL (e.g. sequence_number=4 from your staging URL). So when a user has beenpaginating on the frontend, sequence_number is naturally non-zero.The full explanationyou didn't ask for them:FilterActiv1tvburat zonkangelhsiauist kecuestaouncskenererurns true wnen seauenceNumber === u wnenttsine "trstreduestneseumolci detauirs kickinauromaricalveventDefault on first requestEffectmin_duration = 1 minDroos 0-secono activitiesActivityRecordedonly_recorded = 1Recorded activities onlvOrganiserGroupInUser's own groupRestricts to user's groupFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest = false → no implicit defaults →returns 15 activities.AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence_number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-onlv + duration>1 together matchednothing.Why sequence_number=1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionally stripped (that's existing logic in DATE_FILTER_KEYS )3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representsSetting sequence number=1 is the minimal, correct signal: "this is not a fresh session open, don't apply page-load defaults". The criteria is otherwise builtidentically to how the controller builds it - same Criteria::createFromRequest, same getOnDemandPageFilterSet, same onDemandSearchIds0nly - so theresults will now match.Ö ul ...Ask anything (2*L)+ <> Code Claude Sonnet 4.6Winasun leams124:16uir-o( 4 spaces...
|
NULL
|
|
11200
|
NULL
|
0
|
2026-04-14T09:19:16.756329+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158356756_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditFV faVsco.s vProject v> D Proph PhpStormFileEditFV faVsco.s vProject v> D ProphetAiv D Reports© AutomatedReportsCl© AutomatedReportsRe© AutomatedReportsSt© CreateMockAskJimir© DeleteReportComma© GenerateMarketingR© Team.php© Usage.phpD Slack• TeamsD TracksO TranscriptionO TwilioD UsersVocabularyDZoom© CoachingFeedbacksUpr© Command.php© CreateDatabaseUsers.pc Daraoase oecountoi© DeleteOldAiCrmNotesC:© DeleteS3LeftoversComiDevPostmanCommand./© DiarizeViaAiParticipantk© EncryptTokensComman© EngagementStatsRegen© FeatureFlagsHelper.php© FixCrossTenantlssues.p© FlushRolesPermissionsC(e) Generatelnterna wepho• GroupSetDefaultLangua© HelperTruncateCoachin© HubspotJournalPollingC© HubspotWebhookServic©ImportRecording.php© ImportUsersFromCsvFil© IterateUsersCommand.p© JiminnyCacheClearCom© JiminnyDebugCommanc© JiminnySetEncryptedTo(c) Jiminny okenintocomm© MakeSlackLiveCoaching© ManageScimForTeam.p© MarkBranchForEnvironn© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesCom(e Recalculatebealkisksco(c) Removebe eremarkersc(e) Remove-xoiredNudoes© RemoveUnusedParticip:© ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCorViewNavigateCodeLaravelRefactorToolsWindowHelp( #11894 on JY-18909-automated-reports-ask-jiminny k v© ReportController.php© JiminnyDebugCommand.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© AutomatedReportsRepository.php© AutomatedReportsService.php© TrackProviderInstalledEvent.phpC) CreateActivityLoggedEvent.php© ActivityLogged.phpC AutomatedReportsCallbackService.phplests passea: 1 (10 minutes ago)© AutomatedReportsCommand.php x© Team.php© CreateHeldActivityEvent.php© UserPilotActivityListener.php= custom.log= laravel.logA SF [jiminny@localhost]Hs local liminnyalocalnostconsole PRODL console [EUl(0) RequestGenerate.sk.liminnvRenor.ob.ohn© RequestGenerateReportJob.php© AutomatedReportResult.php© AutomatedReport.phpA2 ^¿ consoe STAGINGI© AskJiminnyReportActivityService.php© ActivitySearch.php•OnDemandV2Controller.phprilterDerinitioncollection.onpC Criteria.php© AskJiminnyReportActivityServiceTest.php x© RequestGenerateAskJiminnyReportJobTest.php26class AskJiminnyReportActivityServiceTe0bject $logger;© HistoryService.phpBLMSAYiervice;iryserulcce oserucen29 ot>oidf.19 D› tring $key, ?string $value): SearchFilter&Mock0bject(...}› User&MockObjectf...3>rch(array $filters): Search&Mock0bjectf...}71%>tyIdsForSavedSearchReturnsIds(): voidf...}31 6t| Process a specific report by ID or UUID (bypasses frequency scheduling)}';100 % > tyIdsForSavedSearchReturnsEmptyWhenNoResults(): void{...}38 641 đ117118 % > tyIdsFiltersOutDateFilters(): voidf...}156157 %>tyIdsFilters0utClosingPeriodDateFilters(): voidf..184185 % >tyIdsHandLesArrayFilters(): voidf...3ll on thean frequency (weekly, monthty, quarterly). Ufg--report-id to manually trig!205206 ₽ >tyIdsHandlesScalarFilters(): void{...}224225 ₽tyIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults227IpoS1LoryeSavedSearch([]):229230eMock( originalClassName: FilterDefinitionCollection::class);chodl constraint: 'gecArrayrilterkeys )->wLLcreturnuLJ:1254258236237242243244245246247248-2472o0pects ($this->once())tOnDemandPageFilterSet')function (Criteria $criteria) use ($filterSet, &$capturedCrit>method( constraint: 'onDemandSearchIdsOnly') ->willReturn([]);istraint: 'info');tyIdsForSavedSearch($savedSearch, $user);Tureduriteria):reourrerarnsrurstre.uest.anvary, April, July, Uctober)252 8j Support Daily • in 2h 41 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:19:16CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Explain it to me again. Why is there issue with thhat? Where is it expected and why do I need to work with that. How is it used inDelllaluvzcontroes vasee oll saveuoedichl. Une los m on celllane ane iiOnSkdILmlуnedoT LheLeveLyetVLceronorL44-00 snoule De salllewLet me read the OnDemandV2Controller to understand how it builds criteria there:Read OnDemanavzcontNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php: 90-93:0 phpVO Repository OnDemandActivitySearch\Criteria::createFromRequest(arrav meroesrequesoaluo.' umir => 00c0unt "oade$user->getTimezone()It passes Srequest->all() - which includes sequence_number from the URL (e.g. sequence_number=4 from your staging URL). So when a user has beenpaginating on the frontend, sequence_number is naturally non-zero.The full explanationyou didn't ask for them:hsiauist kecuestaouncskenererurns true wnen seauenceNumber === u wnenttsine "trstreduestneseumolci detauirs kickinauromaricalveventFiterDefault on first requestEffectActiv1tvburat zonkangelmin_duration = 1 minDroos 0-secono activitiesActivityRecordedonly_recorded = 1Recorded activities onlvOrganiserGroupInUser's own groupRestricts to user's groupFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest = false → no implicit defaults →returns 15 activities.AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-onlv + duration>1 together matchednothing.Why sequence_number=1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionally stripped (that's existing logic in DATE_FILTER_KEYS )3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representsSetting sequence number=1 is the minimal, correct signal: "this is not a fresh session open, don't apply page-load defaults". The criteria is otherwise builtidentically to how the controller builds it - same Criteria::createFromRequest, same get0nDemandPageFilterSet, same onDemandSearchIds0nly - so theresults will now match.O ul ...Ask anything (2*L)+ <> CodeClaude Sonnet 4.6Winasun leams124:10uir-o( 4 spaces...
|
NULL
|
4082850485442642471
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileEditFV faVsco.s vProject v> D Proph PhpStormFileEditFV faVsco.s vProject v> D ProphetAiv D Reports© AutomatedReportsCl© AutomatedReportsRe© AutomatedReportsSt© CreateMockAskJimir© DeleteReportComma© GenerateMarketingR© Team.php© Usage.phpD Slack• TeamsD TracksO TranscriptionO TwilioD UsersVocabularyDZoom© CoachingFeedbacksUpr© Command.php© CreateDatabaseUsers.pc Daraoase oecountoi© DeleteOldAiCrmNotesC:© DeleteS3LeftoversComiDevPostmanCommand./© DiarizeViaAiParticipantk© EncryptTokensComman© EngagementStatsRegen© FeatureFlagsHelper.php© FixCrossTenantlssues.p© FlushRolesPermissionsC(e) Generatelnterna wepho• GroupSetDefaultLangua© HelperTruncateCoachin© HubspotJournalPollingC© HubspotWebhookServic©ImportRecording.php© ImportUsersFromCsvFil© IterateUsersCommand.p© JiminnyCacheClearCom© JiminnyDebugCommanc© JiminnySetEncryptedTo(c) Jiminny okenintocomm© MakeSlackLiveCoaching© ManageScimForTeam.p© MarkBranchForEnvironn© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesCom(e Recalculatebealkisksco(c) Removebe eremarkersc(e) Remove-xoiredNudoes© RemoveUnusedParticip:© ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCorViewNavigateCodeLaravelRefactorToolsWindowHelp( #11894 on JY-18909-automated-reports-ask-jiminny k v© ReportController.php© JiminnyDebugCommand.php© AutomatedReportsSendCommand.php© AddLayoutEntities.php© AutomatedReportsRepository.php© AutomatedReportsService.php© TrackProviderInstalledEvent.phpC) CreateActivityLoggedEvent.php© ActivityLogged.phpC AutomatedReportsCallbackService.phplests passea: 1 (10 minutes ago)© AutomatedReportsCommand.php x© Team.php© CreateHeldActivityEvent.php© UserPilotActivityListener.php= custom.log= laravel.logA SF [jiminny@localhost]Hs local liminnyalocalnostconsole PRODL console [EUl(0) RequestGenerate.sk.liminnvRenor.ob.ohn© RequestGenerateReportJob.php© AutomatedReportResult.php© AutomatedReport.phpA2 ^¿ consoe STAGINGI© AskJiminnyReportActivityService.php© ActivitySearch.php•OnDemandV2Controller.phprilterDerinitioncollection.onpC Criteria.php© AskJiminnyReportActivityServiceTest.php x© RequestGenerateAskJiminnyReportJobTest.php26class AskJiminnyReportActivityServiceTe0bject $logger;© HistoryService.phpBLMSAYiervice;iryserulcce oserucen29 ot>oidf.19 D› tring $key, ?string $value): SearchFilter&Mock0bject(...}› User&MockObjectf...3>rch(array $filters): Search&Mock0bjectf...}71%>tyIdsForSavedSearchReturnsIds(): voidf...}31 6t| Process a specific report by ID or UUID (bypasses frequency scheduling)}';100 % > tyIdsForSavedSearchReturnsEmptyWhenNoResults(): void{...}38 641 đ117118 % > tyIdsFiltersOutDateFilters(): voidf...}156157 %>tyIdsFilters0utClosingPeriodDateFilters(): voidf..184185 % >tyIdsHandLesArrayFilters(): voidf...3ll on thean frequency (weekly, monthty, quarterly). Ufg--report-id to manually trig!205206 ₽ >tyIdsHandlesScalarFilters(): void{...}224225 ₽tyIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults227IpoS1LoryeSavedSearch([]):229230eMock( originalClassName: FilterDefinitionCollection::class);chodl constraint: 'gecArrayrilterkeys )->wLLcreturnuLJ:1254258236237242243244245246247248-2472o0pects ($this->once())tOnDemandPageFilterSet')function (Criteria $criteria) use ($filterSet, &$capturedCrit>method( constraint: 'onDemandSearchIdsOnly') ->willReturn([]);istraint: 'info');tyIdsForSavedSearch($savedSearch, $user);Tureduriteria):reourrerarnsrurstre.uest.anvary, April, July, Uctober)252 8j Support Daily • in 2h 41 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:19:16CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Explain it to me again. Why is there issue with thhat? Where is it expected and why do I need to work with that. How is it used inDelllaluvzcontroes vasee oll saveuoedichl. Une los m on celllane ane iiOnSkdILmlуnedoT LheLeveLyetVLceronorL44-00 snoule De salllewLet me read the OnDemandV2Controller to understand how it builds criteria there:Read OnDemanavzcontNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php: 90-93:0 phpVO Repository OnDemandActivitySearch\Criteria::createFromRequest(arrav meroesrequesoaluo.' umir => 00c0unt "oade$user->getTimezone()It passes Srequest->all() - which includes sequence_number from the URL (e.g. sequence_number=4 from your staging URL). So when a user has beenpaginating on the frontend, sequence_number is naturally non-zero.The full explanationyou didn't ask for them:hsiauist kecuestaouncskenererurns true wnen seauenceNumber === u wnenttsine "trstreduestneseumolci detauirs kickinauromaricalveventFiterDefault on first requestEffectActiv1tvburat zonkangelmin_duration = 1 minDroos 0-secono activitiesActivityRecordedonly_recorded = 1Recorded activities onlvOrganiserGroupInUser's own groupRestricts to user's groupFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest = false → no implicit defaults →returns 15 activities.AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-onlv + duration>1 together matchednothing.Why sequence_number=1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionally stripped (that's existing logic in DATE_FILTER_KEYS )3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representsSetting sequence number=1 is the minimal, correct signal: "this is not a fresh session open, don't apply page-load defaults". The criteria is otherwise builtidentically to how the controller builds it - same Criteria::createFromRequest, same get0nDemandPageFilterSet, same onDemandSearchIds0nly - so theresults will now match.O ul ...Ask anything (2*L)+ <> CodeClaude Sonnet 4.6Winasun leams124:10uir-o( 4 spaces...
|
11198
|
|
11202
|
223
|
0
|
2026-04-14T09:19:34.532004+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158374532_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormProject vFileEditFV faVsco.js vViewNavigat PhpStormProject vFileEditFV faVsco.js vViewNavigateCodeLaravelRefactorToolsWindowHelp#11894 on JY-18909-automated-reports-ask-iminny K vProphetAiv D Reports© AutomatedReportsCl© AutomatedReportsRe© AutomatedReportsSt© CreateMockAskJimir© DeleteReportComma© GenerateMarketingR© Team.php© Usage.phpD Slack• TeamsD TracksO TranscriptionO TwilioD UsersVocabularyDZoom© CoachingFeedbacksUpr© Command.php© CreateDatabaseUsers.pc Daraoase oecountoi© DeleteOldAiCrmNotesC:© DeleteS3LeftoversComiDevPostmanCommand.|© DiarizeViaAiParticipantk© EncryptTokensComman© EngagementStatsRegen© FeatureFlagsHelper.php© FixCrossTenantissues.p© FlushRolesPermissionsC© GeneratelnternalWebho• GroupSetDefaultLangua© HelperTruncateCoachin© HubspotJournalPollingC© HubspotWebhookServic© ImportRecording.php@ Imnortli|sercFromCcvEil© IterateUsersCommand.gcJiminnvcacheclearcom(c) minnv Deouacommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoaching© ManageScimForTeam.p© MarkBranchForEnvironn© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php(©) PurgeSoftDeletedOppol© PurgeSyncBatchesCom© RecalculateDealRisksCaC) RemoveDeleteMarkersd© RemoveExpiredNudgest© RemoveUnusedParticip:© ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCorTests passed: 1 (10 minutes ago)© ReportController.phpJiminnybeouecommana.ong© AutomatedReportsSendCommand.php© AddLayoutEntities.php© AutomatedReportsService.php• ІгаскrrovlderinstalleacventoneC) CreateActivityLoggedEvent.phpAutomatedReportsCommand.php X= custom.log= laravel.logA SF [jiminny@localhost]leam.onoHs local liminnyalocalnostconsole PRODL console [EUl© CreateHeldActivityEvent.php© UserPilotActivityListener.phpC AutomatedReportsCallbackService.php© RequestGenerateReportJob.php© AutomatedReportResult.phpA console [STAGING]© ActivitySearch.php© AskJiminnyReportActivityService.php•OnDemandV2Controller.phprilterDerinitioncollection.ongC Criteria.php© AskJiminnyReportActivityServiceTest.php x© RequestGenerateAskJiminnyReportJobTest.php26class AskJiminnyReportActivityServiceTe0bject $logger;© HistoryService.php19 D31 Ct38 đ42 Ct51535556© AutomatedReport.phpLs\Team;sitories\AutomatedReportsRepository;ices\Kiosk\AutomatedReports\AutomatedReportsService;erInterface;A2 ^BLMSAYiryserulcce oserucen29 ot>oidf.eoorrsconliano excenos conlano› tring $key, ?string $value): SearchFilter&Mock0bject(...}x for all log messagest string LOG_PREFIX = '[automated-reports]':› User&MockObjectf...}and signature of the console command.› rch(array $filters): Search&MockObject{...}71%>tyIdsForSavedSearchReturnsIds(): voidf...}lignature = 'automated-reports f--report-id= : Process a specific report by ID or Ul 100 P > tyIdsForSavedSearchReturnsEmptyWhenNoResults(): voidf...}Le command description.117118 % > tyIdsFiltersOutDateFilters(): voidf...}156157 % >tyIdsFilters0utClosingPeriodDateFilters(): voidf..}185 M >tyIdsHandLesArrayFilters(): voidf...3lescription = 'Process automated reports based on their frequency (weekly, monthly,port-id to manually trigger a specific report by ID or UUID.';206 ₽ >224225 ₽tyIdsHandlesScalarFilters(): void{...;tyIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaultsion __construct(readonly LoggerInterface $logger,readonly BusDispatcher $dispatcher,readonly AutomatedReportsRepository $reportRepositoryeSavedSearch([]):229230eMock( originalClassName: FilterDefinitionCollection::class);__construct();chodl constraint: 'gecArrayrilterkeys )->wLLcreturnuLJ:ne console conmonoiion handle(): intogger->info(self::LOG_PREFIX . ' Started');arbon: : now();y = Snow->1SMondayO:Dav0fMonth = Snow->dav === 1Month = Snow->month:1254258236237242243244245246247248— 2472o0pects ($this->once())tOnDemandPageFilterSet')function (Criteria $criteria) use ($filterSet, &$capturedCrit>method( constraint: 'onDemandSearchIdsOnly') ->willReturn([]);istraint: 'info');tyIdsForSavedSearch($savedSearch, $user);reourrerarnsrurstre.uest.252 Mj Support Daily • in 2h 41 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:19:34CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Explain it to me again. Why is there issue with thhat? Where is it expected and why do I need to work with that. How is it used inDelllaluvzcontroes vasee oll saveuoedichl. Une los m on celllane ane iiOnSkdILmlуnedoT LheLeveLyetVLceronorL44-00 snoule De salllewLet me read the OnDemandV2Controller to understand how it builds criteria there:Read OnDemanavzcontNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php: 90-93:0 phpVO Repository OnDemandActivitySearch\Criteria:: createFromRequest(arrav meroesrequesoaluo.' umir => 00c0unt "oade$user->getTimezone()It passes Srequest->all() - which includes sequence_number from the URL (e.g. sequence_number=4 from your staging URL). So when a user has beenpaginating on the frontend, sequence_number is naturally non-zero.The full explanationyou didn't ask for them:hsiauist kecuestaouncskenererurns true wnen seauenceNumber === u wnenttsine "trstreduestneseumolci detauirs kickinauromaricalveventFiterDefault on first requestEffectActiv1tvburat zonkangelmin_duration = 1 minDroos 0-secono activitiesActivityRecordedonly_recorded = 1Recorded activities onlvOrganiserGroupInUser's own groupRestricts to user's groupFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest = false → no implicit defaults →returns 15 activities.AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-onlv + duration>1 together matchednothing.Why sequence_number=1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionally stripped (that's existing logic in DATE_FILTER_KEYS )3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representsSetting sequence number=1 is the minimal, correct signal: "this is not a fresh session open, don't apply page-load defaults". The criteria is otherwise builtidentically to how the controller builds it - same Criteria::createFromRequest, same get0nDemandPageFilterSet, same onDemandSearchIds0nly - so theresults will now match.Ö ul ...Ask anything (2*L)+ <> CodeClaude Sonnet 4.6Winasun leams39:9uir-o( 4 spaces...
|
NULL
|
8344973971912623520
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormProject vFileEditFV faVsco.js vViewNavigat PhpStormProject vFileEditFV faVsco.js vViewNavigateCodeLaravelRefactorToolsWindowHelp#11894 on JY-18909-automated-reports-ask-iminny K vProphetAiv D Reports© AutomatedReportsCl© AutomatedReportsRe© AutomatedReportsSt© CreateMockAskJimir© DeleteReportComma© GenerateMarketingR© Team.php© Usage.phpD Slack• TeamsD TracksO TranscriptionO TwilioD UsersVocabularyDZoom© CoachingFeedbacksUpr© Command.php© CreateDatabaseUsers.pc Daraoase oecountoi© DeleteOldAiCrmNotesC:© DeleteS3LeftoversComiDevPostmanCommand.|© DiarizeViaAiParticipantk© EncryptTokensComman© EngagementStatsRegen© FeatureFlagsHelper.php© FixCrossTenantissues.p© FlushRolesPermissionsC© GeneratelnternalWebho• GroupSetDefaultLangua© HelperTruncateCoachin© HubspotJournalPollingC© HubspotWebhookServic© ImportRecording.php@ Imnortli|sercFromCcvEil© IterateUsersCommand.gcJiminnvcacheclearcom(c) minnv Deouacommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoaching© ManageScimForTeam.p© MarkBranchForEnvironn© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php(©) PurgeSoftDeletedOppol© PurgeSyncBatchesCom© RecalculateDealRisksCaC) RemoveDeleteMarkersd© RemoveExpiredNudgest© RemoveUnusedParticip:© ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCorTests passed: 1 (10 minutes ago)© ReportController.phpJiminnybeouecommana.ong© AutomatedReportsSendCommand.php© AddLayoutEntities.php© AutomatedReportsService.php• ІгаскrrovlderinstalleacventoneC) CreateActivityLoggedEvent.phpAutomatedReportsCommand.php X= custom.log= laravel.logA SF [jiminny@localhost]leam.onoHs local liminnyalocalnostconsole PRODL console [EUl© CreateHeldActivityEvent.php© UserPilotActivityListener.phpC AutomatedReportsCallbackService.php© RequestGenerateReportJob.php© AutomatedReportResult.phpA console [STAGING]© ActivitySearch.php© AskJiminnyReportActivityService.php•OnDemandV2Controller.phprilterDerinitioncollection.ongC Criteria.php© AskJiminnyReportActivityServiceTest.php x© RequestGenerateAskJiminnyReportJobTest.php26class AskJiminnyReportActivityServiceTe0bject $logger;© HistoryService.php19 D31 Ct38 đ42 Ct51535556© AutomatedReport.phpLs\Team;sitories\AutomatedReportsRepository;ices\Kiosk\AutomatedReports\AutomatedReportsService;erInterface;A2 ^BLMSAYiryserulcce oserucen29 ot>oidf.eoorrsconliano excenos conlano› tring $key, ?string $value): SearchFilter&Mock0bject(...}x for all log messagest string LOG_PREFIX = '[automated-reports]':› User&MockObjectf...}and signature of the console command.› rch(array $filters): Search&MockObject{...}71%>tyIdsForSavedSearchReturnsIds(): voidf...}lignature = 'automated-reports f--report-id= : Process a specific report by ID or Ul 100 P > tyIdsForSavedSearchReturnsEmptyWhenNoResults(): voidf...}Le command description.117118 % > tyIdsFiltersOutDateFilters(): voidf...}156157 % >tyIdsFilters0utClosingPeriodDateFilters(): voidf..}185 M >tyIdsHandLesArrayFilters(): voidf...3lescription = 'Process automated reports based on their frequency (weekly, monthly,port-id to manually trigger a specific report by ID or UUID.';206 ₽ >224225 ₽tyIdsHandlesScalarFilters(): void{...;tyIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaultsion __construct(readonly LoggerInterface $logger,readonly BusDispatcher $dispatcher,readonly AutomatedReportsRepository $reportRepositoryeSavedSearch([]):229230eMock( originalClassName: FilterDefinitionCollection::class);__construct();chodl constraint: 'gecArrayrilterkeys )->wLLcreturnuLJ:ne console conmonoiion handle(): intogger->info(self::LOG_PREFIX . ' Started');arbon: : now();y = Snow->1SMondayO:Dav0fMonth = Snow->dav === 1Month = Snow->month:1254258236237242243244245246247248— 2472o0pects ($this->once())tOnDemandPageFilterSet')function (Criteria $criteria) use ($filterSet, &$capturedCrit>method( constraint: 'onDemandSearchIdsOnly') ->willReturn([]);istraint: 'info');tyIdsForSavedSearch($savedSearch, $user);reourrerarnsrurstre.uest.252 Mj Support Daily • in 2h 41 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:19:34CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D..Explain it to me again. Why is there issue with thhat? Where is it expected and why do I need to work with that. How is it used inDelllaluvzcontroes vasee oll saveuoedichl. Une los m on celllane ane iiOnSkdILmlуnedoT LheLeveLyetVLceronorL44-00 snoule De salllewLet me read the OnDemandV2Controller to understand how it builds criteria there:Read OnDemanavzcontNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php: 90-93:0 phpVO Repository OnDemandActivitySearch\Criteria:: createFromRequest(arrav meroesrequesoaluo.' umir => 00c0unt "oade$user->getTimezone()It passes Srequest->all() - which includes sequence_number from the URL (e.g. sequence_number=4 from your staging URL). So when a user has beenpaginating on the frontend, sequence_number is naturally non-zero.The full explanationyou didn't ask for them:hsiauist kecuestaouncskenererurns true wnen seauenceNumber === u wnenttsine "trstreduestneseumolci detauirs kickinauromaricalveventFiterDefault on first requestEffectActiv1tvburat zonkangelmin_duration = 1 minDroos 0-secono activitiesActivityRecordedonly_recorded = 1Recorded activities onlvOrganiserGroupInUser's own groupRestricts to user's groupFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest = false → no implicit defaults →returns 15 activities.AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-onlv + duration>1 together matchednothing.Why sequence_number=1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionally stripped (that's existing logic in DATE_FILTER_KEYS )3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representsSetting sequence number=1 is the minimal, correct signal: "this is not a fresh session open, don't apply page-load defaults". The criteria is otherwise builtidentically to how the controller builds it - same Criteria::createFromRequest, same get0nDemandPageFilterSet, same onDemandSearchIds0nly - so theresults will now match.Ö ul ...Ask anything (2*L)+ <> CodeClaude Sonnet 4.6Winasun leams39:9uir-o( 4 spaces...
|
NULL
|
|
11204
|
223
|
1
|
2026-04-14T09:19:44.644465+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158384644_m2.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReportsCommand.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
3
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Services\Kiosk\AutomatedReports;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityActualDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityUpdatedDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\DealInsights\ClosingPeriodFilter;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\User;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
class AskJiminnyReportActivityServiceTest extends TestCase
{
private ActivitySearch&MockObject $activitySearch;
private ElasticActivityRepository&MockObject $elasticRepository;
private LoggerInterface&MockObject $logger;
private AskJiminnyReportActivityService $service;
protected function setUp(): void
{
$this->activitySearch = $this->createMock(ActivitySearch::class);
$this->elasticRepository = $this->createMock(ElasticActivityRepository::class);
$this->logger = $this->createMock(LoggerInterface::class);
$this->service = new AskJiminnyReportActivityService(
$this->activitySearch,
$this->elasticRepository,
$this->logger,
);
}
private function makeFilter(string $key, ?string $value): SearchFilter&MockObject
{
$filter = $this->createMock(SearchFilter::class);
$filter->method('getFilterProperty')->willReturn($key);
$filter->method('getFilterValue')->willReturn($value);
return $filter;
}
private function makeUser(): User&MockObject
{
$tz = new \DateTimeZone('UTC');
$user = $this->createMock(User::class);
$user->method('getTimezone')->willReturn($tz);
$user->method('getId')->willReturn(1);
$user->method('getUuid')->willReturn('user-uuid');
return $user;
}
private function makeSavedSearch(array $filters): Search&MockObject
{
$savedSearch = $this->createMock(Search::class);
$savedSearch->method('getId')->willReturn(42);
$savedSearch->method('getFilters')->willReturn(new \Illuminate\Support\LazyCollection($filters));
return $savedSearch;
}
public function testGetActivityIdsForSavedSearchReturnsIds(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->expects($this->once())
->method('getArrayFilterKeys')
->with($user)
->willReturn([]);
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturn($filterSet);
$this->elasticRepository->expects($this->once())
->method('onDemandSearchIdsOnly')
->willReturn(['id-1', 'id-2', 'id-3']);
$this->logger->expects($this->once())
->method('info')
->with('[AskJiminnyReport] Fetched activity IDs for saved search');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1', 'id-2', 'id-3'], $result);
}
public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->expects($this->once())->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEmpty($result);
}
public function testGetActivityIdsFiltersOutDateFilters(): void
{
$user = $this->makeUser();
$nonDateFilter = $this->makeFilter('owner_id', '123');
$startDateFilter = $this->makeFilter(ActivityActualDate::PARAM_START_DATE, '2025-01-01 00:00:00');
$endDateFilter = $this->makeFilter(ActivityActualDate::PARAM_END_DATE, '2025-01-31 23:59:59');
$updatedFromFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_FROM, '2025-01-01 00:00:00');
$updatedToFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_TO, '2025-01-31 23:59:59');
$savedSearch = $this->makeSavedSearch([
$nonDateFilter,
$startDateFilter,
$endDateFilter,
$updatedFromFilter,
$updatedToFilter,
]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$capturedCriteria = null;
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {
$capturedCriteria = $criteria;
return $filterSet;
});
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->method('info');
$this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertNotNull($capturedCriteria);
}
public function testGetActivityIdsFiltersOutClosingPeriodDateFilters(): void
{
$user = $this->makeUser();
$closingStartFilter = $this->makeFilter(ClosingPeriodFilter::KEY_START_DATE, '2025-01-01');
$closingEndFilter = $this->makeFilter(ClosingPeriodFilter::KEY_END_DATE, '2025-03-31');
$regularFilter = $this->makeFilter('rep_id', '99');
$savedSearch = $this->makeSavedSearch([
$closingStartFilter,
$closingEndFilter,
$regularFilter,
]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1'], $result);
}
public function testGetActivityIdsHandlesArrayFilters(): void
{
$user = $this->makeUser();
$filter1 = $this->makeFilter('outcome', 'positive');
$filter2 = $this->makeFilter('outcome', 'negative');
$savedSearch = $this->makeSavedSearch([$filter1, $filter2]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn(['outcome']);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1'], $result);
}
public function testGetActivityIdsHandlesScalarFilters(): void
{
$user = $this->makeUser();
$filter = $this->makeFilter('direction', 'inbound');
$savedSearch = $this->makeSavedSearch([$filter]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-5']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-5'], $result);
}
public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$capturedCriteria = null;
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {
$capturedCriteria = $criteria;
return $filterSet;
});
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->method('info');
$this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertNotNull($capturedCriteria);
$this->assertFalse($capturedCriteria->isFirstRequest());
}
public function testGetActivityIdsLogsWithCorrectContext(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['a', 'b']);
$this->logger->expects($this->once())
->method('info')
->with(
'[AskJiminnyReport] Fetched activity IDs for saved search',
$this->callback(fn ($context) => $context['saved_search_id'] === 42
&& $context['user_id'] === 1
&& $context['activity_count'] === 2)
);
$this->service->getActivityIdsForSavedSearch($savedSearch, $user);
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands\Reports;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Contracts\Bus\Dispatcher as BusDispatcher;
use Illuminate\Support\Collection;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\RequestGenerateReportJob;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\Team;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Psr\Log\LoggerInterface;
class AutomatedReportsCommand extends Command
{
/**
* Log prefix for all log messages
*/
private const string LOG_PREFIX = '[automated-reports]';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'automated-reports
{--report-id= : Process a specific report by ID or UUID (bypasses frequency scheduling)}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly).
Use --report-id to manually trigger a specific report by ID or UUID.';
public function __construct(
private readonly LoggerInterface $logger,
private readonly BusDispatcher $dispatcher,
private readonly AutomatedReportsRepository $reportRepository
) {
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle(): int
{
$this->logger->info(self::LOG_PREFIX . ' Started');
$now = Carbon::now();
$isMonday = $now->isMonday();
$isFirstDayOfMonth = $now->day === 1;
$currentMonth = $now->month;
// Check if the current month is a quarterly month (January, April, July, October)
$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);
$this->logger->info(self::LOG_PREFIX . ' Checking conditions', [
'isMonday' => $isMonday,
'isFirstDayOfMonth' => $isFirstDayOfMonth,
'currentMonth' => $currentMonth,
'isQuarterlyMonth' => $isQuarterlyMonth,
]);
// Process daily reports
$this->processReports(AutomatedReportsService::FREQUENCY_DAILY);
// Process weekly reports on Mondays
if ($isMonday) {
$this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);
}
// Process monthly reports on the first day of the month
if ($isFirstDayOfMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);
}
// Process quarterly reports on the first day of January, April, July, and October
if ($isFirstDayOfMonth && $isQuarterlyMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);
}
$this->logger->info(self::LOG_PREFIX . ' Completed');
return 0;
}
/**
* Process reports for a specific frequency.
*
* @param string $frequency
*
* @return void
*/
private function processReports(string $frequency): void
{
$this->logger->info(self::LOG_PREFIX . " Processing $frequency reports");
$reportId = $this->option('report-id');
if ($reportId !== null) {
$reports = $this->getReportById($reportId);
} else {
// Get all enabled, not deleted reports with active teams for the specified frequency
$reports = $this->reportRepository->getActiveReportsByFrequency($frequency);
}
$this->logger->info(self::LOG_PREFIX . " Found {$reports->count()} $frequency reports to process");
/** @var AutomatedReport $report */
foreach ($reports as $report) {
$this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [
'reportUuid' => $report->getUuid(),
'teamId' => $report->getTeamId(),
'frequency' => $report->getFrequency(),
'type' => $report->getType(),
]);
$job = $report->isAskJiminnyReport()
? new RequestGenerateAskJiminnyReportJob($report->getUuid())
: new RequestGenerateReportJob($report->getUuid());
$this->dispatcher->dispatch($job);
}
}
private function getReportById(string $reportId): Collection
{
$report = $this->reportRepository->findByIdOrUuid($reportId);
if ($report === null) {
$this->logger->warning(self::LOG_PREFIX . ' Report not found for --report-id', ['reportId' => $reportId]);
$this->warn("Report not found: {$reportId}");
return collect();
}
if (! $report->getStatus()) {
$this->logger->warning(self::LOG_PREFIX . ' Report is inactive, processing anyway (manual override)', [
'reportId' => $reportId,
'reportUuid' => $report->getUuid(),
]);
$this->warn('Report is inactive — processing anyway (manual override).');
}
$team = $report->getTeam();
if ($team->getStatus() !== Team::STATUS_ACTIVE) {
$this->logger->warning(self::LOG_PREFIX . ' Team is not active, processing anyway (manual override)', [
'reportId' => $reportId,
'reportUuid' => $report->getUuid(),
'teamId' => $report->getTeamId(),
'teamStatus' => $team->getStatus(),
]);
$this->warn("Team #{$report->getTeamId()} is not active — processing anyway (manual override).");
}
if ($report->isExpired()) {
$this->logger->warning(self::LOG_PREFIX . ' Report is expired, processing anyway (manual override)', [
'reportId' => $reportId,
'reportUuid' => $report->getUuid(),
'expiresAt' => $report->getExpiresAt()?->toDateString(),
]);
$this->warn('Report is expired (expires_at: ' . $report->getExpiresAt()?->toDateString() . ') — processing anyway (manual override).');
}
return collect([$report]);
}
}
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.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","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.7589844,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceT…Defaults","depth":6,"bounds":{"left":0.7769531,"top":0.017361112,"width":0.12382813,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.575,"top":0.19513889,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"3","depth":4,"bounds":{"left":0.58671874,"top":0.19513889,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.5980469,"top":0.19375,"width":0.00859375,"height":0.015972223},"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.60664064,"top":0.19375,"width":0.008203125,"height":0.015972223},"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\\Services\\Kiosk\\AutomatedReports;\n\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityActualDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityUpdatedDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealInsights\\ClosingPeriodFilter;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AskJiminnyReportActivityService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse PHPUnit\\Framework\\TestCase;\nuse Psr\\Log\\LoggerInterface;\n\nclass AskJiminnyReportActivityServiceTest extends TestCase\n{\n private ActivitySearch&MockObject $activitySearch;\n private ElasticActivityRepository&MockObject $elasticRepository;\n private LoggerInterface&MockObject $logger;\n private AskJiminnyReportActivityService $service;\n\n protected function setUp(): void\n {\n $this->activitySearch = $this->createMock(ActivitySearch::class);\n $this->elasticRepository = $this->createMock(ElasticActivityRepository::class);\n $this->logger = $this->createMock(LoggerInterface::class);\n\n $this->service = new AskJiminnyReportActivityService(\n $this->activitySearch,\n $this->elasticRepository,\n $this->logger,\n );\n }\n\n private function makeFilter(string $key, ?string $value): SearchFilter&MockObject\n {\n $filter = $this->createMock(SearchFilter::class);\n $filter->method('getFilterProperty')->willReturn($key);\n $filter->method('getFilterValue')->willReturn($value);\n\n return $filter;\n }\n\n private function makeUser(): User&MockObject\n {\n $tz = new \\DateTimeZone('UTC');\n $user = $this->createMock(User::class);\n $user->method('getTimezone')->willReturn($tz);\n $user->method('getId')->willReturn(1);\n $user->method('getUuid')->willReturn('user-uuid');\n\n return $user;\n }\n\n private function makeSavedSearch(array $filters): Search&MockObject\n {\n $savedSearch = $this->createMock(Search::class);\n $savedSearch->method('getId')->willReturn(42);\n $savedSearch->method('getFilters')->willReturn(new \\Illuminate\\Support\\LazyCollection($filters));\n\n return $savedSearch;\n }\n\n public function testGetActivityIdsForSavedSearchReturnsIds(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->expects($this->once())\n ->method('getArrayFilterKeys')\n ->with($user)\n ->willReturn([]);\n\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturn($filterSet);\n\n $this->elasticRepository->expects($this->once())\n ->method('onDemandSearchIdsOnly')\n ->willReturn(['id-1', 'id-2', 'id-3']);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with('[AskJiminnyReport] Fetched activity IDs for saved search');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1', 'id-2', 'id-3'], $result);\n }\n\n public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n\n $this->logger->expects($this->once())->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEmpty($result);\n }\n\n public function testGetActivityIdsFiltersOutDateFilters(): void\n {\n $user = $this->makeUser();\n\n $nonDateFilter = $this->makeFilter('owner_id', '123');\n $startDateFilter = $this->makeFilter(ActivityActualDate::PARAM_START_DATE, '2025-01-01 00:00:00');\n $endDateFilter = $this->makeFilter(ActivityActualDate::PARAM_END_DATE, '2025-01-31 23:59:59');\n $updatedFromFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_FROM, '2025-01-01 00:00:00');\n $updatedToFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_TO, '2025-01-31 23:59:59');\n\n $savedSearch = $this->makeSavedSearch([\n $nonDateFilter,\n $startDateFilter,\n $endDateFilter,\n $updatedFromFilter,\n $updatedToFilter,\n ]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n\n $capturedCriteria = null;\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {\n $capturedCriteria = $criteria;\n\n return $filterSet;\n });\n\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n $this->logger->method('info');\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertNotNull($capturedCriteria);\n }\n\n public function testGetActivityIdsFiltersOutClosingPeriodDateFilters(): void\n {\n $user = $this->makeUser();\n\n $closingStartFilter = $this->makeFilter(ClosingPeriodFilter::KEY_START_DATE, '2025-01-01');\n $closingEndFilter = $this->makeFilter(ClosingPeriodFilter::KEY_END_DATE, '2025-03-31');\n $regularFilter = $this->makeFilter('rep_id', '99');\n\n $savedSearch = $this->makeSavedSearch([\n $closingStartFilter,\n $closingEndFilter,\n $regularFilter,\n ]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1'], $result);\n }\n\n public function testGetActivityIdsHandlesArrayFilters(): void\n {\n $user = $this->makeUser();\n\n $filter1 = $this->makeFilter('outcome', 'positive');\n $filter2 = $this->makeFilter('outcome', 'negative');\n\n $savedSearch = $this->makeSavedSearch([$filter1, $filter2]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn(['outcome']);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1'], $result);\n }\n\n public function testGetActivityIdsHandlesScalarFilters(): void\n {\n $user = $this->makeUser();\n\n $filter = $this->makeFilter('direction', 'inbound');\n $savedSearch = $this->makeSavedSearch([$filter]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-5']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-5'], $result);\n }\n\n public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n\n $capturedCriteria = null;\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {\n $capturedCriteria = $criteria;\n\n return $filterSet;\n });\n\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n $this->logger->method('info');\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertNotNull($capturedCriteria);\n $this->assertFalse($capturedCriteria->isFirstRequest());\n }\n\n public function testGetActivityIdsLogsWithCorrectContext(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['a', 'b']);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with(\n '[AskJiminnyReport] Fetched activity IDs for saved search',\n $this->callback(fn ($context) => $context['saved_search_id'] === 42\n && $context['user_id'] === 1\n && $context['activity_count'] === 2)\n );\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n }\n}","depth":4,"bounds":{"left":0.32890624,"top":0.0,"width":0.3347656,"height":1.0},"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Services\\Kiosk\\AutomatedReports;\n\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityActualDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityUpdatedDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealInsights\\ClosingPeriodFilter;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AskJiminnyReportActivityService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse PHPUnit\\Framework\\TestCase;\nuse Psr\\Log\\LoggerInterface;\n\nclass AskJiminnyReportActivityServiceTest extends TestCase\n{\n private ActivitySearch&MockObject $activitySearch;\n private ElasticActivityRepository&MockObject $elasticRepository;\n private LoggerInterface&MockObject $logger;\n private AskJiminnyReportActivityService $service;\n\n protected function setUp(): void\n {\n $this->activitySearch = $this->createMock(ActivitySearch::class);\n $this->elasticRepository = $this->createMock(ElasticActivityRepository::class);\n $this->logger = $this->createMock(LoggerInterface::class);\n\n $this->service = new AskJiminnyReportActivityService(\n $this->activitySearch,\n $this->elasticRepository,\n $this->logger,\n );\n }\n\n private function makeFilter(string $key, ?string $value): SearchFilter&MockObject\n {\n $filter = $this->createMock(SearchFilter::class);\n $filter->method('getFilterProperty')->willReturn($key);\n $filter->method('getFilterValue')->willReturn($value);\n\n return $filter;\n }\n\n private function makeUser(): User&MockObject\n {\n $tz = new \\DateTimeZone('UTC');\n $user = $this->createMock(User::class);\n $user->method('getTimezone')->willReturn($tz);\n $user->method('getId')->willReturn(1);\n $user->method('getUuid')->willReturn('user-uuid');\n\n return $user;\n }\n\n private function makeSavedSearch(array $filters): Search&MockObject\n {\n $savedSearch = $this->createMock(Search::class);\n $savedSearch->method('getId')->willReturn(42);\n $savedSearch->method('getFilters')->willReturn(new \\Illuminate\\Support\\LazyCollection($filters));\n\n return $savedSearch;\n }\n\n public function testGetActivityIdsForSavedSearchReturnsIds(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->expects($this->once())\n ->method('getArrayFilterKeys')\n ->with($user)\n ->willReturn([]);\n\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturn($filterSet);\n\n $this->elasticRepository->expects($this->once())\n ->method('onDemandSearchIdsOnly')\n ->willReturn(['id-1', 'id-2', 'id-3']);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with('[AskJiminnyReport] Fetched activity IDs for saved search');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1', 'id-2', 'id-3'], $result);\n }\n\n public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n\n $this->logger->expects($this->once())->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEmpty($result);\n }\n\n public function testGetActivityIdsFiltersOutDateFilters(): void\n {\n $user = $this->makeUser();\n\n $nonDateFilter = $this->makeFilter('owner_id', '123');\n $startDateFilter = $this->makeFilter(ActivityActualDate::PARAM_START_DATE, '2025-01-01 00:00:00');\n $endDateFilter = $this->makeFilter(ActivityActualDate::PARAM_END_DATE, '2025-01-31 23:59:59');\n $updatedFromFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_FROM, '2025-01-01 00:00:00');\n $updatedToFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_TO, '2025-01-31 23:59:59');\n\n $savedSearch = $this->makeSavedSearch([\n $nonDateFilter,\n $startDateFilter,\n $endDateFilter,\n $updatedFromFilter,\n $updatedToFilter,\n ]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n\n $capturedCriteria = null;\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {\n $capturedCriteria = $criteria;\n\n return $filterSet;\n });\n\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n $this->logger->method('info');\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertNotNull($capturedCriteria);\n }\n\n public function testGetActivityIdsFiltersOutClosingPeriodDateFilters(): void\n {\n $user = $this->makeUser();\n\n $closingStartFilter = $this->makeFilter(ClosingPeriodFilter::KEY_START_DATE, '2025-01-01');\n $closingEndFilter = $this->makeFilter(ClosingPeriodFilter::KEY_END_DATE, '2025-03-31');\n $regularFilter = $this->makeFilter('rep_id', '99');\n\n $savedSearch = $this->makeSavedSearch([\n $closingStartFilter,\n $closingEndFilter,\n $regularFilter,\n ]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1'], $result);\n }\n\n public function testGetActivityIdsHandlesArrayFilters(): void\n {\n $user = $this->makeUser();\n\n $filter1 = $this->makeFilter('outcome', 'positive');\n $filter2 = $this->makeFilter('outcome', 'negative');\n\n $savedSearch = $this->makeSavedSearch([$filter1, $filter2]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn(['outcome']);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1'], $result);\n }\n\n public function testGetActivityIdsHandlesScalarFilters(): void\n {\n $user = $this->makeUser();\n\n $filter = $this->makeFilter('direction', 'inbound');\n $savedSearch = $this->makeSavedSearch([$filter]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-5']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-5'], $result);\n }\n\n public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n\n $capturedCriteria = null;\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {\n $capturedCriteria = $criteria;\n\n return $filterSet;\n });\n\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n $this->logger->method('info');\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertNotNull($capturedCriteria);\n $this->assertFalse($capturedCriteria->isFirstRequest());\n }\n\n public function testGetActivityIdsLogsWithCorrectContext(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['a', 'b']);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with(\n '[AskJiminnyReport] Fetched activity IDs for saved search',\n $this->callback(fn ($context) => $context['saved_search_id'] === 42\n && $context['user_id'] === 1\n && $context['activity_count'] === 2)\n );\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.3761719,"top":0.19513889,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.3875,"top":0.19375,"width":0.00859375,"height":0.015972223},"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.39609376,"top":0.19375,"width":0.008203125,"height":0.015972223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands\\Reports;\n\nuse Carbon\\Carbon;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Bus\\Dispatcher as BusDispatcher;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateReportJob;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Psr\\Log\\LoggerInterface;\n\nclass AutomatedReportsCommand extends Command\n{\n /**\n * Log prefix for all log messages\n */\n private const string LOG_PREFIX = '[automated-reports]';\n\n /**\n * The name and signature of the console command.\n *\n * @var string\n */\n protected $signature = 'automated-reports \n {--report-id= : Process a specific report by ID or UUID (bypasses frequency scheduling)}';\n\n /**\n * The console command description.\n *\n * @var string\n */\n protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly). \n Use --report-id to manually trigger a specific report by ID or UUID.';\n\n\n public function __construct(\n private readonly LoggerInterface $logger,\n private readonly BusDispatcher $dispatcher,\n private readonly AutomatedReportsRepository $reportRepository\n ) {\n parent::__construct();\n }\n\n /**\n * Execute the console command.\n *\n * @return int\n */\n public function handle(): int\n {\n $this->logger->info(self::LOG_PREFIX . ' Started');\n\n $now = Carbon::now();\n $isMonday = $now->isMonday();\n $isFirstDayOfMonth = $now->day === 1;\n $currentMonth = $now->month;\n\n // Check if the current month is a quarterly month (January, April, July, October)\n $isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);\n\n $this->logger->info(self::LOG_PREFIX . ' Checking conditions', [\n 'isMonday' => $isMonday,\n 'isFirstDayOfMonth' => $isFirstDayOfMonth,\n 'currentMonth' => $currentMonth,\n 'isQuarterlyMonth' => $isQuarterlyMonth,\n ]);\n\n // Process daily reports\n $this->processReports(AutomatedReportsService::FREQUENCY_DAILY);\n\n // Process weekly reports on Mondays\n if ($isMonday) {\n $this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);\n }\n\n // Process monthly reports on the first day of the month\n if ($isFirstDayOfMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);\n }\n\n // Process quarterly reports on the first day of January, April, July, and October\n if ($isFirstDayOfMonth && $isQuarterlyMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);\n }\n\n $this->logger->info(self::LOG_PREFIX . ' Completed');\n\n return 0;\n }\n\n /**\n * Process reports for a specific frequency.\n *\n * @param string $frequency\n *\n * @return void\n */\n private function processReports(string $frequency): void\n {\n $this->logger->info(self::LOG_PREFIX . \" Processing $frequency reports\");\n\n $reportId = $this->option('report-id');\n if ($reportId !== null) {\n $reports = $this->getReportById($reportId);\n } else {\n // Get all enabled, not deleted reports with active teams for the specified frequency\n $reports = $this->reportRepository->getActiveReportsByFrequency($frequency);\n }\n\n $this->logger->info(self::LOG_PREFIX . \" Found {$reports->count()} $frequency reports to process\");\n\n /** @var AutomatedReport $report */\n foreach ($reports as $report) {\n $this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [\n 'reportUuid' => $report->getUuid(),\n 'teamId' => $report->getTeamId(),\n 'frequency' => $report->getFrequency(),\n 'type' => $report->getType(),\n ]);\n\n $job = $report->isAskJiminnyReport()\n ? new RequestGenerateAskJiminnyReportJob($report->getUuid())\n : new RequestGenerateReportJob($report->getUuid());\n\n $this->dispatcher->dispatch($job);\n }\n }\n\n private function getReportById(string $reportId): Collection\n {\n $report = $this->reportRepository->findByIdOrUuid($reportId);\n\n if ($report === null) {\n $this->logger->warning(self::LOG_PREFIX . ' Report not found for --report-id', ['reportId' => $reportId]);\n $this->warn(\"Report not found: {$reportId}\");\n\n return collect();\n }\n\n if (! $report->getStatus()) {\n $this->logger->warning(self::LOG_PREFIX . ' Report is inactive, processing anyway (manual override)', [\n 'reportId' => $reportId,\n 'reportUuid' => $report->getUuid(),\n ]);\n $this->warn('Report is inactive — processing anyway (manual override).');\n }\n\n $team = $report->getTeam();\n if ($team->getStatus() !== Team::STATUS_ACTIVE) {\n $this->logger->warning(self::LOG_PREFIX . ' Team is not active, processing anyway (manual override)', [\n 'reportId' => $reportId,\n 'reportUuid' => $report->getUuid(),\n 'teamId' => $report->getTeamId(),\n 'teamStatus' => $team->getStatus(),\n ]);\n $this->warn(\"Team #{$report->getTeamId()} is not active — processing anyway (manual override).\");\n }\n\n if ($report->isExpired()) {\n $this->logger->warning(self::LOG_PREFIX . ' Report is expired, processing anyway (manual override)', [\n 'reportId' => $reportId,\n 'reportUuid' => $report->getUuid(),\n 'expiresAt' => $report->getExpiresAt()?->toDateString(),\n ]);\n $this->warn('Report is expired (expires_at: ' . $report->getExpiresAt()?->toDateString() . ') — processing anyway (manual override).');\n }\n\n return collect([$report]);\n }\n}","depth":4,"bounds":{"left":0.09609375,"top":0.00069444446,"width":0.346875,"height":0.99930555},"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands\\Reports;\n\nuse Carbon\\Carbon;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Bus\\Dispatcher as BusDispatcher;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateReportJob;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Psr\\Log\\LoggerInterface;\n\nclass AutomatedReportsCommand extends Command\n{\n /**\n * Log prefix for all log messages\n */\n private const string LOG_PREFIX = '[automated-reports]';\n\n /**\n * The name and signature of the console command.\n *\n * @var string\n */\n protected $signature = 'automated-reports \n {--report-id= : Process a specific report by ID or UUID (bypasses frequency scheduling)}';\n\n /**\n * The console command description.\n *\n * @var string\n */\n protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly). \n Use --report-id to manually trigger a specific report by ID or UUID.';\n\n\n public function __construct(\n private readonly LoggerInterface $logger,\n private readonly BusDispatcher $dispatcher,\n private readonly AutomatedReportsRepository $reportRepository\n ) {\n parent::__construct();\n }\n\n /**\n * Execute the console command.\n *\n * @return int\n */\n public function handle(): int\n {\n $this->logger->info(self::LOG_PREFIX . ' Started');\n\n $now = Carbon::now();\n $isMonday = $now->isMonday();\n $isFirstDayOfMonth = $now->day === 1;\n $currentMonth = $now->month;\n\n // Check if the current month is a quarterly month (January, April, July, October)\n $isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);\n\n $this->logger->info(self::LOG_PREFIX . ' Checking conditions', [\n 'isMonday' => $isMonday,\n 'isFirstDayOfMonth' => $isFirstDayOfMonth,\n 'currentMonth' => $currentMonth,\n 'isQuarterlyMonth' => $isQuarterlyMonth,\n ]);\n\n // Process daily reports\n $this->processReports(AutomatedReportsService::FREQUENCY_DAILY);\n\n // Process weekly reports on Mondays\n if ($isMonday) {\n $this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);\n }\n\n // Process monthly reports on the first day of the month\n if ($isFirstDayOfMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);\n }\n\n // Process quarterly reports on the first day of January, April, July, and October\n if ($isFirstDayOfMonth && $isQuarterlyMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);\n }\n\n $this->logger->info(self::LOG_PREFIX . ' Completed');\n\n return 0;\n }\n\n /**\n * Process reports for a specific frequency.\n *\n * @param string $frequency\n *\n * @return void\n */\n private function processReports(string $frequency): void\n {\n $this->logger->info(self::LOG_PREFIX . \" Processing $frequency reports\");\n\n $reportId = $this->option('report-id');\n if ($reportId !== null) {\n $reports = $this->getReportById($reportId);\n } else {\n // Get all enabled, not deleted reports with active teams for the specified frequency\n $reports = $this->reportRepository->getActiveReportsByFrequency($frequency);\n }\n\n $this->logger->info(self::LOG_PREFIX . \" Found {$reports->count()} $frequency reports to process\");\n\n /** @var AutomatedReport $report */\n foreach ($reports as $report) {\n $this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [\n 'reportUuid' => $report->getUuid(),\n 'teamId' => $report->getTeamId(),\n 'frequency' => $report->getFrequency(),\n 'type' => $report->getType(),\n ]);\n\n $job = $report->isAskJiminnyReport()\n ? new RequestGenerateAskJiminnyReportJob($report->getUuid())\n : new RequestGenerateReportJob($report->getUuid());\n\n $this->dispatcher->dispatch($job);\n }\n }\n\n private function getReportById(string $reportId): Collection\n {\n $report = $this->reportRepository->findByIdOrUuid($reportId);\n\n if ($report === null) {\n $this->logger->warning(self::LOG_PREFIX . ' Report not found for --report-id', ['reportId' => $reportId]);\n $this->warn(\"Report not found: {$reportId}\");\n\n return collect();\n }\n\n if (! $report->getStatus()) {\n $this->logger->warning(self::LOG_PREFIX . ' Report is inactive, processing anyway (manual override)', [\n 'reportId' => $reportId,\n 'reportUuid' => $report->getUuid(),\n ]);\n $this->warn('Report is inactive — processing anyway (manual override).');\n }\n\n $team = $report->getTeam();\n if ($team->getStatus() !== Team::STATUS_ACTIVE) {\n $this->logger->warning(self::LOG_PREFIX . ' Team is not active, processing anyway (manual override)', [\n 'reportId' => $reportId,\n 'reportUuid' => $report->getUuid(),\n 'teamId' => $report->getTeamId(),\n 'teamStatus' => $team->getStatus(),\n ]);\n $this->warn(\"Team #{$report->getTeamId()} is not active — processing anyway (manual override).\");\n }\n\n if ($report->isExpired()) {\n $this->logger->warning(self::LOG_PREFIX . ' Report is expired, processing anyway (manual override)', [\n 'reportId' => $reportId,\n 'reportUuid' => $report->getUuid(),\n 'expiresAt' => $report->getExpiresAt()?->toDateString(),\n ]);\n $this->warn('Report is expired (expires_at: ' . $report->getExpiresAt()?->toDateString() . ') — processing anyway (manual override).');\n }\n\n return collect([$report]);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.0140625,"top":0.041666668,"width":0.028515626,"height":0.021527778},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
5719932180597039997
|
2960206221971779892
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
3
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Services\Kiosk\AutomatedReports;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityActualDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityUpdatedDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\DealInsights\ClosingPeriodFilter;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\User;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
class AskJiminnyReportActivityServiceTest extends TestCase
{
private ActivitySearch&MockObject $activitySearch;
private ElasticActivityRepository&MockObject $elasticRepository;
private LoggerInterface&MockObject $logger;
private AskJiminnyReportActivityService $service;
protected function setUp(): void
{
$this->activitySearch = $this->createMock(ActivitySearch::class);
$this->elasticRepository = $this->createMock(ElasticActivityRepository::class);
$this->logger = $this->createMock(LoggerInterface::class);
$this->service = new AskJiminnyReportActivityService(
$this->activitySearch,
$this->elasticRepository,
$this->logger,
);
}
private function makeFilter(string $key, ?string $value): SearchFilter&MockObject
{
$filter = $this->createMock(SearchFilter::class);
$filter->method('getFilterProperty')->willReturn($key);
$filter->method('getFilterValue')->willReturn($value);
return $filter;
}
private function makeUser(): User&MockObject
{
$tz = new \DateTimeZone('UTC');
$user = $this->createMock(User::class);
$user->method('getTimezone')->willReturn($tz);
$user->method('getId')->willReturn(1);
$user->method('getUuid')->willReturn('user-uuid');
return $user;
}
private function makeSavedSearch(array $filters): Search&MockObject
{
$savedSearch = $this->createMock(Search::class);
$savedSearch->method('getId')->willReturn(42);
$savedSearch->method('getFilters')->willReturn(new \Illuminate\Support\LazyCollection($filters));
return $savedSearch;
}
public function testGetActivityIdsForSavedSearchReturnsIds(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->expects($this->once())
->method('getArrayFilterKeys')
->with($user)
->willReturn([]);
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturn($filterSet);
$this->elasticRepository->expects($this->once())
->method('onDemandSearchIdsOnly')
->willReturn(['id-1', 'id-2', 'id-3']);
$this->logger->expects($this->once())
->method('info')
->with('[AskJiminnyReport] Fetched activity IDs for saved search');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1', 'id-2', 'id-3'], $result);
}
public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->expects($this->once())->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEmpty($result);
}
public function testGetActivityIdsFiltersOutDateFilters(): void
{
$user = $this->makeUser();
$nonDateFilter = $this->makeFilter('owner_id', '123');
$startDateFilter = $this->makeFilter(ActivityActualDate::PARAM_START_DATE, '2025-01-01 00:00:00');
$endDateFilter = $this->makeFilter(ActivityActualDate::PARAM_END_DATE, '2025-01-31 23:59:59');
$updatedFromFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_FROM, '2025-01-01 00:00:00');
$updatedToFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_TO, '2025-01-31 23:59:59');
$savedSearch = $this->makeSavedSearch([
$nonDateFilter,
$startDateFilter,
$endDateFilter,
$updatedFromFilter,
$updatedToFilter,
]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$capturedCriteria = null;
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {
$capturedCriteria = $criteria;
return $filterSet;
});
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->method('info');
$this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertNotNull($capturedCriteria);
}
public function testGetActivityIdsFiltersOutClosingPeriodDateFilters(): void
{
$user = $this->makeUser();
$closingStartFilter = $this->makeFilter(ClosingPeriodFilter::KEY_START_DATE, '2025-01-01');
$closingEndFilter = $this->makeFilter(ClosingPeriodFilter::KEY_END_DATE, '2025-03-31');
$regularFilter = $this->makeFilter('rep_id', '99');
$savedSearch = $this->makeSavedSearch([
$closingStartFilter,
$closingEndFilter,
$regularFilter,
]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1'], $result);
}
public function testGetActivityIdsHandlesArrayFilters(): void
{
$user = $this->makeUser();
$filter1 = $this->makeFilter('outcome', 'positive');
$filter2 = $this->makeFilter('outcome', 'negative');
$savedSearch = $this->makeSavedSearch([$filter1, $filter2]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn(['outcome']);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1'], $result);
}
public function testGetActivityIdsHandlesScalarFilters(): void
{
$user = $this->makeUser();
$filter = $this->makeFilter('direction', 'inbound');
$savedSearch = $this->makeSavedSearch([$filter]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-5']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-5'], $result);
}
public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$capturedCriteria = null;
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {
$capturedCriteria = $criteria;
return $filterSet;
});
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->method('info');
$this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertNotNull($capturedCriteria);
$this->assertFalse($capturedCriteria->isFirstRequest());
}
public function testGetActivityIdsLogsWithCorrectContext(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['a', 'b']);
$this->logger->expects($this->once())
->method('info')
->with(
'[AskJiminnyReport] Fetched activity IDs for saved search',
$this->callback(fn ($context) => $context['saved_search_id'] === 42
&& $context['user_id'] === 1
&& $context['activity_count'] === 2)
);
$this->service->getActivityIdsForSavedSearch($savedSearch, $user);
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands\Reports;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Contracts\Bus\Dispatcher as BusDispatcher;
use Illuminate\Support\Collection;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\RequestGenerateReportJob;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\Team;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Psr\Log\LoggerInterface;
class AutomatedReportsCommand extends Command
{
/**
* Log prefix for all log messages
*/
private const string LOG_PREFIX = '[automated-reports]';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'automated-reports
{--report-id= : Process a specific report by ID or UUID (bypasses frequency scheduling)}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly).
Use --report-id to manually trigger a specific report by ID or UUID.';
public function __construct(
private readonly LoggerInterface $logger,
private readonly BusDispatcher $dispatcher,
private readonly AutomatedReportsRepository $reportRepository
) {
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle(): int
{
$this->logger->info(self::LOG_PREFIX . ' Started');
$now = Carbon::now();
$isMonday = $now->isMonday();
$isFirstDayOfMonth = $now->day === 1;
$currentMonth = $now->month;
// Check if the current month is a quarterly month (January, April, July, October)
$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);
$this->logger->info(self::LOG_PREFIX . ' Checking conditions', [
'isMonday' => $isMonday,
'isFirstDayOfMonth' => $isFirstDayOfMonth,
'currentMonth' => $currentMonth,
'isQuarterlyMonth' => $isQuarterlyMonth,
]);
// Process daily reports
$this->processReports(AutomatedReportsService::FREQUENCY_DAILY);
// Process weekly reports on Mondays
if ($isMonday) {
$this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);
}
// Process monthly reports on the first day of the month
if ($isFirstDayOfMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);
}
// Process quarterly reports on the first day of January, April, July, and October
if ($isFirstDayOfMonth && $isQuarterlyMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);
}
$this->logger->info(self::LOG_PREFIX . ' Completed');
return 0;
}
/**
* Process reports for a specific frequency.
*
* @param string $frequency
*
* @return void
*/
private function processReports(string $frequency): void
{
$this->logger->info(self::LOG_PREFIX . " Processing $frequency reports");
$reportId = $this->option('report-id');
if ($reportId !== null) {
$reports = $this->getReportById($reportId);
} else {
// Get all enabled, not deleted reports with active teams for the specified frequency
$reports = $this->reportRepository->getActiveReportsByFrequency($frequency);
}
$this->logger->info(self::LOG_PREFIX . " Found {$reports->count()} $frequency reports to process");
/** @var AutomatedReport $report */
foreach ($reports as $report) {
$this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [
'reportUuid' => $report->getUuid(),
'teamId' => $report->getTeamId(),
'frequency' => $report->getFrequency(),
'type' => $report->getType(),
]);
$job = $report->isAskJiminnyReport()
? new RequestGenerateAskJiminnyReportJob($report->getUuid())
: new RequestGenerateReportJob($report->getUuid());
$this->dispatcher->dispatch($job);
}
}
private function getReportById(string $reportId): Collection
{
$report = $this->reportRepository->findByIdOrUuid($reportId);
if ($report === null) {
$this->logger->warning(self::LOG_PREFIX . ' Report not found for --report-id', ['reportId' => $reportId]);
$this->warn("Report not found: {$reportId}");
return collect();
}
if (! $report->getStatus()) {
$this->logger->warning(self::LOG_PREFIX . ' Report is inactive, processing anyway (manual override)', [
'reportId' => $reportId,
'reportUuid' => $report->getUuid(),
]);
$this->warn('Report is inactive — processing anyway (manual override).');
}
$team = $report->getTeam();
if ($team->getStatus() !== Team::STATUS_ACTIVE) {
$this->logger->warning(self::LOG_PREFIX . ' Team is not active, processing anyway (manual override)', [
'reportId' => $reportId,
'reportUuid' => $report->getUuid(),
'teamId' => $report->getTeamId(),
'teamStatus' => $team->getStatus(),
]);
$this->warn("Team #{$report->getTeamId()} is not active — processing anyway (manual override).");
}
if ($report->isExpired()) {
$this->logger->warning(self::LOG_PREFIX . ' Report is expired, processing anyway (manual override)', [
'reportId' => $reportId,
'reportUuid' => $report->getUuid(),
'expiresAt' => $report->getExpiresAt()?->toDateString(),
]);
$this->warn('Report is expired (expires_at: ' . $report->getExpiresAt()?->toDateString() . ') — processing anyway (manual override).');
}
return collect([$report]);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
11202
|
|
11206
|
223
|
2
|
2026-04-14T09:19:47.643050+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158387643_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormViewNavigatelaraveRefactonWindowFVravsco.i PhpStormViewNavigatelaraveRefactonWindowFVravsco.isv#11894 on.lY-18909-automated-renorts-ask-liminnvkProject vProphetAiv D Reports© AutomatedReportsCl© AutomatedReportsRe© AutomatedReportsSt© CreateMockAskJimir© DeleteReportComma© GenerateMarketingR© Team.php© Usage.phpD Slack_leamsD TracksO TranscriptionO TwilioD UsersVocabularyDZoom© CoachingFeedbacksUpr© Command.php© CreateDatabaseUsers.pc Daraoase oecountoi© DeleteOldAiCrmNotesC:© DeleteS3LeftoversComiDevPostmanCommand./© DiarizeViaAiParticipantk© EncryptTokensComman© EngagementStatsRegen© FeatureFlagsHelper.php© FixCrossTenantissues.p(C) FlushRolesPermissions(© GeneratelnternalWebho• GroupSetDefaultLanguaHelperTruncateCoachin© HubspotJournalPollingC© HubspotWebhookServic©ImportRecording.php@ Imnortli|sercFromCcvEilC IterateUsersCommand.cJiminnvcacheclearcom(c) minnv Deouacommanc(c)Jminnvser-ncrvotedio(c) Jiminny okenintocomm© MakeSlackLiveCoaching© ManageScimForTeam.p© MarkBranchForEnvironn© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesCom(e RecalculatebealkiskscoC) RemoveDeleteMarkersd(C) RemoveExpiredNudaes© RemoveUnusedParticip:© ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© ReportController.phpJiminnybeouecommana.ongAulomaleakeporissendcommand.ong© AddLayoutEntities.php) AutomatedReportsService.php©) CreateActivityLoggeaevent.onp© AutomatedReportsCommand.php x© Team.php© CreateHeldActivityEvent.php© UserPilotActivityListener.php= custom.log= laravel.logA SF [jiminny@localhost]Hs local liminnyalocalnostconsole PRODL console [EUlC AutomatedReportsCallbackService.phpRequestGenerateask.lminnvRenor.lob.onn© RequestGenerateReportJob.php© AutomatedReportResult.php© AutomatedReport.phpA2^¿ consoe STAGINGII© AskJiminnyReportActivityService.php© ActivitySearch.php•OnDemandV2Controller.phprilterDerinitioncollection.ongC Criteria.php© AskJiminnyReportActivityServiceTest.php x© RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityServiceTe0bject $logger;© HistoryService.phpBLMSAY19 D31 Ct39 G43 Ct\Team;tories\AutomatedReportsRepository;es\Kiosk\AutomatedReports\AutomatedReportsService;Interface;iryserulcce oserucen29 6t >oidf..}orscolliano extenos coniianoi› tring $key, ?string $value): SearchFilter&Mock0bject(...}For all log messagesstring LOG_PREFIX = '[automated-reports]':› User&MockObjectf...}1 signature of the console command.› rch(array $filters): Search&MockObject{...}71 >tyIdsForSavedSearchReturnsIds(): voidf...}lature = 'automated-reportsid= : Process a specific report by ID or UUID (bypasses frequency scheduling)}':100 % > tyIdsForSavedSearchReturnsEmptyWhenNoResults(): voidf...}command description.117118 % > tyIdsFiltersOutDateFilters(): voidf...}156157 %>tyIdsFilters0utClosingPeriodDateFilters(): voidf..185 M >tyIdsHandLesArrayFilters(): voidf...3pription = 'Process automated reports based on their frequency (weekly, monthly, qU 206 86>'t-id to manually trigger a specific report by ID or UUID.':tyIdsHandlesScalarFilters(): void{...}tyIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults__constructCadonly LoggerInterface $logger,adonly BusDispatcher $dispatcher,adonly AutomatedReportsRepository $reportRepository224225 ₽L40eSavedSearch([]):229230eMock( originalClassName: FilterDefinitionCollection::class);construct();chodl constraint: 'gecArrayrilterkeys )->wLLcreturnuLJ:234255console commandpects ($this->once())tOnDemandPageFilterSet')function (Criteria $criteria) use ($filterSet, &$capturedCrith handle(): intjer->info(self::LOG_PREFIX . ' Started'):bon::now();= snow->1SMondayO;Vutmonun = show-sdav szsiuith = Snow->month:237242243244245246247248— 247200>method( constraint: 'onDemandSearchIdsOnly') ->willReturn([]);istraint: 'info');tyIdsForSavedSearch($savedSearch, $user);reourrera-nsrurstre.uesto.252 8Support Daily - in 2h 41mAskJiminnyReportActivityServiceT…Defaults100% C2Tue 14 Apr 12:19:47CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ...Explain it to me again.. Why is there issue with thhat? Where is it expected and why do I need to work with that. How is it used [EMAIL] vasee oll saveuoedichl. Une los I on celllane ane ii.OnSkJLLmynedOT ACLeVeLyDetVacerpnorL44-00 snoule De salllewLet me read the OnDemandV2Controller to understand how it builds criteria there:Read OnDemanavzcoiNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php: 90-93:0 phpVO Repository OnDemandActivitySearch\Criteria:: createFromRequest(arrav meroelsreques→>aluo.' Um1t =>"ropcount, pade$user->getTimezone()→ 11),It passes Srequest->all() - which includes sequence_number from the URL (e.g. sequence_number=4 from your staging URL). So when a user has beenpaginating on the frontend, sequence_number is naturally non-zero.The full explanationyou didn't ask for them:hsiauist kecuestaouncskenererurns true wnen seauenceNumber === u wnenttsine "trstreduestneseumolci detauirs kickinauromaricalveventFiterDefault on first requestEffectActiv1tvburat zonkangelmin_duration = 1 minDroos 0-secono activitiesActivityRecordedonly_recorded = 1Recorded activities onlvOrganiserGroupInUser's own groupRestricts to user's groupFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest = false → no implicit defaults →returns 15 activities.AskJiminnyReportActivitySeervice (before the fix) built params from the saved search filters but never included sequence number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-onlv + duration>1 together matchednothing.Why sequence_number=1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionally stripped (that's existing logic in DATE_FILTER_KEYS )3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representsSetting sequence number=1 is the minimal, correct signal: "this is not a fresh session open, don't apply page-load defaults". The criteria is otherwise builtidentically to how the controller builds it - same Criteria:: createFromRequest, same get0nDemandPageFilterSet, same onDemandSearchIds0nly - so theresults will now match.Ö ul ..Ask anything (2*L)+ <> CodeClaude Sonnet 4.6winasun leUTF-8f 4 spaces...
|
NULL
|
5616108313348376766
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormViewNavigatelaraveRefactonWindowFVravsco.i PhpStormViewNavigatelaraveRefactonWindowFVravsco.isv#11894 on.lY-18909-automated-renorts-ask-liminnvkProject vProphetAiv D Reports© AutomatedReportsCl© AutomatedReportsRe© AutomatedReportsSt© CreateMockAskJimir© DeleteReportComma© GenerateMarketingR© Team.php© Usage.phpD Slack_leamsD TracksO TranscriptionO TwilioD UsersVocabularyDZoom© CoachingFeedbacksUpr© Command.php© CreateDatabaseUsers.pc Daraoase oecountoi© DeleteOldAiCrmNotesC:© DeleteS3LeftoversComiDevPostmanCommand./© DiarizeViaAiParticipantk© EncryptTokensComman© EngagementStatsRegen© FeatureFlagsHelper.php© FixCrossTenantissues.p(C) FlushRolesPermissions(© GeneratelnternalWebho• GroupSetDefaultLanguaHelperTruncateCoachin© HubspotJournalPollingC© HubspotWebhookServic©ImportRecording.php@ Imnortli|sercFromCcvEilC IterateUsersCommand.cJiminnvcacheclearcom(c) minnv Deouacommanc(c)Jminnvser-ncrvotedio(c) Jiminny okenintocomm© MakeSlackLiveCoaching© ManageScimForTeam.p© MarkBranchForEnvironn© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesCom(e RecalculatebealkiskscoC) RemoveDeleteMarkersd(C) RemoveExpiredNudaes© RemoveUnusedParticip:© ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© ReportController.phpJiminnybeouecommana.ongAulomaleakeporissendcommand.ong© AddLayoutEntities.php) AutomatedReportsService.php©) CreateActivityLoggeaevent.onp© AutomatedReportsCommand.php x© Team.php© CreateHeldActivityEvent.php© UserPilotActivityListener.php= custom.log= laravel.logA SF [jiminny@localhost]Hs local liminnyalocalnostconsole PRODL console [EUlC AutomatedReportsCallbackService.phpRequestGenerateask.lminnvRenor.lob.onn© RequestGenerateReportJob.php© AutomatedReportResult.php© AutomatedReport.phpA2^¿ consoe STAGINGII© AskJiminnyReportActivityService.php© ActivitySearch.php•OnDemandV2Controller.phprilterDerinitioncollection.ongC Criteria.php© AskJiminnyReportActivityServiceTest.php x© RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityServiceTe0bject $logger;© HistoryService.phpBLMSAY19 D31 Ct39 G43 Ct\Team;tories\AutomatedReportsRepository;es\Kiosk\AutomatedReports\AutomatedReportsService;Interface;iryserulcce oserucen29 6t >oidf..}orscolliano extenos coniianoi› tring $key, ?string $value): SearchFilter&Mock0bject(...}For all log messagesstring LOG_PREFIX = '[automated-reports]':› User&MockObjectf...}1 signature of the console command.› rch(array $filters): Search&MockObject{...}71 >tyIdsForSavedSearchReturnsIds(): voidf...}lature = 'automated-reportsid= : Process a specific report by ID or UUID (bypasses frequency scheduling)}':100 % > tyIdsForSavedSearchReturnsEmptyWhenNoResults(): voidf...}command description.117118 % > tyIdsFiltersOutDateFilters(): voidf...}156157 %>tyIdsFilters0utClosingPeriodDateFilters(): voidf..185 M >tyIdsHandLesArrayFilters(): voidf...3pription = 'Process automated reports based on their frequency (weekly, monthly, qU 206 86>'t-id to manually trigger a specific report by ID or UUID.':tyIdsHandlesScalarFilters(): void{...}tyIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults__constructCadonly LoggerInterface $logger,adonly BusDispatcher $dispatcher,adonly AutomatedReportsRepository $reportRepository224225 ₽L40eSavedSearch([]):229230eMock( originalClassName: FilterDefinitionCollection::class);construct();chodl constraint: 'gecArrayrilterkeys )->wLLcreturnuLJ:234255console commandpects ($this->once())tOnDemandPageFilterSet')function (Criteria $criteria) use ($filterSet, &$capturedCrith handle(): intjer->info(self::LOG_PREFIX . ' Started'):bon::now();= snow->1SMondayO;Vutmonun = show-sdav szsiuith = Snow->month:237242243244245246247248— 247200>method( constraint: 'onDemandSearchIdsOnly') ->willReturn([]);istraint: 'info');tyIdsForSavedSearch($savedSearch, $user);reourrera-nsrurstre.uesto.252 8Support Daily - in 2h 41mAskJiminnyReportActivityServiceT…Defaults100% C2Tue 14 Apr 12:19:47CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ...Explain it to me again.. Why is there issue with thhat? Where is it expected and why do I need to work with that. How is it used [EMAIL] vasee oll saveuoedichl. Une los I on celllane ane ii.OnSkJLLmynedOT ACLeVeLyDetVacerpnorL44-00 snoule De salllewLet me read the OnDemandV2Controller to understand how it builds criteria there:Read OnDemanavzcoiNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php: 90-93:0 phpVO Repository OnDemandActivitySearch\Criteria:: createFromRequest(arrav meroelsreques→>aluo.' Um1t =>"ropcount, pade$user->getTimezone()→ 11),It passes Srequest->all() - which includes sequence_number from the URL (e.g. sequence_number=4 from your staging URL). So when a user has beenpaginating on the frontend, sequence_number is naturally non-zero.The full explanationyou didn't ask for them:hsiauist kecuestaouncskenererurns true wnen seauenceNumber === u wnenttsine "trstreduestneseumolci detauirs kickinauromaricalveventFiterDefault on first requestEffectActiv1tvburat zonkangelmin_duration = 1 minDroos 0-secono activitiesActivityRecordedonly_recorded = 1Recorded activities onlvOrganiserGroupInUser's own groupRestricts to user's groupFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest = false → no implicit defaults →returns 15 activities.AskJiminnyReportActivitySeervice (before the fix) built params from the saved search filters but never included sequence number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-onlv + duration>1 together matchednothing.Why sequence_number=1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionally stripped (that's existing logic in DATE_FILTER_KEYS )3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representsSetting sequence number=1 is the minimal, correct signal: "this is not a fresh session open, don't apply page-load defaults". The criteria is otherwise builtidentically to how the controller builds it - same Criteria:: createFromRequest, same get0nDemandPageFilterSet, same onDemandSearchIds0nly - so theresults will now match.Ö ul ..Ask anything (2*L)+ <> CodeClaude Sonnet 4.6winasun leUTF-8f 4 spaces...
|
NULL
|
|
11208
|
223
|
3
|
2026-04-14T09:19:50.711510+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158390711_m2.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReportsCommand.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
3
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Services\Kiosk\AutomatedReports;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityActualDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityUpdatedDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\DealInsights\ClosingPeriodFilter;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\User;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
class AskJiminnyReportActivityServiceTest extends TestCase
{
private ActivitySearch&MockObject $activitySearch;
private ElasticActivityRepository&MockObject $elasticRepository;
private LoggerInterface&MockObject $logger;
private AskJiminnyReportActivityService $service;
protected function setUp(): void
{
$this->activitySearch = $this->createMock(ActivitySearch::class);
$this->elasticRepository = $this->createMock(ElasticActivityRepository::class);
$this->logger = $this->createMock(LoggerInterface::class);
$this->service = new AskJiminnyReportActivityService(
$this->activitySearch,
$this->elasticRepository,
$this->logger,
);
}
private function makeFilter(string $key, ?string $value): SearchFilter&MockObject
{
$filter = $this->createMock(SearchFilter::class);
$filter->method('getFilterProperty')->willReturn($key);
$filter->method('getFilterValue')->willReturn($value);
return $filter;
}
private function makeUser(): User&MockObject
{
$tz = new \DateTimeZone('UTC');
$user = $this->createMock(User::class);
$user->method('getTimezone')->willReturn($tz);
$user->method('getId')->willReturn(1);
$user->method('getUuid')->willReturn('user-uuid');
return $user;
}
private function makeSavedSearch(array $filters): Search&MockObject
{
$savedSearch = $this->createMock(Search::class);
$savedSearch->method('getId')->willReturn(42);
$savedSearch->method('getFilters')->willReturn(new \Illuminate\Support\LazyCollection($filters));
return $savedSearch;
}
public function testGetActivityIdsForSavedSearchReturnsIds(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->expects($this->once())
->method('getArrayFilterKeys')
->with($user)
->willReturn([]);
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturn($filterSet);
$this->elasticRepository->expects($this->once())
->method('onDemandSearchIdsOnly')
->willReturn(['id-1', 'id-2', 'id-3']);
$this->logger->expects($this->once())
->method('info')
->with('[AskJiminnyReport] Fetched activity IDs for saved search');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1', 'id-2', 'id-3'], $result);
}
public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->expects($this->once())->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEmpty($result);
}
public function testGetActivityIdsFiltersOutDateFilters(): void
{
$user = $this->makeUser();
$nonDateFilter = $this->makeFilter('owner_id', '123');
$startDateFilter = $this->makeFilter(ActivityActualDate::PARAM_START_DATE, '2025-01-01 00:00:00');
$endDateFilter = $this->makeFilter(ActivityActualDate::PARAM_END_DATE, '2025-01-31 23:59:59');
$updatedFromFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_FROM, '2025-01-01 00:00:00');
$updatedToFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_TO, '2025-01-31 23:59:59');
$savedSearch = $this->makeSavedSearch([
$nonDateFilter,
$startDateFilter,
$endDateFilter,
$updatedFromFilter,
$updatedToFilter,
]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$capturedCriteria = null;
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {
$capturedCriteria = $criteria;
return $filterSet;
});
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->method('info');
$this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertNotNull($capturedCriteria);
}
public function testGetActivityIdsFiltersOutClosingPeriodDateFilters(): void
{
$user = $this->makeUser();
$closingStartFilter = $this->makeFilter(ClosingPeriodFilter::KEY_START_DATE, '2025-01-01');
$closingEndFilter = $this->makeFilter(ClosingPeriodFilter::KEY_END_DATE, '2025-03-31');
$regularFilter = $this->makeFilter('rep_id', '99');
$savedSearch = $this->makeSavedSearch([
$closingStartFilter,
$closingEndFilter,
$regularFilter,
]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1'], $result);
}
public function testGetActivityIdsHandlesArrayFilters(): void
{
$user = $this->makeUser();
$filter1 = $this->makeFilter('outcome', 'positive');
$filter2 = $this->makeFilter('outcome', 'negative');
$savedSearch = $this->makeSavedSearch([$filter1, $filter2]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn(['outcome']);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1'], $result);
}
public function testGetActivityIdsHandlesScalarFilters(): void
{
$user = $this->makeUser();
$filter = $this->makeFilter('direction', 'inbound');
$savedSearch = $this->makeSavedSearch([$filter]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-5']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-5'], $result);
}
public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$capturedCriteria = null;
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {
$capturedCriteria = $criteria;
return $filterSet;
});
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->method('info');
$this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertNotNull($capturedCriteria);
$this->assertFalse($capturedCriteria->isFirstRequest());
}
public function testGetActivityIdsLogsWithCorrectContext(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['a', 'b']);
$this->logger->expects($this->once())
->method('info')
->with(
'[AskJiminnyReport] Fetched activity IDs for saved search',
$this->callback(fn ($context) => $context['saved_search_id'] === 42
&& $context['user_id'] === 1
&& $context['activity_count'] === 2)
);
$this->service->getActivityIdsForSavedSearch($savedSearch, $user);
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands\Reports;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Contracts\Bus\Dispatcher as BusDispatcher;
use Illuminate\Support\Collection;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\RequestGenerateReportJob;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\Team;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Psr\Log\LoggerInterface;
class AutomatedReportsCommand extends Command
{
/**
* Log prefix for all log messages
*/
private const string LOG_PREFIX = '[automated-reports]';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'automated-reports
{--report-id= : Process a specific report by ID or UUID (bypasses frequency scheduling)}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly).
Use --report-id to manually trigger a specific report by ID or UUID.';
public function __construct(
private readonly LoggerInterface $logger,
private readonly BusDispatcher $dispatcher,
private readonly AutomatedReportsRepository $reportRepository
) {
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle(): int
{
$this->logger->info(self::LOG_PREFIX . ' Started');
$now = Carbon::now();
$isMonday = $now->isMonday();
$isFirstDayOfMonth = $now->day === 1;
$currentMonth = $now->month;
// Check if the current month is a quarterly month (January, April, July, October)
$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);
$this->logger->info(self::LOG_PREFIX . ' Checking conditions', [
'isMonday' => $isMonday,
'isFirstDayOfMonth' => $isFirstDayOfMonth,
'currentMonth' => $currentMonth,
'isQuarterlyMonth' => $isQuarterlyMonth,
]);
// Process daily reports
$this->processReports(AutomatedReportsService::FREQUENCY_DAILY);
// Process weekly reports on Mondays
if ($isMonday) {
$this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);
}
// Process monthly reports on the first day of the month
if ($isFirstDayOfMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);
}
// Process quarterly reports on the first day of January, April, July, and October
if ($isFirstDayOfMonth && $isQuarterlyMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);
}
$this->logger->info(self::LOG_PREFIX . ' Completed');
return 0;
}
/**
* Process reports for a specific frequency.
*
* @param string $frequency
*
* @return void
*/
private function processReports(string $frequency): void
{
$this->logger->info(self::LOG_PREFIX . " Processing $frequency reports");
$reportId = $this->option('report-id');
if ($reportId !== null) {
$reports = $this->getReportById($reportId);
} else {
// Get all enabled, not deleted reports with active teams for the specified frequency
$reports = $this->reportRepository->getActiveReportsByFrequency($frequency);
}
$this->logger->info(self::LOG_PREFIX . " Found {$reports->count()} $frequency reports to process");
/** @var AutomatedReport $report */
foreach ($reports as $report) {
$this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [
'reportUuid' => $report->getUuid(),
'teamId' => $report->getTeamId(),
'frequency' => $report->getFrequency(),
'type' => $report->getType(),
]);
$job = $report->isAskJiminnyReport()
? new RequestGenerateAskJiminnyReportJob($report->getUuid())
: new RequestGenerateReportJob($report->getUuid());
$this->dispatcher->dispatch($job);
}
}
private function getReportById(string $reportId): Collection
{
$report = $this->reportRepository->findByIdOrUuid($reportId);
if ($report === null) {
$this->logger->warning(self::LOG_PREFIX . ' Report not found for --report-id', ['reportId' => $reportId]);
$this->warn("Report not found: {$reportId}");
return collect();
}
if (! $report->getStatus()) {
$this->logger->warning(self::LOG_PREFIX . ' Report is inactive, processing anyway (manual override)', [
'reportId' => $reportId,
'reportUuid' => $report->getUuid(),
]);
$this->warn('Report is inactive — processing anyway (manual override).');
}
$team = $report->getTeam();
if ($team->getStatus() !== Team::STATUS_ACTIVE) {
$this->logger->warning(self::LOG_PREFIX . ' Team is not active, processing anyway (manual override)', [
'reportId' => $reportId,
'reportUuid' => $report->getUuid(),
'teamId' => $report->getTeamId(),
'teamStatus' => $team->getStatus(),
]);
$this->warn("Team #{$report->getTeamId()} is not active — processing anyway (manual override).");
}
if ($report->isExpired()) {
$this->logger->warning(self::LOG_PREFIX . ' Report is expired, processing anyway (manual override)', [
'reportId' => $reportId,
'reportUuid' => $report->getUuid(),
'expiresAt' => $report->getExpiresAt()?->toDateString(),
]);
$this->warn('Report is expired (expires_at: ' . $report->getExpiresAt()?->toDateString() . ') — processing anyway (manual override).');
}
return collect([$report]);
}
}
Project...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","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.7589844,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceT…Defaults","depth":6,"bounds":{"left":0.7769531,"top":0.017361112,"width":0.12382813,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.575,"top":0.19513889,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"3","depth":4,"bounds":{"left":0.58671874,"top":0.19513889,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.5980469,"top":0.19375,"width":0.00859375,"height":0.015972223},"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.60664064,"top":0.19375,"width":0.008203125,"height":0.015972223},"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\\Services\\Kiosk\\AutomatedReports;\n\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityActualDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityUpdatedDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealInsights\\ClosingPeriodFilter;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AskJiminnyReportActivityService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse PHPUnit\\Framework\\TestCase;\nuse Psr\\Log\\LoggerInterface;\n\nclass AskJiminnyReportActivityServiceTest extends TestCase\n{\n private ActivitySearch&MockObject $activitySearch;\n private ElasticActivityRepository&MockObject $elasticRepository;\n private LoggerInterface&MockObject $logger;\n private AskJiminnyReportActivityService $service;\n\n protected function setUp(): void\n {\n $this->activitySearch = $this->createMock(ActivitySearch::class);\n $this->elasticRepository = $this->createMock(ElasticActivityRepository::class);\n $this->logger = $this->createMock(LoggerInterface::class);\n\n $this->service = new AskJiminnyReportActivityService(\n $this->activitySearch,\n $this->elasticRepository,\n $this->logger,\n );\n }\n\n private function makeFilter(string $key, ?string $value): SearchFilter&MockObject\n {\n $filter = $this->createMock(SearchFilter::class);\n $filter->method('getFilterProperty')->willReturn($key);\n $filter->method('getFilterValue')->willReturn($value);\n\n return $filter;\n }\n\n private function makeUser(): User&MockObject\n {\n $tz = new \\DateTimeZone('UTC');\n $user = $this->createMock(User::class);\n $user->method('getTimezone')->willReturn($tz);\n $user->method('getId')->willReturn(1);\n $user->method('getUuid')->willReturn('user-uuid');\n\n return $user;\n }\n\n private function makeSavedSearch(array $filters): Search&MockObject\n {\n $savedSearch = $this->createMock(Search::class);\n $savedSearch->method('getId')->willReturn(42);\n $savedSearch->method('getFilters')->willReturn(new \\Illuminate\\Support\\LazyCollection($filters));\n\n return $savedSearch;\n }\n\n public function testGetActivityIdsForSavedSearchReturnsIds(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->expects($this->once())\n ->method('getArrayFilterKeys')\n ->with($user)\n ->willReturn([]);\n\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturn($filterSet);\n\n $this->elasticRepository->expects($this->once())\n ->method('onDemandSearchIdsOnly')\n ->willReturn(['id-1', 'id-2', 'id-3']);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with('[AskJiminnyReport] Fetched activity IDs for saved search');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1', 'id-2', 'id-3'], $result);\n }\n\n public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n\n $this->logger->expects($this->once())->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEmpty($result);\n }\n\n public function testGetActivityIdsFiltersOutDateFilters(): void\n {\n $user = $this->makeUser();\n\n $nonDateFilter = $this->makeFilter('owner_id', '123');\n $startDateFilter = $this->makeFilter(ActivityActualDate::PARAM_START_DATE, '2025-01-01 00:00:00');\n $endDateFilter = $this->makeFilter(ActivityActualDate::PARAM_END_DATE, '2025-01-31 23:59:59');\n $updatedFromFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_FROM, '2025-01-01 00:00:00');\n $updatedToFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_TO, '2025-01-31 23:59:59');\n\n $savedSearch = $this->makeSavedSearch([\n $nonDateFilter,\n $startDateFilter,\n $endDateFilter,\n $updatedFromFilter,\n $updatedToFilter,\n ]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n\n $capturedCriteria = null;\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {\n $capturedCriteria = $criteria;\n\n return $filterSet;\n });\n\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n $this->logger->method('info');\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertNotNull($capturedCriteria);\n }\n\n public function testGetActivityIdsFiltersOutClosingPeriodDateFilters(): void\n {\n $user = $this->makeUser();\n\n $closingStartFilter = $this->makeFilter(ClosingPeriodFilter::KEY_START_DATE, '2025-01-01');\n $closingEndFilter = $this->makeFilter(ClosingPeriodFilter::KEY_END_DATE, '2025-03-31');\n $regularFilter = $this->makeFilter('rep_id', '99');\n\n $savedSearch = $this->makeSavedSearch([\n $closingStartFilter,\n $closingEndFilter,\n $regularFilter,\n ]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1'], $result);\n }\n\n public function testGetActivityIdsHandlesArrayFilters(): void\n {\n $user = $this->makeUser();\n\n $filter1 = $this->makeFilter('outcome', 'positive');\n $filter2 = $this->makeFilter('outcome', 'negative');\n\n $savedSearch = $this->makeSavedSearch([$filter1, $filter2]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn(['outcome']);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1'], $result);\n }\n\n public function testGetActivityIdsHandlesScalarFilters(): void\n {\n $user = $this->makeUser();\n\n $filter = $this->makeFilter('direction', 'inbound');\n $savedSearch = $this->makeSavedSearch([$filter]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-5']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-5'], $result);\n }\n\n public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n\n $capturedCriteria = null;\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {\n $capturedCriteria = $criteria;\n\n return $filterSet;\n });\n\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n $this->logger->method('info');\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertNotNull($capturedCriteria);\n $this->assertFalse($capturedCriteria->isFirstRequest());\n }\n\n public function testGetActivityIdsLogsWithCorrectContext(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['a', 'b']);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with(\n '[AskJiminnyReport] Fetched activity IDs for saved search',\n $this->callback(fn ($context) => $context['saved_search_id'] === 42\n && $context['user_id'] === 1\n && $context['activity_count'] === 2)\n );\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n }\n}","depth":4,"bounds":{"left":0.32890624,"top":0.0,"width":0.3347656,"height":1.0},"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Services\\Kiosk\\AutomatedReports;\n\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityActualDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityUpdatedDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealInsights\\ClosingPeriodFilter;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AskJiminnyReportActivityService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse PHPUnit\\Framework\\TestCase;\nuse Psr\\Log\\LoggerInterface;\n\nclass AskJiminnyReportActivityServiceTest extends TestCase\n{\n private ActivitySearch&MockObject $activitySearch;\n private ElasticActivityRepository&MockObject $elasticRepository;\n private LoggerInterface&MockObject $logger;\n private AskJiminnyReportActivityService $service;\n\n protected function setUp(): void\n {\n $this->activitySearch = $this->createMock(ActivitySearch::class);\n $this->elasticRepository = $this->createMock(ElasticActivityRepository::class);\n $this->logger = $this->createMock(LoggerInterface::class);\n\n $this->service = new AskJiminnyReportActivityService(\n $this->activitySearch,\n $this->elasticRepository,\n $this->logger,\n );\n }\n\n private function makeFilter(string $key, ?string $value): SearchFilter&MockObject\n {\n $filter = $this->createMock(SearchFilter::class);\n $filter->method('getFilterProperty')->willReturn($key);\n $filter->method('getFilterValue')->willReturn($value);\n\n return $filter;\n }\n\n private function makeUser(): User&MockObject\n {\n $tz = new \\DateTimeZone('UTC');\n $user = $this->createMock(User::class);\n $user->method('getTimezone')->willReturn($tz);\n $user->method('getId')->willReturn(1);\n $user->method('getUuid')->willReturn('user-uuid');\n\n return $user;\n }\n\n private function makeSavedSearch(array $filters): Search&MockObject\n {\n $savedSearch = $this->createMock(Search::class);\n $savedSearch->method('getId')->willReturn(42);\n $savedSearch->method('getFilters')->willReturn(new \\Illuminate\\Support\\LazyCollection($filters));\n\n return $savedSearch;\n }\n\n public function testGetActivityIdsForSavedSearchReturnsIds(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->expects($this->once())\n ->method('getArrayFilterKeys')\n ->with($user)\n ->willReturn([]);\n\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturn($filterSet);\n\n $this->elasticRepository->expects($this->once())\n ->method('onDemandSearchIdsOnly')\n ->willReturn(['id-1', 'id-2', 'id-3']);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with('[AskJiminnyReport] Fetched activity IDs for saved search');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1', 'id-2', 'id-3'], $result);\n }\n\n public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n\n $this->logger->expects($this->once())->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEmpty($result);\n }\n\n public function testGetActivityIdsFiltersOutDateFilters(): void\n {\n $user = $this->makeUser();\n\n $nonDateFilter = $this->makeFilter('owner_id', '123');\n $startDateFilter = $this->makeFilter(ActivityActualDate::PARAM_START_DATE, '2025-01-01 00:00:00');\n $endDateFilter = $this->makeFilter(ActivityActualDate::PARAM_END_DATE, '2025-01-31 23:59:59');\n $updatedFromFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_FROM, '2025-01-01 00:00:00');\n $updatedToFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_TO, '2025-01-31 23:59:59');\n\n $savedSearch = $this->makeSavedSearch([\n $nonDateFilter,\n $startDateFilter,\n $endDateFilter,\n $updatedFromFilter,\n $updatedToFilter,\n ]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n\n $capturedCriteria = null;\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {\n $capturedCriteria = $criteria;\n\n return $filterSet;\n });\n\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n $this->logger->method('info');\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertNotNull($capturedCriteria);\n }\n\n public function testGetActivityIdsFiltersOutClosingPeriodDateFilters(): void\n {\n $user = $this->makeUser();\n\n $closingStartFilter = $this->makeFilter(ClosingPeriodFilter::KEY_START_DATE, '2025-01-01');\n $closingEndFilter = $this->makeFilter(ClosingPeriodFilter::KEY_END_DATE, '2025-03-31');\n $regularFilter = $this->makeFilter('rep_id', '99');\n\n $savedSearch = $this->makeSavedSearch([\n $closingStartFilter,\n $closingEndFilter,\n $regularFilter,\n ]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1'], $result);\n }\n\n public function testGetActivityIdsHandlesArrayFilters(): void\n {\n $user = $this->makeUser();\n\n $filter1 = $this->makeFilter('outcome', 'positive');\n $filter2 = $this->makeFilter('outcome', 'negative');\n\n $savedSearch = $this->makeSavedSearch([$filter1, $filter2]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn(['outcome']);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-1'], $result);\n }\n\n public function testGetActivityIdsHandlesScalarFilters(): void\n {\n $user = $this->makeUser();\n\n $filter = $this->makeFilter('direction', 'inbound');\n $savedSearch = $this->makeSavedSearch([$filter]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-5']);\n $this->logger->method('info');\n\n $result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertEquals(['id-5'], $result);\n }\n\n public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n\n $capturedCriteria = null;\n $this->activitySearch->expects($this->once())\n ->method('getOnDemandPageFilterSet')\n ->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {\n $capturedCriteria = $criteria;\n\n return $filterSet;\n });\n\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);\n $this->logger->method('info');\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n\n $this->assertNotNull($capturedCriteria);\n $this->assertFalse($capturedCriteria->isFirstRequest());\n }\n\n public function testGetActivityIdsLogsWithCorrectContext(): void\n {\n $user = $this->makeUser();\n $savedSearch = $this->makeSavedSearch([]);\n\n $filterSet = $this->createMock(FilterDefinitionCollection::class);\n\n $this->activitySearch->method('getArrayFilterKeys')->willReturn([]);\n $this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);\n $this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['a', 'b']);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with(\n '[AskJiminnyReport] Fetched activity IDs for saved search',\n $this->callback(fn ($context) => $context['saved_search_id'] === 42\n && $context['user_id'] === 1\n && $context['activity_count'] === 2)\n );\n\n $this->service->getActivityIdsForSavedSearch($savedSearch, $user);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.3761719,"top":0.19513889,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.3875,"top":0.19375,"width":0.00859375,"height":0.015972223},"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.39609376,"top":0.19375,"width":0.008203125,"height":0.015972223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands\\Reports;\n\nuse Carbon\\Carbon;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Bus\\Dispatcher as BusDispatcher;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateReportJob;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Psr\\Log\\LoggerInterface;\n\nclass AutomatedReportsCommand extends Command\n{\n /**\n * Log prefix for all log messages\n */\n private const string LOG_PREFIX = '[automated-reports]';\n\n /**\n * The name and signature of the console command.\n *\n * @var string\n */\n protected $signature = 'automated-reports \n {--report-id= : Process a specific report by ID or UUID (bypasses frequency scheduling)}';\n\n /**\n * The console command description.\n *\n * @var string\n */\n protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly). \n Use --report-id to manually trigger a specific report by ID or UUID.';\n\n\n public function __construct(\n private readonly LoggerInterface $logger,\n private readonly BusDispatcher $dispatcher,\n private readonly AutomatedReportsRepository $reportRepository\n ) {\n parent::__construct();\n }\n\n /**\n * Execute the console command.\n *\n * @return int\n */\n public function handle(): int\n {\n $this->logger->info(self::LOG_PREFIX . ' Started');\n\n $now = Carbon::now();\n $isMonday = $now->isMonday();\n $isFirstDayOfMonth = $now->day === 1;\n $currentMonth = $now->month;\n\n // Check if the current month is a quarterly month (January, April, July, October)\n $isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);\n\n $this->logger->info(self::LOG_PREFIX . ' Checking conditions', [\n 'isMonday' => $isMonday,\n 'isFirstDayOfMonth' => $isFirstDayOfMonth,\n 'currentMonth' => $currentMonth,\n 'isQuarterlyMonth' => $isQuarterlyMonth,\n ]);\n\n // Process daily reports\n $this->processReports(AutomatedReportsService::FREQUENCY_DAILY);\n\n // Process weekly reports on Mondays\n if ($isMonday) {\n $this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);\n }\n\n // Process monthly reports on the first day of the month\n if ($isFirstDayOfMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);\n }\n\n // Process quarterly reports on the first day of January, April, July, and October\n if ($isFirstDayOfMonth && $isQuarterlyMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);\n }\n\n $this->logger->info(self::LOG_PREFIX . ' Completed');\n\n return 0;\n }\n\n /**\n * Process reports for a specific frequency.\n *\n * @param string $frequency\n *\n * @return void\n */\n private function processReports(string $frequency): void\n {\n $this->logger->info(self::LOG_PREFIX . \" Processing $frequency reports\");\n\n $reportId = $this->option('report-id');\n if ($reportId !== null) {\n $reports = $this->getReportById($reportId);\n } else {\n // Get all enabled, not deleted reports with active teams for the specified frequency\n $reports = $this->reportRepository->getActiveReportsByFrequency($frequency);\n }\n\n $this->logger->info(self::LOG_PREFIX . \" Found {$reports->count()} $frequency reports to process\");\n\n /** @var AutomatedReport $report */\n foreach ($reports as $report) {\n $this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [\n 'reportUuid' => $report->getUuid(),\n 'teamId' => $report->getTeamId(),\n 'frequency' => $report->getFrequency(),\n 'type' => $report->getType(),\n ]);\n\n $job = $report->isAskJiminnyReport()\n ? new RequestGenerateAskJiminnyReportJob($report->getUuid())\n : new RequestGenerateReportJob($report->getUuid());\n\n $this->dispatcher->dispatch($job);\n }\n }\n\n private function getReportById(string $reportId): Collection\n {\n $report = $this->reportRepository->findByIdOrUuid($reportId);\n\n if ($report === null) {\n $this->logger->warning(self::LOG_PREFIX . ' Report not found for --report-id', ['reportId' => $reportId]);\n $this->warn(\"Report not found: {$reportId}\");\n\n return collect();\n }\n\n if (! $report->getStatus()) {\n $this->logger->warning(self::LOG_PREFIX . ' Report is inactive, processing anyway (manual override)', [\n 'reportId' => $reportId,\n 'reportUuid' => $report->getUuid(),\n ]);\n $this->warn('Report is inactive — processing anyway (manual override).');\n }\n\n $team = $report->getTeam();\n if ($team->getStatus() !== Team::STATUS_ACTIVE) {\n $this->logger->warning(self::LOG_PREFIX . ' Team is not active, processing anyway (manual override)', [\n 'reportId' => $reportId,\n 'reportUuid' => $report->getUuid(),\n 'teamId' => $report->getTeamId(),\n 'teamStatus' => $team->getStatus(),\n ]);\n $this->warn(\"Team #{$report->getTeamId()} is not active — processing anyway (manual override).\");\n }\n\n if ($report->isExpired()) {\n $this->logger->warning(self::LOG_PREFIX . ' Report is expired, processing anyway (manual override)', [\n 'reportId' => $reportId,\n 'reportUuid' => $report->getUuid(),\n 'expiresAt' => $report->getExpiresAt()?->toDateString(),\n ]);\n $this->warn('Report is expired (expires_at: ' . $report->getExpiresAt()?->toDateString() . ') — processing anyway (manual override).');\n }\n\n return collect([$report]);\n }\n}","depth":4,"bounds":{"left":0.09609375,"top":0.00069444446,"width":0.346875,"height":0.99930555},"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands\\Reports;\n\nuse Carbon\\Carbon;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Bus\\Dispatcher as BusDispatcher;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateReportJob;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Psr\\Log\\LoggerInterface;\n\nclass AutomatedReportsCommand extends Command\n{\n /**\n * Log prefix for all log messages\n */\n private const string LOG_PREFIX = '[automated-reports]';\n\n /**\n * The name and signature of the console command.\n *\n * @var string\n */\n protected $signature = 'automated-reports \n {--report-id= : Process a specific report by ID or UUID (bypasses frequency scheduling)}';\n\n /**\n * The console command description.\n *\n * @var string\n */\n protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly). \n Use --report-id to manually trigger a specific report by ID or UUID.';\n\n\n public function __construct(\n private readonly LoggerInterface $logger,\n private readonly BusDispatcher $dispatcher,\n private readonly AutomatedReportsRepository $reportRepository\n ) {\n parent::__construct();\n }\n\n /**\n * Execute the console command.\n *\n * @return int\n */\n public function handle(): int\n {\n $this->logger->info(self::LOG_PREFIX . ' Started');\n\n $now = Carbon::now();\n $isMonday = $now->isMonday();\n $isFirstDayOfMonth = $now->day === 1;\n $currentMonth = $now->month;\n\n // Check if the current month is a quarterly month (January, April, July, October)\n $isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);\n\n $this->logger->info(self::LOG_PREFIX . ' Checking conditions', [\n 'isMonday' => $isMonday,\n 'isFirstDayOfMonth' => $isFirstDayOfMonth,\n 'currentMonth' => $currentMonth,\n 'isQuarterlyMonth' => $isQuarterlyMonth,\n ]);\n\n // Process daily reports\n $this->processReports(AutomatedReportsService::FREQUENCY_DAILY);\n\n // Process weekly reports on Mondays\n if ($isMonday) {\n $this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);\n }\n\n // Process monthly reports on the first day of the month\n if ($isFirstDayOfMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);\n }\n\n // Process quarterly reports on the first day of January, April, July, and October\n if ($isFirstDayOfMonth && $isQuarterlyMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);\n }\n\n $this->logger->info(self::LOG_PREFIX . ' Completed');\n\n return 0;\n }\n\n /**\n * Process reports for a specific frequency.\n *\n * @param string $frequency\n *\n * @return void\n */\n private function processReports(string $frequency): void\n {\n $this->logger->info(self::LOG_PREFIX . \" Processing $frequency reports\");\n\n $reportId = $this->option('report-id');\n if ($reportId !== null) {\n $reports = $this->getReportById($reportId);\n } else {\n // Get all enabled, not deleted reports with active teams for the specified frequency\n $reports = $this->reportRepository->getActiveReportsByFrequency($frequency);\n }\n\n $this->logger->info(self::LOG_PREFIX . \" Found {$reports->count()} $frequency reports to process\");\n\n /** @var AutomatedReport $report */\n foreach ($reports as $report) {\n $this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [\n 'reportUuid' => $report->getUuid(),\n 'teamId' => $report->getTeamId(),\n 'frequency' => $report->getFrequency(),\n 'type' => $report->getType(),\n ]);\n\n $job = $report->isAskJiminnyReport()\n ? new RequestGenerateAskJiminnyReportJob($report->getUuid())\n : new RequestGenerateReportJob($report->getUuid());\n\n $this->dispatcher->dispatch($job);\n }\n }\n\n private function getReportById(string $reportId): Collection\n {\n $report = $this->reportRepository->findByIdOrUuid($reportId);\n\n if ($report === null) {\n $this->logger->warning(self::LOG_PREFIX . ' Report not found for --report-id', ['reportId' => $reportId]);\n $this->warn(\"Report not found: {$reportId}\");\n\n return collect();\n }\n\n if (! $report->getStatus()) {\n $this->logger->warning(self::LOG_PREFIX . ' Report is inactive, processing anyway (manual override)', [\n 'reportId' => $reportId,\n 'reportUuid' => $report->getUuid(),\n ]);\n $this->warn('Report is inactive — processing anyway (manual override).');\n }\n\n $team = $report->getTeam();\n if ($team->getStatus() !== Team::STATUS_ACTIVE) {\n $this->logger->warning(self::LOG_PREFIX . ' Team is not active, processing anyway (manual override)', [\n 'reportId' => $reportId,\n 'reportUuid' => $report->getUuid(),\n 'teamId' => $report->getTeamId(),\n 'teamStatus' => $team->getStatus(),\n ]);\n $this->warn(\"Team #{$report->getTeamId()} is not active — processing anyway (manual override).\");\n }\n\n if ($report->isExpired()) {\n $this->logger->warning(self::LOG_PREFIX . ' Report is expired, processing anyway (manual override)', [\n 'reportId' => $reportId,\n 'reportUuid' => $report->getUuid(),\n 'expiresAt' => $report->getExpiresAt()?->toDateString(),\n ]);\n $this->warn('Report is expired (expires_at: ' . $report->getExpiresAt()?->toDateString() . ') — processing anyway (manual override).');\n }\n\n return collect([$report]);\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,"role_description":"text"}]...
|
2309070296108418966
|
2960206084532827444
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
3
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Services\Kiosk\AutomatedReports;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityActualDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityUpdatedDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\DealInsights\ClosingPeriodFilter;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\User;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
class AskJiminnyReportActivityServiceTest extends TestCase
{
private ActivitySearch&MockObject $activitySearch;
private ElasticActivityRepository&MockObject $elasticRepository;
private LoggerInterface&MockObject $logger;
private AskJiminnyReportActivityService $service;
protected function setUp(): void
{
$this->activitySearch = $this->createMock(ActivitySearch::class);
$this->elasticRepository = $this->createMock(ElasticActivityRepository::class);
$this->logger = $this->createMock(LoggerInterface::class);
$this->service = new AskJiminnyReportActivityService(
$this->activitySearch,
$this->elasticRepository,
$this->logger,
);
}
private function makeFilter(string $key, ?string $value): SearchFilter&MockObject
{
$filter = $this->createMock(SearchFilter::class);
$filter->method('getFilterProperty')->willReturn($key);
$filter->method('getFilterValue')->willReturn($value);
return $filter;
}
private function makeUser(): User&MockObject
{
$tz = new \DateTimeZone('UTC');
$user = $this->createMock(User::class);
$user->method('getTimezone')->willReturn($tz);
$user->method('getId')->willReturn(1);
$user->method('getUuid')->willReturn('user-uuid');
return $user;
}
private function makeSavedSearch(array $filters): Search&MockObject
{
$savedSearch = $this->createMock(Search::class);
$savedSearch->method('getId')->willReturn(42);
$savedSearch->method('getFilters')->willReturn(new \Illuminate\Support\LazyCollection($filters));
return $savedSearch;
}
public function testGetActivityIdsForSavedSearchReturnsIds(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->expects($this->once())
->method('getArrayFilterKeys')
->with($user)
->willReturn([]);
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturn($filterSet);
$this->elasticRepository->expects($this->once())
->method('onDemandSearchIdsOnly')
->willReturn(['id-1', 'id-2', 'id-3']);
$this->logger->expects($this->once())
->method('info')
->with('[AskJiminnyReport] Fetched activity IDs for saved search');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1', 'id-2', 'id-3'], $result);
}
public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->expects($this->once())->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEmpty($result);
}
public function testGetActivityIdsFiltersOutDateFilters(): void
{
$user = $this->makeUser();
$nonDateFilter = $this->makeFilter('owner_id', '123');
$startDateFilter = $this->makeFilter(ActivityActualDate::PARAM_START_DATE, '2025-01-01 00:00:00');
$endDateFilter = $this->makeFilter(ActivityActualDate::PARAM_END_DATE, '2025-01-31 23:59:59');
$updatedFromFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_FROM, '2025-01-01 00:00:00');
$updatedToFilter = $this->makeFilter(ActivityUpdatedDate::PARAM_UPDATED_TO, '2025-01-31 23:59:59');
$savedSearch = $this->makeSavedSearch([
$nonDateFilter,
$startDateFilter,
$endDateFilter,
$updatedFromFilter,
$updatedToFilter,
]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$capturedCriteria = null;
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {
$capturedCriteria = $criteria;
return $filterSet;
});
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->method('info');
$this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertNotNull($capturedCriteria);
}
public function testGetActivityIdsFiltersOutClosingPeriodDateFilters(): void
{
$user = $this->makeUser();
$closingStartFilter = $this->makeFilter(ClosingPeriodFilter::KEY_START_DATE, '2025-01-01');
$closingEndFilter = $this->makeFilter(ClosingPeriodFilter::KEY_END_DATE, '2025-03-31');
$regularFilter = $this->makeFilter('rep_id', '99');
$savedSearch = $this->makeSavedSearch([
$closingStartFilter,
$closingEndFilter,
$regularFilter,
]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1'], $result);
}
public function testGetActivityIdsHandlesArrayFilters(): void
{
$user = $this->makeUser();
$filter1 = $this->makeFilter('outcome', 'positive');
$filter2 = $this->makeFilter('outcome', 'negative');
$savedSearch = $this->makeSavedSearch([$filter1, $filter2]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn(['outcome']);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-1']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-1'], $result);
}
public function testGetActivityIdsHandlesScalarFilters(): void
{
$user = $this->makeUser();
$filter = $this->makeFilter('direction', 'inbound');
$savedSearch = $this->makeSavedSearch([$filter]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['id-5']);
$this->logger->method('info');
$result = $this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertEquals(['id-5'], $result);
}
public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$capturedCriteria = null;
$this->activitySearch->expects($this->once())
->method('getOnDemandPageFilterSet')
->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {
$capturedCriteria = $criteria;
return $filterSet;
});
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn([]);
$this->logger->method('info');
$this->service->getActivityIdsForSavedSearch($savedSearch, $user);
$this->assertNotNull($capturedCriteria);
$this->assertFalse($capturedCriteria->isFirstRequest());
}
public function testGetActivityIdsLogsWithCorrectContext(): void
{
$user = $this->makeUser();
$savedSearch = $this->makeSavedSearch([]);
$filterSet = $this->createMock(FilterDefinitionCollection::class);
$this->activitySearch->method('getArrayFilterKeys')->willReturn([]);
$this->activitySearch->method('getOnDemandPageFilterSet')->willReturn($filterSet);
$this->elasticRepository->method('onDemandSearchIdsOnly')->willReturn(['a', 'b']);
$this->logger->expects($this->once())
->method('info')
->with(
'[AskJiminnyReport] Fetched activity IDs for saved search',
$this->callback(fn ($context) => $context['saved_search_id'] === 42
&& $context['user_id'] === 1
&& $context['activity_count'] === 2)
);
$this->service->getActivityIdsForSavedSearch($savedSearch, $user);
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands\Reports;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Contracts\Bus\Dispatcher as BusDispatcher;
use Illuminate\Support\Collection;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\RequestGenerateReportJob;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\Team;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Psr\Log\LoggerInterface;
class AutomatedReportsCommand extends Command
{
/**
* Log prefix for all log messages
*/
private const string LOG_PREFIX = '[automated-reports]';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'automated-reports
{--report-id= : Process a specific report by ID or UUID (bypasses frequency scheduling)}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly).
Use --report-id to manually trigger a specific report by ID or UUID.';
public function __construct(
private readonly LoggerInterface $logger,
private readonly BusDispatcher $dispatcher,
private readonly AutomatedReportsRepository $reportRepository
) {
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle(): int
{
$this->logger->info(self::LOG_PREFIX . ' Started');
$now = Carbon::now();
$isMonday = $now->isMonday();
$isFirstDayOfMonth = $now->day === 1;
$currentMonth = $now->month;
// Check if the current month is a quarterly month (January, April, July, October)
$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);
$this->logger->info(self::LOG_PREFIX . ' Checking conditions', [
'isMonday' => $isMonday,
'isFirstDayOfMonth' => $isFirstDayOfMonth,
'currentMonth' => $currentMonth,
'isQuarterlyMonth' => $isQuarterlyMonth,
]);
// Process daily reports
$this->processReports(AutomatedReportsService::FREQUENCY_DAILY);
// Process weekly reports on Mondays
if ($isMonday) {
$this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);
}
// Process monthly reports on the first day of the month
if ($isFirstDayOfMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);
}
// Process quarterly reports on the first day of January, April, July, and October
if ($isFirstDayOfMonth && $isQuarterlyMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);
}
$this->logger->info(self::LOG_PREFIX . ' Completed');
return 0;
}
/**
* Process reports for a specific frequency.
*
* @param string $frequency
*
* @return void
*/
private function processReports(string $frequency): void
{
$this->logger->info(self::LOG_PREFIX . " Processing $frequency reports");
$reportId = $this->option('report-id');
if ($reportId !== null) {
$reports = $this->getReportById($reportId);
} else {
// Get all enabled, not deleted reports with active teams for the specified frequency
$reports = $this->reportRepository->getActiveReportsByFrequency($frequency);
}
$this->logger->info(self::LOG_PREFIX . " Found {$reports->count()} $frequency reports to process");
/** @var AutomatedReport $report */
foreach ($reports as $report) {
$this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [
'reportUuid' => $report->getUuid(),
'teamId' => $report->getTeamId(),
'frequency' => $report->getFrequency(),
'type' => $report->getType(),
]);
$job = $report->isAskJiminnyReport()
? new RequestGenerateAskJiminnyReportJob($report->getUuid())
: new RequestGenerateReportJob($report->getUuid());
$this->dispatcher->dispatch($job);
}
}
private function getReportById(string $reportId): Collection
{
$report = $this->reportRepository->findByIdOrUuid($reportId);
if ($report === null) {
$this->logger->warning(self::LOG_PREFIX . ' Report not found for --report-id', ['reportId' => $reportId]);
$this->warn("Report not found: {$reportId}");
return collect();
}
if (! $report->getStatus()) {
$this->logger->warning(self::LOG_PREFIX . ' Report is inactive, processing anyway (manual override)', [
'reportId' => $reportId,
'reportUuid' => $report->getUuid(),
]);
$this->warn('Report is inactive — processing anyway (manual override).');
}
$team = $report->getTeam();
if ($team->getStatus() !== Team::STATUS_ACTIVE) {
$this->logger->warning(self::LOG_PREFIX . ' Team is not active, processing anyway (manual override)', [
'reportId' => $reportId,
'reportUuid' => $report->getUuid(),
'teamId' => $report->getTeamId(),
'teamStatus' => $team->getStatus(),
]);
$this->warn("Team #{$report->getTeamId()} is not active — processing anyway (manual override).");
}
if ($report->isExpired()) {
$this->logger->warning(self::LOG_PREFIX . ' Report is expired, processing anyway (manual override)', [
'reportId' => $reportId,
'reportUuid' => $report->getUuid(),
'expiresAt' => $report->getExpiresAt()?->toDateString(),
]);
$this->warn('Report is expired (expires_at: ' . $report->getExpiresAt()?->toDateString() . ') — processing anyway (manual override).');
}
return collect([$report]);
}
}
Project...
|
11206
|
|
11210
|
223
|
4
|
2026-04-14T09:19:53.644665+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158393644_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormProject vFileEditFV faVsco.js vViewNavigat PhpStormProject vFileEditFV faVsco.js vViewNavigateCodeLaravelRefactorToolsWindowHelp#11894 on JY-18909-automated-reports-ask-iminny K vProphetAiv D Reports© AutomatedReportsCl© AutomatedReportsRe© AutomatedReportsSt© CreateMockAskJimir© DeleteReportComma© GenerateMarketingR© Team.php© Usage.phpD Slack• TeamsD TracksO TranscriptionO TwilioD UsersVocabularyDZoom© CoachingFeedbacksUpr© Command.php© CreateDatabaseUsers.pc Daraoase oecountoi© DeleteOldAiCrmNotesC:© DeleteS3LeftoversComiDevPostmanCommand./© DiarizeViaAiParticipantk© EncryptTokensComman© EngagementStatsRegen© FeatureFlagsHelper.php© FixCrossTenantissues.p© FlushRolesPermissionsC© GeneratelnternalWebho• GroupSetDefaultLangua© HelperTruncateCoachin© HubspotJournalPollingC© HubspotWebhookServic©ImportRecording.phpemnortcorc.romecv=llC IterateUsersCommand.cJiminnvcacheclearcom(c) minnv Deouacommanc(c)Jminnvser-ncrvotedio(c) Jiminny okenintocomm© MakeSlackLiveCoaching© ManageScimForTeam.p© MarkBranchForEnvironn© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesCom(e RecalculatebealkiskscoC) RemoveDeleteMarkersd(C) RemoveExpiredNudaes© RemoveUnusedParticip:© ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCorTests passed: 1 (11 minutes ago)© ReportController.php© AutomatedReportsSendCommand.php© JiminnyDebugCommand.php© AddLayoutEntities.php© AutomatedReportsService.phpC) CreateActivityLoggedEvent.phpAutomatedReportsCommand.php x© Team.php© CreateHeldActivityEvent.php© UserPilotActivityListener.php= custom.log= laravel.logA SF [jiminny@localhost]Hs local liminnyalocalnostconsole PRODL console [EUlC AutomatedReportsCallbackService.php(0) RequestGenerate.sk.liminnvRenor.ob.ohn© RequestGenerateReportJob.php© AutomatedReportResult.php© AutomatedReport.phpA2^¿ consoe STAGINGII© AskJiminnyReportActivityService.php© ActivitySearch.php•OnDemandV2Controller.phprilterDerinitioncollection.onpC Criteria.php© AskJiminnyReportActivityServiceTest.php x© RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityServiceTe0bject $logger;© HistoryService.phpBLMSAY19 D31 Ct39 G43 Ct52\Team;tories\AutomatedReportsRepository;es\Kiosk\AutomatedReports\AutomatedReportsService;Interface;iryserulcce oserucen29 6t >oidf.orscolliano extenos coniianol› tring $key, ?string $value): SearchFilter&Mock0bject(...}For all log messagesstring LOG_PREFIX = '[automated-reports]':› User&MockObjectf...}1 signature of the console command.› rch(array $filters): Search&MockObject{...}71 >tyIdsForSavedSearchReturnsIds(): voidf...}lature ='automated-reportsid= : Process a specific report by ID or UUID (bypasses frequency scheduling)}':100 % > tyIdsForSavedSearchReturnsEmptyWhenNoResults(): voidf...}command description.117118 % > tyIdsFiltersOutDateFilters(): voidf...}156157 %>tyIdsFilters0utClosingPeriodDateFilters(): voidf..}185 M >tyIdsHandLesArrayFilters(): voidf...3pription = 'Process automated reports based on their frequency (weekly, monthly, qU 206 86>'t-id to manually trigger a specific report by ID or UUID.':tyIdsHandlesScalarFilters(): void{...;tyIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults__constructCadonly LoggerInterface $logger,adonly BusDispatcher $dispatcher,adonly AutomatedReportsRepository $reportRepository224225 ₽L40eSavedSearch([]):229230eMock( originalClassName: FilterDefinitionCollection::class);construct();chodl constraint: 'gecArrayrilterkeys )->wLLcreturnuLJ:1 To Lonmand234255console commandpects ($this->once())tOnDemandPageFilterSet')function (Criteria $criteria) use ($filterSet, &$capturedCrith handle(): intjer->info(self::LOG_PREFIX . ' Started'):bon::now();= snow->1SMondayO;VutMonun = snow-sdav sez iith = Snow->month:237242243244245246247248— 247200>method( constraint: 'onDemandSearchIdsOnly') ->willReturn([]);istraint: 'info');tyIdsForSavedSearch($savedSearch, $user);reourrerarnsrurstre.uest.252 8j Support Daily • in 2h 41 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:19:53CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ...Explain it to me again. Why is there issue with thhat? Where is it expected and why do I need to work with that. How is it used inclllanuvzconeroes vasee oll saveuoedichl. Une los m on celllane ane iiOnSkdILmlуnedoT LheLeveLyetVLceronorL44-00 snoule De sallleCascadeWLet me read the OnDemandV2Controller to understand how it builds criteria there:Read OnDemanavzcontNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php: 90-93:0 phpVO Repository OnDemandActivitySearch\Criteria::createFromRequest(arrav meroesrequesoaluo.' umir => 00c0unt "oade$user->getTimezone()It passes Srequest->all() - which includes sequence_number from the URL (e.g. sequence_number=4 from your staging URL). So when a user has beenpaginating on the frontend, sequence_number is naturally non-zero.The full explanationyou didn't ask for them:hsiauist kecuestaouncskenererurns true wnen seauenceNumber === u wnenttsine "trstreduestneseumolci detauirs kickinauromaricalveventFiterDefault on first requestEffectActiv1tvburat zonkangelmin_duration = 1 minDroos 0-secono activitiesActivityRecordedonly_recorded = 1Recorded activities onlvOrganiserGroupInUser's own groupRestricts to user's groupFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest = false → no implicit defaults →returns 15 activities.AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-onlv + duration>1 together matchednothing.Why sequence_number=1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionally stripped (that's existing logic in DATE_FILTER_KEYS )3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representsSetting sequence number=1 is the minimal, correct signal: "this is not a fresh session open, don't apply page-load defaults". The criteria is otherwise builtidentically to how the controller builds it - same Criteria::createFromRequest, same get0nDemandPageFilterSet, same onDemandSearchIds0nly - so theresults will now match.Ö ul ...Ask anything (2*L)+ <> CodeClaude Sonnet 4.6winasun leamsuir-o( 4 spaces...
|
NULL
|
-4878574417365180208
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormProject vFileEditFV faVsco.js vViewNavigat PhpStormProject vFileEditFV faVsco.js vViewNavigateCodeLaravelRefactorToolsWindowHelp#11894 on JY-18909-automated-reports-ask-iminny K vProphetAiv D Reports© AutomatedReportsCl© AutomatedReportsRe© AutomatedReportsSt© CreateMockAskJimir© DeleteReportComma© GenerateMarketingR© Team.php© Usage.phpD Slack• TeamsD TracksO TranscriptionO TwilioD UsersVocabularyDZoom© CoachingFeedbacksUpr© Command.php© CreateDatabaseUsers.pc Daraoase oecountoi© DeleteOldAiCrmNotesC:© DeleteS3LeftoversComiDevPostmanCommand./© DiarizeViaAiParticipantk© EncryptTokensComman© EngagementStatsRegen© FeatureFlagsHelper.php© FixCrossTenantissues.p© FlushRolesPermissionsC© GeneratelnternalWebho• GroupSetDefaultLangua© HelperTruncateCoachin© HubspotJournalPollingC© HubspotWebhookServic©ImportRecording.phpemnortcorc.romecv=llC IterateUsersCommand.cJiminnvcacheclearcom(c) minnv Deouacommanc(c)Jminnvser-ncrvotedio(c) Jiminny okenintocomm© MakeSlackLiveCoaching© ManageScimForTeam.p© MarkBranchForEnvironn© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php© PurgeSoftDeletedOppor© PurgeSyncBatchesCom(e RecalculatebealkiskscoC) RemoveDeleteMarkersd(C) RemoveExpiredNudaes© RemoveUnusedParticip:© ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCorTests passed: 1 (11 minutes ago)© ReportController.php© AutomatedReportsSendCommand.php© JiminnyDebugCommand.php© AddLayoutEntities.php© AutomatedReportsService.phpC) CreateActivityLoggedEvent.phpAutomatedReportsCommand.php x© Team.php© CreateHeldActivityEvent.php© UserPilotActivityListener.php= custom.log= laravel.logA SF [jiminny@localhost]Hs local liminnyalocalnostconsole PRODL console [EUlC AutomatedReportsCallbackService.php(0) RequestGenerate.sk.liminnvRenor.ob.ohn© RequestGenerateReportJob.php© AutomatedReportResult.php© AutomatedReport.phpA2^¿ consoe STAGINGII© AskJiminnyReportActivityService.php© ActivitySearch.php•OnDemandV2Controller.phprilterDerinitioncollection.onpC Criteria.php© AskJiminnyReportActivityServiceTest.php x© RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityServiceTe0bject $logger;© HistoryService.phpBLMSAY19 D31 Ct39 G43 Ct52\Team;tories\AutomatedReportsRepository;es\Kiosk\AutomatedReports\AutomatedReportsService;Interface;iryserulcce oserucen29 6t >oidf.orscolliano extenos coniianol› tring $key, ?string $value): SearchFilter&Mock0bject(...}For all log messagesstring LOG_PREFIX = '[automated-reports]':› User&MockObjectf...}1 signature of the console command.› rch(array $filters): Search&MockObject{...}71 >tyIdsForSavedSearchReturnsIds(): voidf...}lature ='automated-reportsid= : Process a specific report by ID or UUID (bypasses frequency scheduling)}':100 % > tyIdsForSavedSearchReturnsEmptyWhenNoResults(): voidf...}command description.117118 % > tyIdsFiltersOutDateFilters(): voidf...}156157 %>tyIdsFilters0utClosingPeriodDateFilters(): voidf..}185 M >tyIdsHandLesArrayFilters(): voidf...3pription = 'Process automated reports based on their frequency (weekly, monthly, qU 206 86>'t-id to manually trigger a specific report by ID or UUID.':tyIdsHandlesScalarFilters(): void{...;tyIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults__constructCadonly LoggerInterface $logger,adonly BusDispatcher $dispatcher,adonly AutomatedReportsRepository $reportRepository224225 ₽L40eSavedSearch([]):229230eMock( originalClassName: FilterDefinitionCollection::class);construct();chodl constraint: 'gecArrayrilterkeys )->wLLcreturnuLJ:1 To Lonmand234255console commandpects ($this->once())tOnDemandPageFilterSet')function (Criteria $criteria) use ($filterSet, &$capturedCrith handle(): intjer->info(self::LOG_PREFIX . ' Started'):bon::now();= snow->1SMondayO;VutMonun = snow-sdav sez iith = Snow->month:237242243244245246247248— 247200>method( constraint: 'onDemandSearchIdsOnly') ->willReturn([]);istraint: 'info');tyIdsForSavedSearch($savedSearch, $user);reourrerarnsrurstre.uest.252 8j Support Daily • in 2h 41 mAAskJiminnyReportActivityServiceT…Defaults100% C•Tue 14 Apr 12:19:53CascadeFixing ReportControllerAutomated Report MarFixing Ask Jiminny Rep+D ...Explain it to me again. Why is there issue with thhat? Where is it expected and why do I need to work with that. How is it used inclllanuvzconeroes vasee oll saveuoedichl. Une los m on celllane ane iiOnSkdILmlуnedoT LheLeveLyetVLceronorL44-00 snoule De sallleCascadeWLet me read the OnDemandV2Controller to understand how it builds criteria there:Read OnDemanavzcontNow look at the key difference. The controller's getContextForAskAnythingByFilter at OnDemandV2Controller.php: 90-93:0 phpVO Repository OnDemandActivitySearch\Criteria::createFromRequest(arrav meroesrequesoaluo.' umir => 00c0unt "oade$user->getTimezone()It passes Srequest->all() - which includes sequence_number from the URL (e.g. sequence_number=4 from your staging URL). So when a user has beenpaginating on the frontend, sequence_number is naturally non-zero.The full explanationyou didn't ask for them:hsiauist kecuestaouncskenererurns true wnen seauenceNumber === u wnenttsine "trstreduestneseumolci detauirs kickinauromaricalveventFiterDefault on first requestEffectActiv1tvburat zonkangelmin_duration = 1 minDroos 0-secono activitiesActivityRecordedonly_recorded = 1Recorded activities onlvOrganiserGroupInUser's own groupRestricts to user's groupFrontend hits /api/v1/page/on-demand?topic id(]=...&sequence number=4 → sequence number=4 → isFirstRequest = false → no implicit defaults →returns 15 activities.AskJiminnyReportActivityService (before the fix) built params from the saved search filters but never included sequence number → defaulted to 0 → isFirstRequest() = true → implicit defaults applied → 0 activities returned because the topic filter + recorded-onlv + duration>1 together matchednothing.Why sequence_number=1 is the right fixThe service is doing a deliberate, one-shot search - not a paginated session. It should never apply first-request defaults, because:1. The saved search already encodes the user's intent (those filters were chosen explicitly)2. Date filters are already intentionally stripped (that's existing logic in DATE_FILTER_KEYS )3. Adding implicit min_duration, only_recorded, and group scope on top would contradict what the saved search representsSetting sequence number=1 is the minimal, correct signal: "this is not a fresh session open, don't apply page-load defaults". The criteria is otherwise builtidentically to how the controller builds it - same Criteria::createFromRequest, same get0nDemandPageFilterSet, same onDemandSearchIds0nly - so theresults will now match.Ö ul ...Ask anything (2*L)+ <> CodeClaude Sonnet 4.6winasun leamsuir-o( 4 spaces...
|
NULL
|
|
11212
|
223
|
5
|
2026-04-14T09:19:56.647433+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158396647_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormProject vFileEditViewNavigateCodeLaravelRe PhpStormProject vFileEditViewNavigateCodeLaravelRefactorToolsWindowHelpFV faVsco.js v#11894 on JY-18909-automated-reports-ask-jiminny k ~© ReportController.phpJiminnyDeouecommana.ongProphetAiAutomatedReportsRepository.phpAutomatedReportsService.phpv D Reports© AutomatedReportsCl© UserPilotActivityListener.php© ActivityLogged.php© AutomatedReportsCommand.php X| AutomatedReportsSendCommand.phpCreateHeldActivityEvent.php• TrackProviderInstalledEvent.php© AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.php© AutomatedReportsRe© AutomatedReportResult.phpc) Automatedkeport.one© AutomatedReportsSt© CreateMockAskJimirJuse Jiminny\Models\Team;© DeleteReportCommause Jiminny\Repositories\AutomatedReportsRepository;© GenerateMarketingRuse Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;© Team.phpuse Psr\Log\LoggerInterface;© Usage.phpD Slack19 Dclass Aurolareckeoorsconlianoiextends Command_leamsD TracksO Transcription* Log prefix for all log messagesO Twilio*/D Usersprivate const string LOG_PREFIX = '[automated-reports]';VocabularyDZoom© CoachingFeedbacksUpr* The name and signature of the console command.© Command.phpo Cearevaroaseusers.o* @var stringc Daraoase oecountoi*/© DeleteOldAiCrmNotesC:31 Ctprotected Ssignature = 'automated-reports© DeleteS3LeftoversComiDevPostmanCommand.|/**© DiarizeViaAiParticipantk© EncryptTokensComman© EngagementStatsRegen© FeatureFlagsHelper.php* Ovar string© FixCrossTenantissues.p© FlushRolesPermissionsC39 G© GeneratelnternalWebhoUse --report-id to manually trigger a specific report by ID or UUID.'il• GroupSetDefaultLangua© HelperTruncateCoachin© HubspotJournalPollingCpublic function __construct(© HubspotWebhookServic© ImportRecording.php@ Imnortl|sercFromCcvEillprivate readonly BusDispatcher $dispatcher,private readonly AutomatedReportsRepository $reportRepository© IterateUsersCommand.gparent::__constructcJiminnvcacheclearcom(e) lminnv Deouacommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoaching* Execute the console command.© ManageScimForTeam.p© MarkBranchForEnvironn* Oreturn int© MuteOrganizerChannel.© PhpApm.phppublic function handle(): int© PropagateCoachingFeer© PurgeConferences.php$this->logger->info(self::LOG_PREFIX'Started');(©) PurgeSoftDeletedOppol© PurgeSyncBatchesCom© RecalculateDealRisksCaC) RemoveDeleteMarkersd© RemoveExpiredNudgest$now = Carbon: :now();$isMonday = $now->isMonday();$isFirstDay0fMonth = $now->day === 1;$currentMonth = $now->month;© RemoveUnusedParticip:© ResetElasticSearch.php© RestoreActivityCrmProvstrict: true);© RestoreActivityTypeCorTests passed: 1 (11 minutes ago)© AddLayoutEntities.php© Team.phpCreateActivityLoggedEvent.php© RequestGenerateReportJob.php$this->logger->info(self::LOG_PREFIX' Checking conditions', I• Suonort Dailv • in 2h 41 mA1EAsk JiminnvRenortActivitvServiceT. Defaults100% |45]Tue 14 Apr 12:19:56= custom.logÁ console [STAGING]E laravel.logA SF ljiminny@localhost]A HS_local [jiminny@localhost]Al console [PROD]A console [EU]© AskJiminnyReportActivityService.php© ActivitySearch.php© OnDemandV2Controller.php© HistoryService.php© FllterDefinitionCollection.phpC) Criteria.php© AskJiminnyReportActivityServiceTest.php X© RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityServiceTest extends TestCase42 X3 лvievale Loucer tncer тасeхмockud cel sroueer9usages29 @* >71 %>100 % >117118 ₽ >156157 % >1184185 ₽>205206 ₽ >224225 %226227228230ZS1204233234235236237242243244245246247248249250251252 % >274275private AskJiminnyReportActivityService $service;protected function setUp(): voidf...}11 usagesprivate function makeFilter(string $key, ?string $valve): SearchFilter&Mock0bjectf...}8 usagesprivate function makeUser(): User&Mock0bjectf…o usaeesprivate function makeSavedSearch(array $filters): Search&Mock0bject{……}public function testGetActivityIdsForSavedSearchReturnsIds(): voidf…;public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): voidk..}public function testGetActivityIdsFiltersOutDateFilters(): voidf..}public function testGetActivityIdsFilters0utClosingPeriodDateFilters(): voidf...}public function testGetActivityIdsHandLesArrayFilters(): void{...}public function testGetActivityIdsHandlesScalarFilters(): voidf..public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(): void$user = $this->makeUser():ssavedsearch = pchis->makesavedsearcncl..h$filterSet = $this->createMock( originalClassName: FilterDefinitionCollection::class);$this->activitySearch->method ( constraint: 'getArrayFilterKeys')->willReturn([]);$capturedCriteria = null;$this->activitySearch->expects($this->once())->method( constraint: 'getOnDemandPageFilterSet')->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {...});puhis->elastickepos1tory->mechodl constraint: 'onbemandsearchlasunly)->wLtrecurnclJ:$this->logger->method( constraint: 'info');$this->service->getActivityIdsForSavedSearch($savedSearch, $user);$this->assertNotNull($capturedCriteria);$this->assertFalse($capturedCriteria->isFirstRequest());public function testGetActivityIdsLogsWithCorrectContext(): void{...}Winasun leams40:79uir-of 4 spaces...
|
NULL
|
-6681906253552935930
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormProject vFileEditViewNavigateCodeLaravelRe PhpStormProject vFileEditViewNavigateCodeLaravelRefactorToolsWindowHelpFV faVsco.js v#11894 on JY-18909-automated-reports-ask-jiminny k ~© ReportController.phpJiminnyDeouecommana.ongProphetAiAutomatedReportsRepository.phpAutomatedReportsService.phpv D Reports© AutomatedReportsCl© UserPilotActivityListener.php© ActivityLogged.php© AutomatedReportsCommand.php X| AutomatedReportsSendCommand.phpCreateHeldActivityEvent.php• TrackProviderInstalledEvent.php© AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.php© AutomatedReportsRe© AutomatedReportResult.phpc) Automatedkeport.one© AutomatedReportsSt© CreateMockAskJimirJuse Jiminny\Models\Team;© DeleteReportCommause Jiminny\Repositories\AutomatedReportsRepository;© GenerateMarketingRuse Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;© Team.phpuse Psr\Log\LoggerInterface;© Usage.phpD Slack19 Dclass Aurolareckeoorsconlianoiextends Command_leamsD TracksO Transcription* Log prefix for all log messagesO Twilio*/D Usersprivate const string LOG_PREFIX = '[automated-reports]';VocabularyDZoom© CoachingFeedbacksUpr* The name and signature of the console command.© Command.phpo Cearevaroaseusers.o* @var stringc Daraoase oecountoi*/© DeleteOldAiCrmNotesC:31 Ctprotected Ssignature = 'automated-reports© DeleteS3LeftoversComiDevPostmanCommand.|/**© DiarizeViaAiParticipantk© EncryptTokensComman© EngagementStatsRegen© FeatureFlagsHelper.php* Ovar string© FixCrossTenantissues.p© FlushRolesPermissionsC39 G© GeneratelnternalWebhoUse --report-id to manually trigger a specific report by ID or UUID.'il• GroupSetDefaultLangua© HelperTruncateCoachin© HubspotJournalPollingCpublic function __construct(© HubspotWebhookServic© ImportRecording.php@ Imnortl|sercFromCcvEillprivate readonly BusDispatcher $dispatcher,private readonly AutomatedReportsRepository $reportRepository© IterateUsersCommand.gparent::__constructcJiminnvcacheclearcom(e) lminnv Deouacommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoaching* Execute the console command.© ManageScimForTeam.p© MarkBranchForEnvironn* Oreturn int© MuteOrganizerChannel.© PhpApm.phppublic function handle(): int© PropagateCoachingFeer© PurgeConferences.php$this->logger->info(self::LOG_PREFIX'Started');(©) PurgeSoftDeletedOppol© PurgeSyncBatchesCom© RecalculateDealRisksCaC) RemoveDeleteMarkersd© RemoveExpiredNudgest$now = Carbon: :now();$isMonday = $now->isMonday();$isFirstDay0fMonth = $now->day === 1;$currentMonth = $now->month;© RemoveUnusedParticip:© ResetElasticSearch.php© RestoreActivityCrmProvstrict: true);© RestoreActivityTypeCorTests passed: 1 (11 minutes ago)© AddLayoutEntities.php© Team.phpCreateActivityLoggedEvent.php© RequestGenerateReportJob.php$this->logger->info(self::LOG_PREFIX' Checking conditions', I• Suonort Dailv • in 2h 41 mA1EAsk JiminnvRenortActivitvServiceT. Defaults100% |45]Tue 14 Apr 12:19:56= custom.logÁ console [STAGING]E laravel.logA SF ljiminny@localhost]A HS_local [jiminny@localhost]Al console [PROD]A console [EU]© AskJiminnyReportActivityService.php© ActivitySearch.php© OnDemandV2Controller.php© HistoryService.php© FllterDefinitionCollection.phpC) Criteria.php© AskJiminnyReportActivityServiceTest.php X© RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityServiceTest extends TestCase42 X3 лvievale Loucer tncer тасeхмockud cel sroueer9usages29 @* >71 %>100 % >117118 ₽ >156157 % >1184185 ₽>205206 ₽ >224225 %226227228230ZS1204233234235236237242243244245246247248249250251252 % >274275private AskJiminnyReportActivityService $service;protected function setUp(): voidf...}11 usagesprivate function makeFilter(string $key, ?string $valve): SearchFilter&Mock0bjectf...}8 usagesprivate function makeUser(): User&Mock0bjectf…o usaeesprivate function makeSavedSearch(array $filters): Search&Mock0bject{……}public function testGetActivityIdsForSavedSearchReturnsIds(): voidf…;public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): voidk..}public function testGetActivityIdsFiltersOutDateFilters(): voidf..}public function testGetActivityIdsFilters0utClosingPeriodDateFilters(): voidf...}public function testGetActivityIdsHandLesArrayFilters(): void{...}public function testGetActivityIdsHandlesScalarFilters(): voidf..public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(): void$user = $this->makeUser():ssavedsearch = pchis->makesavedsearcncl..h$filterSet = $this->createMock( originalClassName: FilterDefinitionCollection::class);$this->activitySearch->method ( constraint: 'getArrayFilterKeys')->willReturn([]);$capturedCriteria = null;$this->activitySearch->expects($this->once())->method( constraint: 'getOnDemandPageFilterSet')->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {...});puhis->elastickepos1tory->mechodl constraint: 'onbemandsearchlasunly)->wLtrecurnclJ:$this->logger->method( constraint: 'info');$this->service->getActivityIdsForSavedSearch($savedSearch, $user);$this->assertNotNull($capturedCriteria);$this->assertFalse($capturedCriteria->isFirstRequest());public function testGetActivityIdsLogsWithCorrectContext(): void{...}Winasun leams40:79uir-of 4 spaces...
|
11210
|
|
11215
|
223
|
6
|
2026-04-14T09:20:00.967895+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158400967_m2.jpg...
|
iTerm2
|
DEV (-zsh)
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Last login: Sat Apr 11 12:38:35 on ttys006
Poetry Last login: Sat Apr 11 12:38:35 on ttys006
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 (JY-18909-automated-reports-ask-jiminny) $
DOCKER
Close Tab
DEV (-zsh)
Close Tab
APP (-zsh)
Close Tab
ec2-user@ip-10-30-93-249:~ (nc)
Close Tab
-zsh
Close Tab
-zsh
Close Tab
-zsh
Close Tab
✳ Unable to access screenpipe activity data (claude)
Close Tab
⌥⌘1
DEV (-zsh)...
|
[{"role":"AXTextArea","text [{"role":"AXTextArea","text":"Last login: Sat Apr 11 12:38:35 on ttys006\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 (JY-18909-automated-reports-ask-jiminny) $","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.5566406,"height":-0.05486107},"value":"Last login: Sat Apr 11 12:38:35 on ttys006\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 (JY-18909-automated-reports-ask-jiminny) $","is_focused":true},{"role":"AXRadioButton","text":"DOCKER","depth":2,"bounds":{"left":0.23320313,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.23554687,"top":1.0,"width":0.00625,"height":-0.039583325},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"DEV (-zsh)","depth":2,"bounds":{"left":0.30234376,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.3046875,"top":1.0,"width":0.00625,"height":-0.039583325},"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.37148437,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.3738281,"top":1.0,"width":0.00625,"height":-0.039583325},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"ec2-user@ip-10-30-93-249:~ (nc)","depth":2,"bounds":{"left":0.440625,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.44296876,"top":1.0,"width":0.00625,"height":-0.039583325},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"-zsh","depth":2,"bounds":{"left":0.5097656,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.5121094,"top":1.0,"width":0.00625,"height":-0.039583325},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"-zsh","depth":2,"bounds":{"left":0.57890624,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.58125,"top":1.0,"width":0.00625,"height":-0.039583325},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"-zsh","depth":2,"bounds":{"left":0.64804685,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.6503906,"top":1.0,"width":0.00625,"height":-0.039583325},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"✳ Unable to access screenpipe activity data (claude)","depth":2,"bounds":{"left":0.7171875,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.71953124,"top":1.0,"width":0.00625,"height":-0.039583325},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"⌥⌘1","depth":1,"bounds":{"left":0.7703125,"top":1.0,"width":0.021875,"height":-0.02013886},"automation_id":"_NS:8","role_description":"text"},{"role":"AXStaticText","text":"DEV (-zsh)","depth":1,"bounds":{"left":0.5,"top":1.0,"width":0.029296875,"height":-0.020833373},"role_description":"text"}]...
|
1132831535450885273
|
5729594858220514453
|
click
|
accessibility
|
NULL
|
Last login: Sat Apr 11 12:38:35 on ttys006
Poetry Last login: Sat Apr 11 12:38:35 on ttys006
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 (JY-18909-automated-reports-ask-jiminny) $
DOCKER
Close Tab
DEV (-zsh)
Close Tab
APP (-zsh)
Close Tab
ec2-user@ip-10-30-93-249:~ (nc)
Close Tab
-zsh
Close Tab
-zsh
Close Tab
-zsh
Close Tab
✳ Unable to access screenpipe activity data (claude)
Close Tab
⌥⌘1
DEV (-zsh)...
|
NULL
|
|
11217
|
223
|
7
|
2026-04-14T09:20:01.681255+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158401681_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
({)PhpStormViewNavigateLaravelRefactonWindowFV faV ({)PhpStormViewNavigateLaravelRefactonWindowFV faVsco.js vProject vProphetAiv D Reports© AutomatedReportsCl© AutomatedReportsRe© AutomatedReportsSt© CreateMockAskJimir© DeleteReportComma© GenerateMarketingR© Team.php© Usage.phpD Slack_leamsD TracksO TranscriptionO TwilioD UsersVocabularyDZoom© CoachingFeedbacksUpr© Command.phpo Cearevaroaseusers.oc Daraoase oecountoi© DeleteOldAiCrmNotesC:© DeleteS3LeftoversComiDevPostmanCommand.|© DiarizeViaAiParticipantk© EncryptTokensComman© EngagementStatsRegen© FeatureFlagsHelper.php© FixCrossTenantissues.p© FlushRolesPermissionsC© GeneratelnternalWebho• GroupSetDefaultLangua© HelperTruncateCoachin© HubspotJournalPollingC© HubspotWebhookServic© ImportRecording.php@ Imnortl|sercFromCcvEill© IterateUsersCommand.gcJiminnvcacheclearcom(e) lminnv Deouacommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoaching© ManageScimForTeam.p© MarkBranchForEnvironn© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php(©) PurgeSoftDeletedOppol© PurgeSyncBatchesCom© RecalculateDealRisksCaC) RemoveDeleteMarkersd© RemoveExpiredNudgest© RemoveUnusedParticip:© ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© ReportController.phpJiminnyDeouecommana.ongAulomaleakeporskeposilory.oneAutomatedReportsService.php© UserPilotActivityListener.php© AutomatedReportResult.php© ActivityLogged.phpc) Automatedkeport.one© AutomatedReportsCommand.php X| AutomatedReportsSendCommand.phpCreateHeldActivityEvent.php• TrackProviderInstalledEvent.php© AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.php© AddLayoutEntities.php© Team.phpCreateActivityLoggedEvent.php© RequestGenerateReportJob.phpJuse Jiminny\Models\Team;use Jiminny\Repositories\AutomatedReportsRepository;use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;use Psr\Log\LoggerInterface;19 Dclass Aurolareckeoorsconlianoiextends Command31 Ct39 G51 =* Log prefix for all log messages*/private const string LOG_PREFIX = '[automated-reports]';* The name and signature of the console command.* @var string*/protected Ssignature = 'automated-reports/**Use --report-id to manually trigger a specific report by ID or UUID.':public function __construct(private readonly BusDispatcher $dispatcher,private readonly AutomatedReportsRepository $reportRepositoryparent::__construct* Execute the console command.* Oreturn intpublic function handle(): int$this->logger->info(self::LOG_PREFIX'Started');$now = Carbon: :now();$isMonday = $now->isMonday();$isFirstDay0fMonth = $now->day === 1;$currentMonth = $now->month;Suooort Dailv . in 2h 40m100% 4= custom.logÁ console [STAGING]E laravel.logA SF ljiminny@localhost]A HS_local [jiminny@localhost]#concole DPOlbI#concole f.unl© AskJiminnyReportActivityService.php© ActivitySearch.php© OnDemandV2Controller.php© HistoryService.phpFllterbetinitioncolllection.omv© Criteria.php© AskJiminnyReportActivityServiceTest.php x|© RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityServiceTest extends TestCaseA2 V3 ^vievale Loucer tncer тасeхмockud cel sroueer9usages29 @* >71% >100 % >117118 ₽ >156157 % >1184185 ₽>205206 >224225 %226227228230ZS1204233234235236237242243244245246247248249250251252 % >274275private AskJiminnyReportActivityService $service;protected function setUp(): voidf.}11 usagesprivate function makeFilter(string $key, ?string $value): SearchFilter&Mock0bject{...}8 usagesprivate function makeUser(): User&Mock0bjectf…o usaeesprivate function makeSavedSearch(array $filters): Search&Mock0bjectf...}public function testGetActivityIdsForSavedSearchReturnsIds(): voidf…;public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): voidf...}public function testGetActivityIdsFiltersOutDateFilters(): voidf..}public function testGetActivityIdsFilters0utClosingPeriodDateFilters(): voidf...}public function testGetActivityIdsHandLesArrayFilters(): void{...}public function testGetActivityIdsHandLesScalarFilters(): voidf…public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(): void$user = $this->makeUser();$savedSearch = $this->makeSavedSearch([1);$filterSet = $this->createMock( originalClassName: FilterDefinitionCollection::class);$this->activitySearch->method ( constraint: 'getArrayFilterKeys')->willReturn([]);$capturedCriteria = null;$this->activitySearch->expects($this->once())->method( constraint: 'getOnDemandPageFilterSet')->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {...});puhis->elastickepos1tory->mechodl constraint: 'onbemandsearchlasunly)->wLtrecurnclJ:$this->logger->method( constraint: 'info');$this->service->getActivityIdsForSavedSearch($savedSearch, $user);$this->assertNotNull($capturedCriteria);$this->assertFalse($capturedCriteria->isFirstRequest());public function testGetActivityIdsLogsWithCorrectContext(): void{...}gs 40:79uir-of 4 spaces...
|
NULL
|
-7511186711661135277
|
NULL
|
click
|
ocr
|
NULL
|
({)PhpStormViewNavigateLaravelRefactonWindowFV faV ({)PhpStormViewNavigateLaravelRefactonWindowFV faVsco.js vProject vProphetAiv D Reports© AutomatedReportsCl© AutomatedReportsRe© AutomatedReportsSt© CreateMockAskJimir© DeleteReportComma© GenerateMarketingR© Team.php© Usage.phpD Slack_leamsD TracksO TranscriptionO TwilioD UsersVocabularyDZoom© CoachingFeedbacksUpr© Command.phpo Cearevaroaseusers.oc Daraoase oecountoi© DeleteOldAiCrmNotesC:© DeleteS3LeftoversComiDevPostmanCommand.|© DiarizeViaAiParticipantk© EncryptTokensComman© EngagementStatsRegen© FeatureFlagsHelper.php© FixCrossTenantissues.p© FlushRolesPermissionsC© GeneratelnternalWebho• GroupSetDefaultLangua© HelperTruncateCoachin© HubspotJournalPollingC© HubspotWebhookServic© ImportRecording.php@ Imnortl|sercFromCcvEill© IterateUsersCommand.gcJiminnvcacheclearcom(e) lminnv Deouacommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoaching© ManageScimForTeam.p© MarkBranchForEnvironn© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php(©) PurgeSoftDeletedOppol© PurgeSyncBatchesCom© RecalculateDealRisksCaC) RemoveDeleteMarkersd© RemoveExpiredNudgest© RemoveUnusedParticip:© ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© ReportController.phpJiminnyDeouecommana.ongAulomaleakeporskeposilory.oneAutomatedReportsService.php© UserPilotActivityListener.php© AutomatedReportResult.php© ActivityLogged.phpc) Automatedkeport.one© AutomatedReportsCommand.php X| AutomatedReportsSendCommand.phpCreateHeldActivityEvent.php• TrackProviderInstalledEvent.php© AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.php© AddLayoutEntities.php© Team.phpCreateActivityLoggedEvent.php© RequestGenerateReportJob.phpJuse Jiminny\Models\Team;use Jiminny\Repositories\AutomatedReportsRepository;use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;use Psr\Log\LoggerInterface;19 Dclass Aurolareckeoorsconlianoiextends Command31 Ct39 G51 =* Log prefix for all log messages*/private const string LOG_PREFIX = '[automated-reports]';* The name and signature of the console command.* @var string*/protected Ssignature = 'automated-reports/**Use --report-id to manually trigger a specific report by ID or UUID.':public function __construct(private readonly BusDispatcher $dispatcher,private readonly AutomatedReportsRepository $reportRepositoryparent::__construct* Execute the console command.* Oreturn intpublic function handle(): int$this->logger->info(self::LOG_PREFIX'Started');$now = Carbon: :now();$isMonday = $now->isMonday();$isFirstDay0fMonth = $now->day === 1;$currentMonth = $now->month;Suooort Dailv . in 2h 40m100% 4= custom.logÁ console [STAGING]E laravel.logA SF ljiminny@localhost]A HS_local [jiminny@localhost]#concole DPOlbI#concole f.unl© AskJiminnyReportActivityService.php© ActivitySearch.php© OnDemandV2Controller.php© HistoryService.phpFllterbetinitioncolllection.omv© Criteria.php© AskJiminnyReportActivityServiceTest.php x|© RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityServiceTest extends TestCaseA2 V3 ^vievale Loucer tncer тасeхмockud cel sroueer9usages29 @* >71% >100 % >117118 ₽ >156157 % >1184185 ₽>205206 >224225 %226227228230ZS1204233234235236237242243244245246247248249250251252 % >274275private AskJiminnyReportActivityService $service;protected function setUp(): voidf.}11 usagesprivate function makeFilter(string $key, ?string $value): SearchFilter&Mock0bject{...}8 usagesprivate function makeUser(): User&Mock0bjectf…o usaeesprivate function makeSavedSearch(array $filters): Search&Mock0bjectf...}public function testGetActivityIdsForSavedSearchReturnsIds(): voidf…;public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): voidf...}public function testGetActivityIdsFiltersOutDateFilters(): voidf..}public function testGetActivityIdsFilters0utClosingPeriodDateFilters(): voidf...}public function testGetActivityIdsHandLesArrayFilters(): void{...}public function testGetActivityIdsHandLesScalarFilters(): voidf…public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(): void$user = $this->makeUser();$savedSearch = $this->makeSavedSearch([1);$filterSet = $this->createMock( originalClassName: FilterDefinitionCollection::class);$this->activitySearch->method ( constraint: 'getArrayFilterKeys')->willReturn([]);$capturedCriteria = null;$this->activitySearch->expects($this->once())->method( constraint: 'getOnDemandPageFilterSet')->willReturnCallback(function (Criteria $criteria) use ($filterSet, &$capturedCriteria) {...});puhis->elastickepos1tory->mechodl constraint: 'onbemandsearchlasunly)->wLtrecurnclJ:$this->logger->method( constraint: 'info');$this->service->getActivityIdsForSavedSearch($savedSearch, $user);$this->assertNotNull($capturedCriteria);$this->assertFalse($capturedCriteria->isFirstRequest());public function testGetActivityIdsLogsWithCorrectContext(): void{...}gs 40:79uir-of 4 spaces...
|
11215
|
|
11220
|
223
|
8
|
2026-04-14T09:20:21.424926+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158421424_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormViewNavigateLaravelRefactonWindowFV faVsco PhpStormViewNavigateLaravelRefactonWindowFV faVsco.js vProject vProphetAiv D Reports© AutomatedReportsCl© AutomatedReportsRe© AutomatedReportsSt© CreateMockAskJimir© DeleteReportComma© GenerateMarketingR© Team.php© Usage.phpD Slack_leamsD TracksO TranscriptionO TwilioD UsersVocabularyDZoom© CoachingFeedbacksUpr© Command.phpo Cearevaroaseusers.oc Daraoase oecountoi© DeleteOldAiCrmNotesC:© DeleteS3LeftoversComiDevPostmanCommand.|© DiarizeViaAiParticipantk© EncryptTokensComman© EngagementStatsRegen© FeatureFlagsHelper.php© FixCrossTenantlssues.p© FlushRolesPermissionsC© GeneratelnternalWebho• GroupSetDefaultLangua© HelperTruncateCoachin© HubspotJournalPollingC© HubspotWebhookServic© ImportRecording.php@ Imnortl|sercFromCcvEill© IterateUsersCommand.gcJiminnvcacheclearcom(e) lminnv Deouacommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoaching© ManageScimForTeam.p© MarkBranchForEnvironn© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php(©) PurgeSoftDeletedOppol© PurgeSyncBatchesCom© RecalculateDealRisksCaC) RemoveDeleteMarkersd© RemoveExpiredNudgest© RemoveUnusedParticip:© ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© ReportController.phpJiminnyDeouecommana.ongAulomaleakeporskeposilory.oneAutomatedReportsService.php© UserPilotActivityListener.php© AutomatedReportResult.php© ActivityLogged.phpc) Automatedkeport.one© AutomatedReportsCommand.php X| AutomatedReportsSendCommand.phpCreateHeldActivityEvent.php• TrackProviderInstalledEvent.php© AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.php© AddLayoutEntities.php© Team.phpCreateActivityLoggedEvent.php© RequestGenerateReportJob.phpJuse Jiminny\Models\Team;use Jiminny\Repositories\AutomatedReportsRepository;use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;use Psr\Log\LoggerInterface;19 Dclass Aurolareckeoorsconlianoiextends Command31 Ct373839 G5862* Log prefix for all log messages*/private const string LOG_PREFIX = '[automated-reports]';* The name and signature of the console command.* @var string*/protected Ssignature = 'automated-reports/**Use --report-id to manually trigger a specific report by ID or UUID.';public function __construct(private readonly BusDispatcher $dispatcher,private readonly AutomatedReportsRepository $reportRepositoryparent: :__construct();* Execute the console command.* Oreturn intpublic function handle(): int$this->logger->info(self::L0G_PREFIStarted');$now = Carbon: :now();$isMonday = $now->¡sMonday();SisFirstDay0fMonth = Snow->day === 1;$currentMonth = $now->month;$this->logger->info(self::LOG_PREFIX' Checking conditions', ISuooort Dailv . in 2h 40m= custom.logÁ console [STAGING]E laravel.logA SF ljiminny@localhost]A HS_local [jiminny@localhost]#concole DPOlbIE console (EU]© AskJiminyReporfActivitySerice,php© ActivitySearch.php© OnDemandV2Controller.php© HistoryService.phpFllterbetinitioncolllection.omv© Criteria.php x© AskJiminnyReportActivityServiceTest.php x© RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityServiceTest extends TestCaseA2 V3 ^i evale Loucer ncel таceoмockodcel srouee9usages29 @* >71% >100 % >117118 ₽ >156157 % >1184185 ₽>205206 ₽ >224225 %226227228230ZS1204233234235236237242243244245246247248249250251252 % >274275private AskJiminnyReportActivityService $service;protected function setUp(): voidf.}11 usagesprivate function makeFilter(string $key, ?string $value): SearchFilter&Mock0bject{...}8 usagesprivate function makeUser(): User&Mock0bjectf…o usaeesprivate function makeSavedSearch(array $filters): Search&Mock0bjectf...}public function testGetActivityIdsForSavedSearchReturnsIds(): voidf…;public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): voidf...}public function testGetActivityIdsFiltersOutDateFilters(): voidf..}public function testGetActivityIdsFilters0utClosingPeriodDateFilters(): voidf...}public function testGetActivityIdsHandLesArrayFilters(): void{...}public function testGetActivityIdsHandLesScalarFilters(): voidf…public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(): void$user = $this->makeUser();$savedSearch = $this->makeSavedSearch([1);$filterSet = $this->createMock( originalClassName: FilterDefinitionCollection::class);$this->activitySearch->method ( constraint: 'getArrayFilterKeys')->willReturn([]);$capturedCriteria = null;$this->activitySearch->expects($this->once())->method( constraint: 'getOnDemandPageFilterSet')->W1LLReturnCallback(function (Criteria scriteria) use (sfilterset, x capturedcriteria) 1...npuhis->elasticrepos1tory->mechod constraint: 'onuemandsearchlasunly )->wiLLreturncLJh$this->logger->method( constraint: 'info');$this->service->getActivityIdsForSavedSearch($savedSearch, $user);$this->assertNotNull($capturedCriteria);$this->assertFalse($capturedCriteria->isFirstRequest());public function testGetActivityIdsLogsWithCorrectContext(): void{...}gS 50:004 spaces...
|
NULL
|
3023928349652878433
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormViewNavigateLaravelRefactonWindowFV faVsco PhpStormViewNavigateLaravelRefactonWindowFV faVsco.js vProject vProphetAiv D Reports© AutomatedReportsCl© AutomatedReportsRe© AutomatedReportsSt© CreateMockAskJimir© DeleteReportComma© GenerateMarketingR© Team.php© Usage.phpD Slack_leamsD TracksO TranscriptionO TwilioD UsersVocabularyDZoom© CoachingFeedbacksUpr© Command.phpo Cearevaroaseusers.oc Daraoase oecountoi© DeleteOldAiCrmNotesC:© DeleteS3LeftoversComiDevPostmanCommand.|© DiarizeViaAiParticipantk© EncryptTokensComman© EngagementStatsRegen© FeatureFlagsHelper.php© FixCrossTenantlssues.p© FlushRolesPermissionsC© GeneratelnternalWebho• GroupSetDefaultLangua© HelperTruncateCoachin© HubspotJournalPollingC© HubspotWebhookServic© ImportRecording.php@ Imnortl|sercFromCcvEill© IterateUsersCommand.gcJiminnvcacheclearcom(e) lminnv Deouacommanc© JiminnySetEncryptedTo© JiminnyTokenInfoComn© MakeSlackLiveCoaching© ManageScimForTeam.p© MarkBranchForEnvironn© MuteOrganizerChannel.© PhpApm.php© PropagateCoachingFeer© PurgeConferences.php(©) PurgeSoftDeletedOppol© PurgeSyncBatchesCom© RecalculateDealRisksCaC) RemoveDeleteMarkersd© RemoveExpiredNudgest© RemoveUnusedParticip:© ResetElasticSearch.php© RestoreActivityCrmProv© RestoreActivityTypeCor© ReportController.phpJiminnyDeouecommana.ongAulomaleakeporskeposilory.oneAutomatedReportsService.php© UserPilotActivityListener.php© AutomatedReportResult.php© ActivityLogged.phpc) Automatedkeport.one© AutomatedReportsCommand.php X| AutomatedReportsSendCommand.phpCreateHeldActivityEvent.php• TrackProviderInstalledEvent.php© AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.php© AddLayoutEntities.php© Team.phpCreateActivityLoggedEvent.php© RequestGenerateReportJob.phpJuse Jiminny\Models\Team;use Jiminny\Repositories\AutomatedReportsRepository;use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;use Psr\Log\LoggerInterface;19 Dclass Aurolareckeoorsconlianoiextends Command31 Ct373839 G5862* Log prefix for all log messages*/private const string LOG_PREFIX = '[automated-reports]';* The name and signature of the console command.* @var string*/protected Ssignature = 'automated-reports/**Use --report-id to manually trigger a specific report by ID or UUID.';public function __construct(private readonly BusDispatcher $dispatcher,private readonly AutomatedReportsRepository $reportRepositoryparent: :__construct();* Execute the console command.* Oreturn intpublic function handle(): int$this->logger->info(self::L0G_PREFIStarted');$now = Carbon: :now();$isMonday = $now->¡sMonday();SisFirstDay0fMonth = Snow->day === 1;$currentMonth = $now->month;$this->logger->info(self::LOG_PREFIX' Checking conditions', ISuooort Dailv . in 2h 40m= custom.logÁ console [STAGING]E laravel.logA SF ljiminny@localhost]A HS_local [jiminny@localhost]#concole DPOlbIE console (EU]© AskJiminyReporfActivitySerice,php© ActivitySearch.php© OnDemandV2Controller.php© HistoryService.phpFllterbetinitioncolllection.omv© Criteria.php x© AskJiminnyReportActivityServiceTest.php x© RequestGenerateAskJiminnyReportJobTest.phpclass AskJiminnyReportActivityServiceTest extends TestCaseA2 V3 ^i evale Loucer ncel таceoмockodcel srouee9usages29 @* >71% >100 % >117118 ₽ >156157 % >1184185 ₽>205206 ₽ >224225 %226227228230ZS1204233234235236237242243244245246247248249250251252 % >274275private AskJiminnyReportActivityService $service;protected function setUp(): voidf.}11 usagesprivate function makeFilter(string $key, ?string $value): SearchFilter&Mock0bject{...}8 usagesprivate function makeUser(): User&Mock0bjectf…o usaeesprivate function makeSavedSearch(array $filters): Search&Mock0bjectf...}public function testGetActivityIdsForSavedSearchReturnsIds(): voidf…;public function testGetActivityIdsForSavedSearchReturnsEmptyWhenNoResults(): voidf...}public function testGetActivityIdsFiltersOutDateFilters(): voidf..}public function testGetActivityIdsFilters0utClosingPeriodDateFilters(): voidf...}public function testGetActivityIdsHandLesArrayFilters(): void{...}public function testGetActivityIdsHandLesScalarFilters(): voidf…public function testGetActivityIdsPassesNonZeroSequenceNumberToDisableFirstRequestDefaults(): void$user = $this->makeUser();$savedSearch = $this->makeSavedSearch([1);$filterSet = $this->createMock( originalClassName: FilterDefinitionCollection::class);$this->activitySearch->method ( constraint: 'getArrayFilterKeys')->willReturn([]);$capturedCriteria = null;$this->activitySearch->expects($this->once())->method( constraint: 'getOnDemandPageFilterSet')->W1LLReturnCallback(function (Criteria scriteria) use (sfilterset, x capturedcriteria) 1...npuhis->elasticrepos1tory->mechod constraint: 'onuemandsearchlasunly )->wiLLreturncLJh$this->logger->method( constraint: 'info');$this->service->getActivityIdsForSavedSearch($savedSearch, $user);$this->assertNotNull($capturedCriteria);$this->assertFalse($capturedCriteria->isFirstRequest());public function testGetActivityIdsLogsWithCorrectContext(): void{...}gS 50:004 spaces...
|
NULL
|
|
11222
|
223
|
9
|
2026-04-14T09:20:24.188711+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158424188_m2.jpg...
|
PhpStorm
|
faVsco.js – SF [jiminny@localhost]
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","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.7589844,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceT…Defaults","depth":6,"bounds":{"left":0.7769531,"top":0.017361112,"width":0.12382813,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
7418164613004400520
|
-4026076994304753311
|
visual_change
|
hybrid
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
PhpStormFileEditFV faVsco.s vProject vw testuase.uuy› _ vendorê .editorconfig= .env= .env.circleci=.env.circleci-nightly=.env.local=.env.migrate=.env.nikilocalE env.othenE env.productionE.env.production-eu=.env.aaE .env.qai=.env.rootE.env.staging= .gitattributes•.gitignore=.php-cs-fixer.cachephp.php-cs-fixer.dist.phpphp.phpstorm.meta.php=.phpunit.result.cacheE orettierianoreE .windsurfrulespip lue nelper.onephp_ide_helper_models.phpphp artisan0 composer.jsonO composer.lockO dependency-checker.json( dev.jsonEids.txtEinfection.ison.distM+INSALLMOIMJ INTERNAL_WEBHOOK_SETUP.mcEjiminny_storageM+licenses.mdM MakefileO package-lock.jsonEphpstan.neon.dist= phpstan-baseline.neon< phpunit.xmlTaraw_sqLquery.sqlM+ R-ADME,moso sonar-proiect propertiesEtest.py<> Untitled Diagram.xmlIs vetur.config.jsM+ WEBHOOK_FILTERING_IMPLEMEI› ib External LibrariesE° Scratches and Consolesv D Database ConsolesViewNavigateCodeLaravelRefactorToolsWindowHelp#11894 on JY-18909-automated-reports-ask-jiminny k ~© ReportController.phpJiminnyDeouecommana.ong© AutomatedReportsCommand.php x© AutomatedReportsRepository.phpC AutomatedReportsService.phpCreateHeldActivityEvent.php© UserPilotActivityListener.php© ActivityLogged.php© AutomatedReportsCallbackService.php© AutomatedReportResult.phpAutomaleakeportoneJuse Jiminny\ModeLs\Team;use Jiminny\Repositories\AutomatedReportsRepository;use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;use Psr\Log\LoggerInterface;vd jiminny@localhost4 console [jiminny@localhost4 DI liiminnv@localhostlc noocaminnvolocanos4 SF [jiminny@localhost]s cono dev minny clocaine> 4 PRODTests passed: 1 (11 minutes ago)C) AutomatedReportsSendCommand.php© TrackProviderInstalledEvent.phpC RequestGenerateAskJiminnyReportJob.php© AddLayoutEntities.php© Team.phpCreateActivityLoggedEvent.php© RequestGenerateReportJob.php19 Dclass Aurolareckeoorsconlianoiextenos coniano31 G39 C43 Gt45* Log prefix for all log messages*/private const string LOG_PREFIX = '[automated-reports]';* The name and signature of the console command.* @var string*/protected Ssignature = 'automated-reports{--report-id= : Process a specific report by ID or UUID (bypasses frequency scheduling)}':/*** The console command description.* Ovar stringprotected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly).Use --report-id to manually trigger a specific report by ID or UUID.':public function __construct(privace readonty Loggerintertace +logger,private readonly BusDispatcher $dispatcher,private readonly AutomatedReportsRepository $reportRepositoryparent: :__construct();* Execure cne console conmono.* Oreturn int*/public function handle(): int$this->logger->info(self::LOG_PREFIX. ' Started');$now = Carbon: : now();$isMonday = $now->isMonday);$isFirstDay0fMonth = $now->day === 1;scurrencmonch = snow->month;1l check It the current monch is a quarterly monch lvanvary, April, suly, uccober$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 101,strict: true);$this->logger->info(self::LOG_PREFIX . ' Checking conditions', [, 0f Support Daily • in 2h 40 mAL AskJiminnyReportActivityServiceT….Defaults100% C•Tue 14 Apr 12:20:24= custom.logElaravel.logÁ console [STAGING]© FilterDefinitionCollection.phpA SF ljiminny@localhost]C AskJiminnyReportActivityService.php© Criteria.php4 HS_local [jiminny@localhost]© ActivitySearch.php© AskJiminnyReportActivityServiceTest.phpAl console [PROD]A console [EU]cOnbemanavzcontroller.oneC HistoryService.phpRequestGenerateAskJiminnyReportJobTest.phpX:Auto vPlaygroundMa lminnv vv 13813914014114211451441451140147148149150151152153INSERT INTO 'activity_search_filters'C'activity_search_id,filter',"value") VALUES( activity_search_id 1977,filter 'group_id',( activity_search_id 1978,filter 'group_id',( activity_search_id 1979,filter 'group_id',445t26D8-0512-45/e-ayty-/e/sro025Czz),*445T26D8-0512-457e-ayт7-/e/sto025022),'443f26b8-8512-437e-a9f9-7e75f8025c22')select * from crm_configurations where id = 39;select * from teams where id = 1;select * from team_features where team_id = 1;select * from features;SELECT * FROM activity_searches where id = 1982; # 1981SELECT * FROM activity_search_filters WHERE activity_search_id = 1982;155SELECT * FROM automated_reports where id = 68;SELECT * FROM automated_report_results where id = 275;157158159160161162163164116511.661681691701731741751761771781791801811821831841851861871881189LIMIT 10;{"request_id": "edc47759-160a-4f61-82fc-c8cdf5e55464", "status":"completed", "timestamp": "2026-03-31T15:52:05.828229-191s3://dev.jiminny.client-data/5f0f4810-7e77-4086-8f69-93429ae4d70b/panorama-reports/test_req_q_1.MDs3://dev.jiminny.client-data/5f0f4810-7e77-4086-8f69-93429ae4d70b/panorama-reports/test_req_q_1.pdflW Windsurf Teams 191:100UTF-8...
|
11220
|
|
11223
|
223
|
10
|
2026-04-14T09:20:26.595966+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158426595_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditFV faVsco.s vProject vw testuase.u PhpStormFileEditFV faVsco.s vProject vw testuase.uuy› _ vendorê .editorconfig= .env= .env.circleci=.env.circleci-nightly=.env.local=.env.migrate=.env.nikilocalE env.othenE env.productionE.env.production-eu=.env.aaE .env.qai=.env.rootE.env.staging= .gitattributes•.gitignore=.php-cs-fixer.cachephp.php-cs-fixer.dist.phpphp.phpstorm.meta.php=.phpunit.result.cacheE orettierianoreE .windsurfrulespip lue nelper.onephp_ide_helper_models.phpphp artisan0 composer.jsonO composer.lockO dependency-checker.json( dev.jsonEids.txtEinfection.ison.distM+INSALLMOIMJ INTERNAL_WEBHOOK_SETUP.mcEjiminny_storageM+licenses.mdM MakefileO package-lock.jsonEphpstan.neon.dist= phpstan-baseline.neon< phpunit.xmlTaraw_sqLquery.sqlM+ R-ADME,moso sonar-proiect propertiesEtest.py<> Untitled Diagram.xmlIs vetur.config.jsM+ WEBHOOK_FILTERING_IMPLEMEI› ib External LibrariesE° Scratches and Consolesv D Database ConsolesViewNavigateCodeLaravelRefactorToolsWindowHelp#11894 on JY-18909-automated-reports-ask-jiminny k ~© ReportController.phpJiminnyDeouecommana.ong© AutomatedReportsCommand.php x© AutomatedReportsRepository.phpC AutomatedReportsService.phpCreateHeldActivityEvent.php© UserPilotActivityListener.php© ActivityLogged.php© AutomatedReportsCallbackService.php© AutomatedReportResult.phpAutomaleakeportoneJuse Jiminny\ModeLs\Team;use Jiminny\Repositories\AutomatedReportsRepository;use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;use Psr\Log\LoggerInterface;vd jiminny@localhost4 console [jiminny@localhost4 DI liiminnv@localhostlc noocaminnvolocanos4 SF [jiminny@localhost]s cono dev minny clocaine> 4 PRODTests passed: 1 (11 minutes ago)C) AutomatedReportsSendCommand.php• TrackProviderInstalledEvent.phpC RequestGenerateAskJiminnyReportJob.php© AddLayoutEntities.php© Team.phpCreateActivityLoggedEvent.php© RequestGenerateReportJob.php19 Dclass Aurolareckeoor scoliialneextenos coniano31 G39 C43 Gt45* Log prefix for all log messages*/private const string LOG_PREFIX = '[automated-reports]';* The name and signature of the console command.* @var string*/protected Ssignature = 'automated-reports{--report-id= : Process a specific report by ID or UUID (bypasses frequency scheduLing)}':/*** The console command description.* Ovar stringprotected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly).Use --report-id to manually trigger a specific report by ID or UUID.':public function __construct(privace readonty Loggerintertace +logger,private readonly BusDispatcher $dispatcher,private readonly AutomatedReportsRepository $reportRepositoryparent: :__construct();* Execure cne console conmono.* Oreturn int*/public function handle(): int$this->logger->info(self::LOG_PREFIX .' Started');$now = Carbon: : now();$isMonday = $now->isMonday);$isFirstDay0fMonth = $now->day === 1;scurrencmonch = snow->month;1l check It the current monch is a quarterly monch lvanvary, April, suly, uccober$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 101,strict: true);$this->logger->info(self::LOG_PREFIX . ' Checking conditions', [= custom.logÁ console [STAGING]© FilterDefinitionCollection.php, 0f Support Daily • in 2h 40 mAL AskJiminnyReportActivityServiceT...DefaultsElaravel.logA SF [jiminny@localhost] >4 HS_local [jiminny@localhost]Al console [PROD]© AskJiminnyReportActivityService.php© ActivitySearch.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpX:Auto vPlavaroundv100% C•Tue 14 Apr 12:20:26A console [EU]Onbemanavzcontroller.onoC HistoryService.phpRequestGenerateAskJiminnyReportJobTest.php14214314414514611481149150151152153154155156157158159160162163164165166167168169170171172173174175177179180181182183184185180187188189190191Ma lminnv v( activity_search_id 1978,( activity_search_id 1979,filter 'group_id',filter 'group_id'," 443f26b8-8512-437e-a9f9-7e75f8025c22') ,'443f26b8-8512-437e-a9f9-7e75f8025c22')010 A12 V.1 ^select * from crm_configurations where id = 39;select * from teams where id = 1;select * from team_features where team_id = 1;select * from features;SELECT * FROM activity_searches where id = 1982; # 1981SELECT * FROM activity_search_filters WHERE activity_search_id = 1982;SELECT * FROM automated_reports where id = 68;SELECT * FROM automated_report_results where id = 275;SELECT * FROM automated_reports order by id desc;SELECT * FROM automated_report_results order by id desc;select * from playbooks where team_id = 1;select * from crm_profiles where user_id = 143;s3://dev.jiminny.client-data/5f0f4810-7e77-4086-8f69-93429ae4d70b/panorama-reports/test_req_q_1.pdf|4 spaces...
|
NULL
|
3208784052608060068
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileEditFV faVsco.s vProject vw testuase.u PhpStormFileEditFV faVsco.s vProject vw testuase.uuy› _ vendorê .editorconfig= .env= .env.circleci=.env.circleci-nightly=.env.local=.env.migrate=.env.nikilocalE env.othenE env.productionE.env.production-eu=.env.aaE .env.qai=.env.rootE.env.staging= .gitattributes•.gitignore=.php-cs-fixer.cachephp.php-cs-fixer.dist.phpphp.phpstorm.meta.php=.phpunit.result.cacheE orettierianoreE .windsurfrulespip lue nelper.onephp_ide_helper_models.phpphp artisan0 composer.jsonO composer.lockO dependency-checker.json( dev.jsonEids.txtEinfection.ison.distM+INSALLMOIMJ INTERNAL_WEBHOOK_SETUP.mcEjiminny_storageM+licenses.mdM MakefileO package-lock.jsonEphpstan.neon.dist= phpstan-baseline.neon< phpunit.xmlTaraw_sqLquery.sqlM+ R-ADME,moso sonar-proiect propertiesEtest.py<> Untitled Diagram.xmlIs vetur.config.jsM+ WEBHOOK_FILTERING_IMPLEMEI› ib External LibrariesE° Scratches and Consolesv D Database ConsolesViewNavigateCodeLaravelRefactorToolsWindowHelp#11894 on JY-18909-automated-reports-ask-jiminny k ~© ReportController.phpJiminnyDeouecommana.ong© AutomatedReportsCommand.php x© AutomatedReportsRepository.phpC AutomatedReportsService.phpCreateHeldActivityEvent.php© UserPilotActivityListener.php© ActivityLogged.php© AutomatedReportsCallbackService.php© AutomatedReportResult.phpAutomaleakeportoneJuse Jiminny\ModeLs\Team;use Jiminny\Repositories\AutomatedReportsRepository;use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;use Psr\Log\LoggerInterface;vd jiminny@localhost4 console [jiminny@localhost4 DI liiminnv@localhostlc noocaminnvolocanos4 SF [jiminny@localhost]s cono dev minny clocaine> 4 PRODTests passed: 1 (11 minutes ago)C) AutomatedReportsSendCommand.php• TrackProviderInstalledEvent.phpC RequestGenerateAskJiminnyReportJob.php© AddLayoutEntities.php© Team.phpCreateActivityLoggedEvent.php© RequestGenerateReportJob.php19 Dclass Aurolareckeoor scoliialneextenos coniano31 G39 C43 Gt45* Log prefix for all log messages*/private const string LOG_PREFIX = '[automated-reports]';* The name and signature of the console command.* @var string*/protected Ssignature = 'automated-reports{--report-id= : Process a specific report by ID or UUID (bypasses frequency scheduLing)}':/*** The console command description.* Ovar stringprotected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly).Use --report-id to manually trigger a specific report by ID or UUID.':public function __construct(privace readonty Loggerintertace +logger,private readonly BusDispatcher $dispatcher,private readonly AutomatedReportsRepository $reportRepositoryparent: :__construct();* Execure cne console conmono.* Oreturn int*/public function handle(): int$this->logger->info(self::LOG_PREFIX .' Started');$now = Carbon: : now();$isMonday = $now->isMonday);$isFirstDay0fMonth = $now->day === 1;scurrencmonch = snow->month;1l check It the current monch is a quarterly monch lvanvary, April, suly, uccober$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 101,strict: true);$this->logger->info(self::LOG_PREFIX . ' Checking conditions', [= custom.logÁ console [STAGING]© FilterDefinitionCollection.php, 0f Support Daily • in 2h 40 mAL AskJiminnyReportActivityServiceT...DefaultsElaravel.logA SF [jiminny@localhost] >4 HS_local [jiminny@localhost]Al console [PROD]© AskJiminnyReportActivityService.php© ActivitySearch.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpX:Auto vPlavaroundv100% C•Tue 14 Apr 12:20:26A console [EU]Onbemanavzcontroller.onoC HistoryService.phpRequestGenerateAskJiminnyReportJobTest.php14214314414514611481149150151152153154155156157158159160162163164165166167168169170171172173174175177179180181182183184185180187188189190191Ma lminnv v( activity_search_id 1978,( activity_search_id 1979,filter 'group_id',filter 'group_id'," 443f26b8-8512-437e-a9f9-7e75f8025c22') ,'443f26b8-8512-437e-a9f9-7e75f8025c22')010 A12 V.1 ^select * from crm_configurations where id = 39;select * from teams where id = 1;select * from team_features where team_id = 1;select * from features;SELECT * FROM activity_searches where id = 1982; # 1981SELECT * FROM activity_search_filters WHERE activity_search_id = 1982;SELECT * FROM automated_reports where id = 68;SELECT * FROM automated_report_results where id = 275;SELECT * FROM automated_reports order by id desc;SELECT * FROM automated_report_results order by id desc;select * from playbooks where team_id = 1;select * from crm_profiles where user_id = 143;s3://dev.jiminny.client-data/5f0f4810-7e77-4086-8f69-93429ae4d70b/panorama-reports/test_req_q_1.pdf|4 spaces...
|
NULL
|
|
11225
|
223
|
11
|
2026-04-14T09:20:31.646332+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158431646_m2.jpg...
|
PhpStorm
|
faVsco.js – SF [jiminny@localhost]
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…
In-Editor Results
Tx: Auto
Cancel Running Statements
Playground
jiminny
Code changed:
Hide
Sync Changes
Hide This Notification
10
12
2
4
Previous Highlighted Error
Next Highlighted Error
SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o
JOIN activities a ON o.id = a.opportunity_id
WHERE a.crm_configuration_id = 39
AND a.actual_start_time > '2025-10-13'
AND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM activities
WHERE crm_configuration_id = 39 and user_id = 143
and actual_start_time >= '2025-10-13'
AND type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM opportunities WHERE account_id IN (178);
select * from activities where id IN (620137, 620187, 620188, 620189, 620230);
# HS
SELECT * FROM opportunities WHERE id IN (238);
select * from activities where id IN (477,2076);
select * from users;
SELECT COUNT(*) FROM users;
SELECT COUNT(*) FROM activities;
SELECT COUNT(*) FROM opportunities;
UPDATE activities
SET
actual_start_time = '2025-12-19 09:00:00',
actual_end_time = '2025-12-19 10:30:00',
scheduled_start_time = '2025-12-19 09:00:00',
scheduled_end_time = '2025-12-19 10:30:00'
WHERE id IN (407509,407375);
select * from partners;
SELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id
FROM activities
WHERE user_id = 143
AND actual_start_time >= '2025-10-13 00:00:00'
AND actual_start_time <= '2026-01-13 23:59:59'
ORDER BY actual_start_time DESC;
SELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;
SELECT * FROM crm_layouts where crm_configuration_id = 39;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
# lead_id
# account_id 177
# contact_id 3969
# opportunity_id
# stage_id 203
SELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;
SELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'
AND user_id = 143 and actual_start_time >= '2025-10-13';
SELECT * FROM activities a
# JOIN opportunities o ON a.opportunity_id = o.id
WHERE a.crm_configuration_id = 39 AND a.type = 'conference'
and status = 'completed' and recording_state = 'recorded'
and a.actual_start_time >= '2025-10-13'
AND a.user_id = 143
;
select * from leads
where crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310);
SELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198
SELECT * FROM activities WHERE id IN (356001, 356008); # contacts:
SELECT * FROM opportunities WHERE id IN (1707);
SELECT * FROM stages where id IN (204, 198);
SELECT * FROM opportunities WHERE account_id IN (178);
SELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';
SELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal
SELECT * FROM activities where crm_configuration_id = 39
AND opportunity_id IS NULL
AND is_internal = false
and status = 'completed' and recording_state = 'recorded'
AND actual_start_time >= '2025-10-13'
AND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)
# AND lead_id IN (112, 109)
;
SELECT * FROM crm_profiles WHERE user_id = 143;
select * from inboxes; # 212
select * from users where id = 143; # 143
select * from inbox_email_batches where inbox_id = 212
and updated_at >= '2026-01-28 00:00:00' order by id desc;
select * from inbox_emails where inbox_id = 212
and batch_id = 95885 order by id desc;
select * from email_messages where origin_user_id = 143;
select * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';
select * from participants where activity_id = 620247;
select * from crm_profiles where user_id = 143;
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001
select * from transcription where activity_id = 356001; # 6943
select * from ai_prompts where transcription_id = 6943;
SELECT * FROM activity_summary_logs where activity_id = 356001;
SELECT * FROM social_accounts WHERE sociable_id = 143;
# [PASSWORD_DOTS]
SELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;
# 422515 softphone tr. 8100
SELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;
# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS
select * from ai_prompts where transcription_id IN (8100, 7670);
select * from activity_summary_logs where activity_id = 407509;
select * from sidekick_settings;
select * from default_activity_types;
SELECT * FROM contacts WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM leads WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM activity_searches where user_id = 143;
SELECT * FROM groups where team_id = 1;
select * from teams where id = 1;
select * from groups where team_id = 1; # 1150 - 7e75f8025c22
select id, name, group_id, status, deleted_at, email
from users where team_id = 1 order by group_id desc ;
select * from activity_searches where id in (1977, 1978, 1979);
select * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);
select * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277
select * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879
INSERT INTO `activity_search_filters`
(`activity_search_id`, `filter`, `value`) VALUES
(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')
;
select * from crm_configurations where id = 39;
select * from teams where id = 1;
select * from team_features where team_id = 1;
select * from features;
SELECT * FROM activity_searches where id = 1982; # 1981
SELECT * FROM activity_search_filters WHERE activity_search_id = 1982;
SELECT * FROM automated_reports where id = 68;
SELECT * FROM automated_report_results where id = 275;
SELECT * FROM automated_reports order by id desc;
SELECT * FROM automated_report_results order by id desc;
select * from activity_searches where user_id = 143;
select * from ask_anything_prompts;
SELECT * FROM groups WHERE id = 1439;
SELECT * FROM users WHERE group_id = 1439;
select * from permissions; # 158
select * from roles;
select * from permission_role
select * from teams where id = 1;
select * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;
select * from groups where id = 28;
select * from playbooks where team_id = 1;
select * from playbooks where id = 179;
select * from playbook_categories where id = 1391;
select * from users where id = 143;
select * from crm_profiles where user_id = 143;
select * from activities where crm_configuration_id = 39 and type = 'conference'
and crm_provider_id IS NOT NULL ORDER by id desc;
select * from activities where id = 422003; # 00UO400000pB6fpMAC
SELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type
FROM automated_report_results ar
JOIN automated_reports a ON a.id = ar.report_id
WHERE a.type = 'ask_jiminny'
LIMIT 10;
{"request_id":"edc47759-160a-4f61-82fc-c8cdf5e55464","status":"completed","timestamp":"2026-03-31T15:52:05.828229+00:00","s3_url":"s3:\/\/dev.jiminny.client-data\/5f0f4810-7e77-4086-8f69-93429ae4d70b\/panorama-reports\/test_req_q_1.MD","report_type":"exec_summary","pdf_url":"s3:\/\/dev.jiminny.client-data\/5f0f4810-7e77-4086-8f69-93429ae4d70b\/panorama-reports\/test_req_q_1.pdf"}
[URL_WITH_CREDENTIALS] string
*/
protected $signature = 'automated-reports
{--report-id= : Process a specific report by ID or UUID (bypasses frequency scheduling)}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly).
Use --report-id to manually trigger a specific report by ID or UUID.';
public function __construct(
private readonly LoggerInterface $logger,
private readonly BusDispatcher $dispatcher,
private readonly AutomatedReportsRepository $reportRepository
) {
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle(): int
{
$this->logger->info(self::LOG_PREFIX . ' Started');
$now = Carbon::now();
$isMonday = $now->isMonday();
$isFirstDayOfMonth = $now->day === 1;
$currentMonth = $now->month;
// Check if the current month is a quarterly month (January, April, July, October)
$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);
$this->logger->info(self::LOG_PREFIX . ' Checking conditions', [
'isMonday' => $isMonday,
'isFirstDayOfMonth' => $isFirstDayOfMonth,
'currentMonth' => $currentMonth,
'isQuarterlyMonth' => $isQuarterlyMonth,
]);
// Process daily reports
$this->processReports(AutomatedReportsService::FREQUENCY_DAILY);
// Process weekly reports on Mondays
if ($isMonday) {
$this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);
}
// Process monthly reports on the first day of the month
if ($isFirstDayOfMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);
}
// Process quarterly reports on the first day of January, April, July, and October
if ($isFirstDayOfMonth && $isQuarterlyMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);
}
$this->logger->info(self::LOG_PREFIX . ' Completed');
return 0;
}
/**
* Process reports for a specific frequency.
*
* @param string $frequency
*
* @return void
*/
private function processReports(string $frequency): void
{
$this->logger->info(self::LOG_PREFIX . " Processing $frequency reports");
$reportId = $this->option('report-id');
if ($reportId !== null) {
$reports = $this->getReportById($reportId);
} else {
// Get all enabled, not deleted reports with active teams for the specified frequency
$reports = $this->reportRepository->getActiveReportsByFrequency($frequency);
}
$this->logger->info(self::LOG_PREFIX . " Found {$reports->count()} $frequency reports to process");
/** @var AutomatedReport $report */
foreach ($reports as $report) {
$this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [
'reportUuid' => $report->getUuid(),
'teamId' => $report->getTeamId(),
'frequency' => $report->getFrequency(),
'type' => $report->getType(),
]);
$job = $report->isAskJiminnyReport()
? new RequestGenerateAskJiminnyReportJob($report->getUuid())
: new RequestGenerateReportJob($report->getUuid());
$this->dispatcher->dispatch($job);
}
}
private function getReportById(string $reportId): Collection
{
$report = $this->reportRepository->findByIdOrUuid($reportId);
if ($report === null) {
$this->logger->warning(self::LOG_PREFIX . ' Report not found for --report-id', ['reportId' => $reportId]);
$this->warn("Report not found: {$reportId}");
return collect();
}
if (! $report->getStatus()) {
$this->logger->warning(self::LOG_PREFIX . ' Report is inactive, processing anyway (manual override)', [
'reportId' => $reportId,
'reportUuid' => $report->getUuid(),
]);
$this->warn('Report is inactive — processing anyway (manual override).');
}
$team = $report->getTeam();
if ($team->getStatus() !== Team::STATUS_ACTIVE) {
$this->logger->warning(self::LOG_PREFIX . ' Team is not active, processing anyway (manual override)', [
'reportId' => $reportId,
'reportUuid' => $report->getUuid(),
'teamId' => $report->getTeamId(),
'teamStatus' => $team->getStatus(),
]);
$this->warn("Team #{$report->getTeamId()} is not active — processing anyway (manual override).");
}
if ($report->isExpired()) {
$this->logger->warning(self::LOG_PREFIX . ' Report is expired, processing anyway (manual override)', [
'reportId' => $reportId,
'reportUuid' => $report->getUuid(),
'expiresAt' => $report->getExpiresAt()?->toDateString(),
]);
$this->warn('Report is expired (expires_at: ' . $report->getExpiresAt()?->toDateString() . ') — processing anyway (manual override).');
}
return collect([$report]);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl, folder
ActionItems, folder
Activity, folder
ActivityAnalytics, folder
ActivitySearch, folder...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","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.7589844,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceT…Defaults","depth":6,"bounds":{"left":0.7769531,"top":0.017361112,"width":0.12382813,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Execute","depth":4,"bounds":{"left":0.6171875,"top":0.10763889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Explain Plan","depth":4,"bounds":{"left":0.6273438,"top":0.10763889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Browse Query History","depth":4,"bounds":{"left":0.64023435,"top":0.10763889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"View Parameters","depth":4,"bounds":{"left":0.6503906,"top":0.10763889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open Query Execution Settings…","depth":4,"bounds":{"left":0.6605469,"top":0.10763889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"In-Editor Results","depth":4,"bounds":{"left":0.6734375,"top":0.10763889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tx: Auto","depth":4,"bounds":{"left":0.6863281,"top":0.10763889,"width":0.028515626,"height":0.016666668},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cancel Running Statements","depth":4,"bounds":{"left":0.7175781,"top":0.10763889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Playground","depth":4,"bounds":{"left":0.73046875,"top":0.10763889,"width":0.034765624,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"bounds":{"left":0.9515625,"top":0.10763889,"width":0.033203125,"height":0.016666668},"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.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10","depth":4,"bounds":{"left":0.91914064,"top":0.12916666,"width":0.011328125,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"12","depth":4,"bounds":{"left":0.9328125,"top":0.12916666,"width":0.011328125,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.9464844,"top":0.12916666,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.95820314,"top":0.12916666,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.96953124,"top":0.12777779,"width":0.00859375,"height":0.015972223},"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.978125,"top":0.12777779,"width":0.008203125,"height":0.015972223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o\nJOIN activities a ON o.id = a.opportunity_id\nWHERE a.crm_configuration_id = 39\nAND a.actual_start_time > '2025-10-13'\nAND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM activities\nWHERE crm_configuration_id = 39 and user_id = 143\nand actual_start_time >= '2025-10-13'\nAND type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM opportunities WHERE account_id IN (178);\nselect * from activities where id IN (620137, 620187, 620188, 620189, 620230);\n\n# HS\nSELECT * FROM opportunities WHERE id IN (238);\nselect * from activities where id IN (477,2076);\n\nselect * from users;\n\nSELECT COUNT(*) FROM users;\nSELECT COUNT(*) FROM activities;\nSELECT COUNT(*) FROM opportunities;\n\nUPDATE activities\nSET\n actual_start_time = '2025-12-19 09:00:00',\n actual_end_time = '2025-12-19 10:30:00',\n scheduled_start_time = '2025-12-19 09:00:00',\n scheduled_end_time = '2025-12-19 10:30:00'\nWHERE id IN (407509,407375);\n\nselect * from partners;\n\nSELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id\nFROM activities\nWHERE user_id = 143\nAND actual_start_time >= '2025-10-13 00:00:00'\nAND actual_start_time <= '2026-01-13 23:59:59'\nORDER BY actual_start_time DESC;\n\nSELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;\nSELECT * FROM crm_layouts where crm_configuration_id = 39;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\n# lead_id\n# account_id 177\n# contact_id 3969\n# opportunity_id\n# stage_id 203\n\nSELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;\n\nSELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'\nAND user_id = 143 and actual_start_time >= '2025-10-13';\n\nSELECT * FROM activities a\n# JOIN opportunities o ON a.opportunity_id = o.id\nWHERE a.crm_configuration_id = 39 AND a.type = 'conference'\nand status = 'completed' and recording_state = 'recorded'\nand a.actual_start_time >= '2025-10-13'\nAND a.user_id = 143\n;\n\nselect * from leads\nwhere crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707\n\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310);\nSELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198\nSELECT * FROM activities WHERE id IN (356001, 356008); # contacts:\n\nSELECT * FROM opportunities WHERE id IN (1707);\nSELECT * FROM stages where id IN (204, 198);\nSELECT * FROM opportunities WHERE account_id IN (178);\nSELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';\nSELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal\n\nSELECT * FROM activities where crm_configuration_id = 39\nAND opportunity_id IS NULL\nAND is_internal = false\nand status = 'completed' and recording_state = 'recorded'\nAND actual_start_time >= '2025-10-13'\nAND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)\n# AND lead_id IN (112, 109)\n;\n\nSELECT * FROM crm_profiles WHERE user_id = 143;\n\nselect * from inboxes; # 212\nselect * from users where id = 143; # 143\nselect * from inbox_email_batches where inbox_id = 212\nand updated_at >= '2026-01-28 00:00:00' order by id desc;\nselect * from inbox_emails where inbox_id = 212\nand batch_id = 95885 order by id desc;\nselect * from email_messages where origin_user_id = 143;\nselect * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';\nselect * from participants where activity_id = 620247;\n\nselect * from crm_profiles where user_id = 143;\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001\nselect * from transcription where activity_id = 356001; # 6943\nselect * from ai_prompts where transcription_id = 6943;\nSELECT * FROM activity_summary_logs where activity_id = 356001;\n\nSELECT * FROM social_accounts WHERE sociable_id = 143;\n\n# ************************************************************************************\nSELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;\n# 422515 softphone tr. 8100\n\nSELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;\n# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS\n\nselect * from ai_prompts where transcription_id IN (8100, 7670);\nselect * from activity_summary_logs where activity_id = 407509;\n\nselect * from sidekick_settings;\nselect * from default_activity_types;\n\nSELECT * FROM contacts WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\nSELECT * FROM leads WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\n\nSELECT * FROM activity_searches where user_id = 143;\nSELECT * FROM groups where team_id = 1;\n\nselect * from teams where id = 1;\nselect * from groups where team_id = 1; # 1150 - 7e75f8025c22\nselect id, name, group_id, status, deleted_at, email\nfrom users where team_id = 1 order by group_id desc ;\n\nselect * from activity_searches where id in (1977, 1978, 1979);\nselect * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);\nselect * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277\nselect * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879\n\nINSERT INTO `activity_search_filters`\n(`activity_search_id`, `filter`, `value`) VALUES\n(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')\n;\n\nselect * from crm_configurations where id = 39;\n\nselect * from teams where id = 1;\nselect * from team_features where team_id = 1;\nselect * from features;\n\nSELECT * FROM activity_searches where id = 1982; # 1981\nSELECT * FROM activity_search_filters WHERE activity_search_id = 1982;\n\nSELECT * FROM automated_reports where id = 68;\nSELECT * FROM automated_report_results where id = 275;\n\nSELECT * FROM automated_reports order by id desc;\nSELECT * FROM automated_report_results order by id desc;\nselect * from activity_searches where user_id = 143;\nselect * from ask_anything_prompts;\n\nSELECT * FROM groups WHERE id = 1439;\nSELECT * FROM users WHERE group_id = 1439;\n\nselect * from permissions; # 158\nselect * from roles;\nselect * from permission_role\n\nselect * from teams where id = 1;\nselect * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;\nselect * from groups where id = 28;\nselect * from playbooks where team_id = 1;\nselect * from playbooks where id = 179;\nselect * from playbook_categories where id = 1391;\nselect * from users where id = 143;\nselect * from crm_profiles where user_id = 143;\nselect * from activities where crm_configuration_id = 39 and type = 'conference'\nand crm_provider_id IS NOT NULL ORDER by id desc;\nselect * from activities where id = 422003; # 00UO400000pB6fpMAC\n\nSELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type\nFROM automated_report_results ar\nJOIN automated_reports a ON a.id = ar.report_id\nWHERE a.type = 'ask_jiminny'\nLIMIT 10;\n\n{\"request_id\":\"edc47759-160a-4f61-82fc-c8cdf5e55464\",\"status\":\"completed\",\"timestamp\":\"2026-03-31T15:52:05.828229+00:00\",\"s3_url\":\"s3:\\/\\/dev.jiminny.client-data\\/5f0f4810-7e77-4086-8f69-93429ae4d70b\\/panorama-reports\\/test_req_q_1.MD\",\"report_type\":\"exec_summary\",\"pdf_url\":\"s3:\\/\\/dev.jiminny.client-data\\/5f0f4810-7e77-4086-8f69-93429ae4d70b\\/panorama-reports\\/test_req_q_1.pdf\"}\n\ns3://dev.jiminny.client-data/5f0f4810-7e77-4086-8f69-93429ae4d70b/panorama-reports/test_req_q_1.MD\ns3://dev.jiminny.client-data/5f0f4810-7e77-4086-8f69-93429ae4d70b/panorama-reports/test_req_q_1.pdf","depth":4,"value":"SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o\nJOIN activities a ON o.id = a.opportunity_id\nWHERE a.crm_configuration_id = 39\nAND a.actual_start_time > '2025-10-13'\nAND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM activities\nWHERE crm_configuration_id = 39 and user_id = 143\nand actual_start_time >= '2025-10-13'\nAND type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM opportunities WHERE account_id IN (178);\nselect * from activities where id IN (620137, 620187, 620188, 620189, 620230);\n\n# HS\nSELECT * FROM opportunities WHERE id IN (238);\nselect * from activities where id IN (477,2076);\n\nselect * from users;\n\nSELECT COUNT(*) FROM users;\nSELECT COUNT(*) FROM activities;\nSELECT COUNT(*) FROM opportunities;\n\nUPDATE activities\nSET\n actual_start_time = '2025-12-19 09:00:00',\n actual_end_time = '2025-12-19 10:30:00',\n scheduled_start_time = '2025-12-19 09:00:00',\n scheduled_end_time = '2025-12-19 10:30:00'\nWHERE id IN (407509,407375);\n\nselect * from partners;\n\nSELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id\nFROM activities\nWHERE user_id = 143\nAND actual_start_time >= '2025-10-13 00:00:00'\nAND actual_start_time <= '2026-01-13 23:59:59'\nORDER BY actual_start_time DESC;\n\nSELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;\nSELECT * FROM crm_layouts where crm_configuration_id = 39;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\n# lead_id\n# account_id 177\n# contact_id 3969\n# opportunity_id\n# stage_id 203\n\nSELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;\n\nSELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'\nAND user_id = 143 and actual_start_time >= '2025-10-13';\n\nSELECT * FROM activities a\n# JOIN opportunities o ON a.opportunity_id = o.id\nWHERE a.crm_configuration_id = 39 AND a.type = 'conference'\nand status = 'completed' and recording_state = 'recorded'\nand a.actual_start_time >= '2025-10-13'\nAND a.user_id = 143\n;\n\nselect * from leads\nwhere crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707\n\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310);\nSELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198\nSELECT * FROM activities WHERE id IN (356001, 356008); # contacts:\n\nSELECT * FROM opportunities WHERE id IN (1707);\nSELECT * FROM stages where id IN (204, 198);\nSELECT * FROM opportunities WHERE account_id IN (178);\nSELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';\nSELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal\n\nSELECT * FROM activities where crm_configuration_id = 39\nAND opportunity_id IS NULL\nAND is_internal = false\nand status = 'completed' and recording_state = 'recorded'\nAND actual_start_time >= '2025-10-13'\nAND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)\n# AND lead_id IN (112, 109)\n;\n\nSELECT * FROM crm_profiles WHERE user_id = 143;\n\nselect * from inboxes; # 212\nselect * from users where id = 143; # 143\nselect * from inbox_email_batches where inbox_id = 212\nand updated_at >= '2026-01-28 00:00:00' order by id desc;\nselect * from inbox_emails where inbox_id = 212\nand batch_id = 95885 order by id desc;\nselect * from email_messages where origin_user_id = 143;\nselect * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';\nselect * from participants where activity_id = 620247;\n\nselect * from crm_profiles where user_id = 143;\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001\nselect * from transcription where activity_id = 356001; # 6943\nselect * from ai_prompts where transcription_id = 6943;\nSELECT * FROM activity_summary_logs where activity_id = 356001;\n\nSELECT * FROM social_accounts WHERE sociable_id = 143;\n\n# ************************************************************************************\nSELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;\n# 422515 softphone tr. 8100\n\nSELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;\n# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS\n\nselect * from ai_prompts where transcription_id IN (8100, 7670);\nselect * from activity_summary_logs where activity_id = 407509;\n\nselect * from sidekick_settings;\nselect * from default_activity_types;\n\nSELECT * FROM contacts WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\nSELECT * FROM leads WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\n\nSELECT * FROM activity_searches where user_id = 143;\nSELECT * FROM groups where team_id = 1;\n\nselect * from teams where id = 1;\nselect * from groups where team_id = 1; # 1150 - 7e75f8025c22\nselect id, name, group_id, status, deleted_at, email\nfrom users where team_id = 1 order by group_id desc ;\n\nselect * from activity_searches where id in (1977, 1978, 1979);\nselect * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);\nselect * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277\nselect * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879\n\nINSERT INTO `activity_search_filters`\n(`activity_search_id`, `filter`, `value`) VALUES\n(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')\n;\n\nselect * from crm_configurations where id = 39;\n\nselect * from teams where id = 1;\nselect * from team_features where team_id = 1;\nselect * from features;\n\nSELECT * FROM activity_searches where id = 1982; # 1981\nSELECT * FROM activity_search_filters WHERE activity_search_id = 1982;\n\nSELECT * FROM automated_reports where id = 68;\nSELECT * FROM automated_report_results where id = 275;\n\nSELECT * FROM automated_reports order by id desc;\nSELECT * FROM automated_report_results order by id desc;\nselect * from activity_searches where user_id = 143;\nselect * from ask_anything_prompts;\n\nSELECT * FROM groups WHERE id = 1439;\nSELECT * FROM users WHERE group_id = 1439;\n\nselect * from permissions; # 158\nselect * from roles;\nselect * from permission_role\n\nselect * from teams where id = 1;\nselect * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;\nselect * from groups where id = 28;\nselect * from playbooks where team_id = 1;\nselect * from playbooks where id = 179;\nselect * from playbook_categories where id = 1391;\nselect * from users where id = 143;\nselect * from crm_profiles where user_id = 143;\nselect * from activities where crm_configuration_id = 39 and type = 'conference'\nand crm_provider_id IS NOT NULL ORDER by id desc;\nselect * from activities where id = 422003; # 00UO400000pB6fpMAC\n\nSELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type\nFROM automated_report_results ar\nJOIN automated_reports a ON a.id = ar.report_id\nWHERE a.type = 'ask_jiminny'\nLIMIT 10;\n\n{\"request_id\":\"edc47759-160a-4f61-82fc-c8cdf5e55464\",\"status\":\"completed\",\"timestamp\":\"2026-03-31T15:52:05.828229+00:00\",\"s3_url\":\"s3:\\/\\/dev.jiminny.client-data\\/5f0f4810-7e77-4086-8f69-93429ae4d70b\\/panorama-reports\\/test_req_q_1.MD\",\"report_type\":\"exec_summary\",\"pdf_url\":\"s3:\\/\\/dev.jiminny.client-data\\/5f0f4810-7e77-4086-8f69-93429ae4d70b\\/panorama-reports\\/test_req_q_1.pdf\"}\n\ns3://dev.jiminny.client-data/5f0f4810-7e77-4086-8f69-93429ae4d70b/panorama-reports/test_req_q_1.MD\ns3://dev.jiminny.client-data/5f0f4810-7e77-4086-8f69-93429ae4d70b/panorama-reports/test_req_q_1.pdf","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.5875,"top":0.13055556,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.59882814,"top":0.12916666,"width":0.00859375,"height":0.015972223},"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.6074219,"top":0.12916666,"width":0.008203125,"height":0.015972223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands\\Reports;\n\nuse Carbon\\Carbon;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Bus\\Dispatcher as BusDispatcher;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateReportJob;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Psr\\Log\\LoggerInterface;\n\nclass AutomatedReportsCommand extends Command\n{\n /**\n * Log prefix for all log messages\n */\n private const string LOG_PREFIX = '[automated-reports]';\n\n /**\n * The name and signature of the console command.\n *\n * @var string\n */\n protected $signature = 'automated-reports \n {--report-id= : Process a specific report by ID or UUID (bypasses frequency scheduling)}';\n\n /**\n * The console command description.\n *\n * @var string\n */\n protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly). \n Use --report-id to manually trigger a specific report by ID or UUID.';\n\n\n public function __construct(\n private readonly LoggerInterface $logger,\n private readonly BusDispatcher $dispatcher,\n private readonly AutomatedReportsRepository $reportRepository\n ) {\n parent::__construct();\n }\n\n /**\n * Execute the console command.\n *\n * @return int\n */\n public function handle(): int\n {\n $this->logger->info(self::LOG_PREFIX . ' Started');\n\n $now = Carbon::now();\n $isMonday = $now->isMonday();\n $isFirstDayOfMonth = $now->day === 1;\n $currentMonth = $now->month;\n\n // Check if the current month is a quarterly month (January, April, July, October)\n $isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);\n\n $this->logger->info(self::LOG_PREFIX . ' Checking conditions', [\n 'isMonday' => $isMonday,\n 'isFirstDayOfMonth' => $isFirstDayOfMonth,\n 'currentMonth' => $currentMonth,\n 'isQuarterlyMonth' => $isQuarterlyMonth,\n ]);\n\n // Process daily reports\n $this->processReports(AutomatedReportsService::FREQUENCY_DAILY);\n\n // Process weekly reports on Mondays\n if ($isMonday) {\n $this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);\n }\n\n // Process monthly reports on the first day of the month\n if ($isFirstDayOfMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);\n }\n\n // Process quarterly reports on the first day of January, April, July, and October\n if ($isFirstDayOfMonth && $isQuarterlyMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);\n }\n\n $this->logger->info(self::LOG_PREFIX . ' Completed');\n\n return 0;\n }\n\n /**\n * Process reports for a specific frequency.\n *\n * @param string $frequency\n *\n * @return void\n */\n private function processReports(string $frequency): void\n {\n $this->logger->info(self::LOG_PREFIX . \" Processing $frequency reports\");\n\n $reportId = $this->option('report-id');\n if ($reportId !== null) {\n $reports = $this->getReportById($reportId);\n } else {\n // Get all enabled, not deleted reports with active teams for the specified frequency\n $reports = $this->reportRepository->getActiveReportsByFrequency($frequency);\n }\n\n $this->logger->info(self::LOG_PREFIX . \" Found {$reports->count()} $frequency reports to process\");\n\n /** @var AutomatedReport $report */\n foreach ($reports as $report) {\n $this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [\n 'reportUuid' => $report->getUuid(),\n 'teamId' => $report->getTeamId(),\n 'frequency' => $report->getFrequency(),\n 'type' => $report->getType(),\n ]);\n\n $job = $report->isAskJiminnyReport()\n ? new RequestGenerateAskJiminnyReportJob($report->getUuid())\n : new RequestGenerateReportJob($report->getUuid());\n\n $this->dispatcher->dispatch($job);\n }\n }\n\n private function getReportById(string $reportId): Collection\n {\n $report = $this->reportRepository->findByIdOrUuid($reportId);\n\n if ($report === null) {\n $this->logger->warning(self::LOG_PREFIX . ' Report not found for --report-id', ['reportId' => $reportId]);\n $this->warn(\"Report not found: {$reportId}\");\n\n return collect();\n }\n\n if (! $report->getStatus()) {\n $this->logger->warning(self::LOG_PREFIX . ' Report is inactive, processing anyway (manual override)', [\n 'reportId' => $reportId,\n 'reportUuid' => $report->getUuid(),\n ]);\n $this->warn('Report is inactive — processing anyway (manual override).');\n }\n\n $team = $report->getTeam();\n if ($team->getStatus() !== Team::STATUS_ACTIVE) {\n $this->logger->warning(self::LOG_PREFIX . ' Team is not active, processing anyway (manual override)', [\n 'reportId' => $reportId,\n 'reportUuid' => $report->getUuid(),\n 'teamId' => $report->getTeamId(),\n 'teamStatus' => $team->getStatus(),\n ]);\n $this->warn(\"Team #{$report->getTeamId()} is not active — processing anyway (manual override).\");\n }\n\n if ($report->isExpired()) {\n $this->logger->warning(self::LOG_PREFIX . ' Report is expired, processing anyway (manual override)', [\n 'reportId' => $reportId,\n 'reportUuid' => $report->getUuid(),\n 'expiresAt' => $report->getExpiresAt()?->toDateString(),\n ]);\n $this->warn('Report is expired (expires_at: ' . $report->getExpiresAt()?->toDateString() . ') — processing anyway (manual override).');\n }\n\n return collect([$report]);\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands\\Reports;\n\nuse Carbon\\Carbon;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Bus\\Dispatcher as BusDispatcher;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateReportJob;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Psr\\Log\\LoggerInterface;\n\nclass AutomatedReportsCommand extends Command\n{\n /**\n * Log prefix for all log messages\n */\n private const string LOG_PREFIX = '[automated-reports]';\n\n /**\n * The name and signature of the console command.\n *\n * @var string\n */\n protected $signature = 'automated-reports \n {--report-id= : Process a specific report by ID or UUID (bypasses frequency scheduling)}';\n\n /**\n * The console command description.\n *\n * @var string\n */\n protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly). \n Use --report-id to manually trigger a specific report by ID or UUID.';\n\n\n public function __construct(\n private readonly LoggerInterface $logger,\n private readonly BusDispatcher $dispatcher,\n private readonly AutomatedReportsRepository $reportRepository\n ) {\n parent::__construct();\n }\n\n /**\n * Execute the console command.\n *\n * @return int\n */\n public function handle(): int\n {\n $this->logger->info(self::LOG_PREFIX . ' Started');\n\n $now = Carbon::now();\n $isMonday = $now->isMonday();\n $isFirstDayOfMonth = $now->day === 1;\n $currentMonth = $now->month;\n\n // Check if the current month is a quarterly month (January, April, July, October)\n $isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);\n\n $this->logger->info(self::LOG_PREFIX . ' Checking conditions', [\n 'isMonday' => $isMonday,\n 'isFirstDayOfMonth' => $isFirstDayOfMonth,\n 'currentMonth' => $currentMonth,\n 'isQuarterlyMonth' => $isQuarterlyMonth,\n ]);\n\n // Process daily reports\n $this->processReports(AutomatedReportsService::FREQUENCY_DAILY);\n\n // Process weekly reports on Mondays\n if ($isMonday) {\n $this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);\n }\n\n // Process monthly reports on the first day of the month\n if ($isFirstDayOfMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);\n }\n\n // Process quarterly reports on the first day of January, April, July, and October\n if ($isFirstDayOfMonth && $isQuarterlyMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);\n }\n\n $this->logger->info(self::LOG_PREFIX . ' Completed');\n\n return 0;\n }\n\n /**\n * Process reports for a specific frequency.\n *\n * @param string $frequency\n *\n * @return void\n */\n private function processReports(string $frequency): void\n {\n $this->logger->info(self::LOG_PREFIX . \" Processing $frequency reports\");\n\n $reportId = $this->option('report-id');\n if ($reportId !== null) {\n $reports = $this->getReportById($reportId);\n } else {\n // Get all enabled, not deleted reports with active teams for the specified frequency\n $reports = $this->reportRepository->getActiveReportsByFrequency($frequency);\n }\n\n $this->logger->info(self::LOG_PREFIX . \" Found {$reports->count()} $frequency reports to process\");\n\n /** @var AutomatedReport $report */\n foreach ($reports as $report) {\n $this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [\n 'reportUuid' => $report->getUuid(),\n 'teamId' => $report->getTeamId(),\n 'frequency' => $report->getFrequency(),\n 'type' => $report->getType(),\n ]);\n\n $job = $report->isAskJiminnyReport()\n ? new RequestGenerateAskJiminnyReportJob($report->getUuid())\n : new RequestGenerateReportJob($report->getUuid());\n\n $this->dispatcher->dispatch($job);\n }\n }\n\n private function getReportById(string $reportId): Collection\n {\n $report = $this->reportRepository->findByIdOrUuid($reportId);\n\n if ($report === null) {\n $this->logger->warning(self::LOG_PREFIX . ' Report not found for --report-id', ['reportId' => $reportId]);\n $this->warn(\"Report not found: {$reportId}\");\n\n return collect();\n }\n\n if (! $report->getStatus()) {\n $this->logger->warning(self::LOG_PREFIX . ' Report is inactive, processing anyway (manual override)', [\n 'reportId' => $reportId,\n 'reportUuid' => $report->getUuid(),\n ]);\n $this->warn('Report is inactive — processing anyway (manual override).');\n }\n\n $team = $report->getTeam();\n if ($team->getStatus() !== Team::STATUS_ACTIVE) {\n $this->logger->warning(self::LOG_PREFIX . ' Team is not active, processing anyway (manual override)', [\n 'reportId' => $reportId,\n 'reportUuid' => $report->getUuid(),\n 'teamId' => $report->getTeamId(),\n 'teamStatus' => $team->getStatus(),\n ]);\n $this->warn(\"Team #{$report->getTeamId()} is not active — processing anyway (manual override).\");\n }\n\n if ($report->isExpired()) {\n $this->logger->warning(self::LOG_PREFIX . ' Report is expired, processing anyway (manual override)', [\n 'reportId' => $reportId,\n 'reportUuid' => $report->getUuid(),\n 'expiresAt' => $report->getExpiresAt()?->toDateString(),\n ]);\n $this->warn('Report is expired (expires_at: ' . $report->getExpiresAt()?->toDateString() . ') — processing anyway (manual override).');\n }\n\n return collect([$report]);\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,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.0140625,"top":0.041666668,"width":0.028515626,"height":0.021527778},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Acl, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Activity, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch, folder","depth":9,"role_description":"text"}]...
|
-5927610008380917177
|
6470157055874699845
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…
In-Editor Results
Tx: Auto
Cancel Running Statements
Playground
jiminny
Code changed:
Hide
Sync Changes
Hide This Notification
10
12
2
4
Previous Highlighted Error
Next Highlighted Error
SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o
JOIN activities a ON o.id = a.opportunity_id
WHERE a.crm_configuration_id = 39
AND a.actual_start_time > '2025-10-13'
AND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM activities
WHERE crm_configuration_id = 39 and user_id = 143
and actual_start_time >= '2025-10-13'
AND type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM opportunities WHERE account_id IN (178);
select * from activities where id IN (620137, 620187, 620188, 620189, 620230);
# HS
SELECT * FROM opportunities WHERE id IN (238);
select * from activities where id IN (477,2076);
select * from users;
SELECT COUNT(*) FROM users;
SELECT COUNT(*) FROM activities;
SELECT COUNT(*) FROM opportunities;
UPDATE activities
SET
actual_start_time = '2025-12-19 09:00:00',
actual_end_time = '2025-12-19 10:30:00',
scheduled_start_time = '2025-12-19 09:00:00',
scheduled_end_time = '2025-12-19 10:30:00'
WHERE id IN (407509,407375);
select * from partners;
SELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id
FROM activities
WHERE user_id = 143
AND actual_start_time >= '2025-10-13 00:00:00'
AND actual_start_time <= '2026-01-13 23:59:59'
ORDER BY actual_start_time DESC;
SELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;
SELECT * FROM crm_layouts where crm_configuration_id = 39;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
# lead_id
# account_id 177
# contact_id 3969
# opportunity_id
# stage_id 203
SELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;
SELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'
AND user_id = 143 and actual_start_time >= '2025-10-13';
SELECT * FROM activities a
# JOIN opportunities o ON a.opportunity_id = o.id
WHERE a.crm_configuration_id = 39 AND a.type = 'conference'
and status = 'completed' and recording_state = 'recorded'
and a.actual_start_time >= '2025-10-13'
AND a.user_id = 143
;
select * from leads
where crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310);
SELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198
SELECT * FROM activities WHERE id IN (356001, 356008); # contacts:
SELECT * FROM opportunities WHERE id IN (1707);
SELECT * FROM stages where id IN (204, 198);
SELECT * FROM opportunities WHERE account_id IN (178);
SELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';
SELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal
SELECT * FROM activities where crm_configuration_id = 39
AND opportunity_id IS NULL
AND is_internal = false
and status = 'completed' and recording_state = 'recorded'
AND actual_start_time >= '2025-10-13'
AND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)
# AND lead_id IN (112, 109)
;
SELECT * FROM crm_profiles WHERE user_id = 143;
select * from inboxes; # 212
select * from users where id = 143; # 143
select * from inbox_email_batches where inbox_id = 212
and updated_at >= '2026-01-28 00:00:00' order by id desc;
select * from inbox_emails where inbox_id = 212
and batch_id = 95885 order by id desc;
select * from email_messages where origin_user_id = 143;
select * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';
select * from participants where activity_id = 620247;
select * from crm_profiles where user_id = 143;
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001
select * from transcription where activity_id = 356001; # 6943
select * from ai_prompts where transcription_id = 6943;
SELECT * FROM activity_summary_logs where activity_id = 356001;
SELECT * FROM social_accounts WHERE sociable_id = 143;
# [PASSWORD_DOTS]
SELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;
# 422515 softphone tr. 8100
SELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;
# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS
select * from ai_prompts where transcription_id IN (8100, 7670);
select * from activity_summary_logs where activity_id = 407509;
select * from sidekick_settings;
select * from default_activity_types;
SELECT * FROM contacts WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM leads WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM activity_searches where user_id = 143;
SELECT * FROM groups where team_id = 1;
select * from teams where id = 1;
select * from groups where team_id = 1; # 1150 - 7e75f8025c22
select id, name, group_id, status, deleted_at, email
from users where team_id = 1 order by group_id desc ;
select * from activity_searches where id in (1977, 1978, 1979);
select * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);
select * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277
select * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879
INSERT INTO `activity_search_filters`
(`activity_search_id`, `filter`, `value`) VALUES
(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')
;
select * from crm_configurations where id = 39;
select * from teams where id = 1;
select * from team_features where team_id = 1;
select * from features;
SELECT * FROM activity_searches where id = 1982; # 1981
SELECT * FROM activity_search_filters WHERE activity_search_id = 1982;
SELECT * FROM automated_reports where id = 68;
SELECT * FROM automated_report_results where id = 275;
SELECT * FROM automated_reports order by id desc;
SELECT * FROM automated_report_results order by id desc;
select * from activity_searches where user_id = 143;
select * from ask_anything_prompts;
SELECT * FROM groups WHERE id = 1439;
SELECT * FROM users WHERE group_id = 1439;
select * from permissions; # 158
select * from roles;
select * from permission_role
select * from teams where id = 1;
select * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;
select * from groups where id = 28;
select * from playbooks where team_id = 1;
select * from playbooks where id = 179;
select * from playbook_categories where id = 1391;
select * from users where id = 143;
select * from crm_profiles where user_id = 143;
select * from activities where crm_configuration_id = 39 and type = 'conference'
and crm_provider_id IS NOT NULL ORDER by id desc;
select * from activities where id = 422003; # 00UO400000pB6fpMAC
SELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type
FROM automated_report_results ar
JOIN automated_reports a ON a.id = ar.report_id
WHERE a.type = 'ask_jiminny'
LIMIT 10;
{"request_id":"edc47759-160a-4f61-82fc-c8cdf5e55464","status":"completed","timestamp":"2026-03-31T15:52:05.828229+00:00","s3_url":"s3:\/\/dev.jiminny.client-data\/5f0f4810-7e77-4086-8f69-93429ae4d70b\/panorama-reports\/test_req_q_1.MD","report_type":"exec_summary","pdf_url":"s3:\/\/dev.jiminny.client-data\/5f0f4810-7e77-4086-8f69-93429ae4d70b\/panorama-reports\/test_req_q_1.pdf"}
[URL_WITH_CREDENTIALS] string
*/
protected $signature = 'automated-reports
{--report-id= : Process a specific report by ID or UUID (bypasses frequency scheduling)}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly).
Use --report-id to manually trigger a specific report by ID or UUID.';
public function __construct(
private readonly LoggerInterface $logger,
private readonly BusDispatcher $dispatcher,
private readonly AutomatedReportsRepository $reportRepository
) {
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle(): int
{
$this->logger->info(self::LOG_PREFIX . ' Started');
$now = Carbon::now();
$isMonday = $now->isMonday();
$isFirstDayOfMonth = $now->day === 1;
$currentMonth = $now->month;
// Check if the current month is a quarterly month (January, April, July, October)
$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);
$this->logger->info(self::LOG_PREFIX . ' Checking conditions', [
'isMonday' => $isMonday,
'isFirstDayOfMonth' => $isFirstDayOfMonth,
'currentMonth' => $currentMonth,
'isQuarterlyMonth' => $isQuarterlyMonth,
]);
// Process daily reports
$this->processReports(AutomatedReportsService::FREQUENCY_DAILY);
// Process weekly reports on Mondays
if ($isMonday) {
$this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);
}
// Process monthly reports on the first day of the month
if ($isFirstDayOfMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);
}
// Process quarterly reports on the first day of January, April, July, and October
if ($isFirstDayOfMonth && $isQuarterlyMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);
}
$this->logger->info(self::LOG_PREFIX . ' Completed');
return 0;
}
/**
* Process reports for a specific frequency.
*
* @param string $frequency
*
* @return void
*/
private function processReports(string $frequency): void
{
$this->logger->info(self::LOG_PREFIX . " Processing $frequency reports");
$reportId = $this->option('report-id');
if ($reportId !== null) {
$reports = $this->getReportById($reportId);
} else {
// Get all enabled, not deleted reports with active teams for the specified frequency
$reports = $this->reportRepository->getActiveReportsByFrequency($frequency);
}
$this->logger->info(self::LOG_PREFIX . " Found {$reports->count()} $frequency reports to process");
/** @var AutomatedReport $report */
foreach ($reports as $report) {
$this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [
'reportUuid' => $report->getUuid(),
'teamId' => $report->getTeamId(),
'frequency' => $report->getFrequency(),
'type' => $report->getType(),
]);
$job = $report->isAskJiminnyReport()
? new RequestGenerateAskJiminnyReportJob($report->getUuid())
: new RequestGenerateReportJob($report->getUuid());
$this->dispatcher->dispatch($job);
}
}
private function getReportById(string $reportId): Collection
{
$report = $this->reportRepository->findByIdOrUuid($reportId);
if ($report === null) {
$this->logger->warning(self::LOG_PREFIX . ' Report not found for --report-id', ['reportId' => $reportId]);
$this->warn("Report not found: {$reportId}");
return collect();
}
if (! $report->getStatus()) {
$this->logger->warning(self::LOG_PREFIX . ' Report is inactive, processing anyway (manual override)', [
'reportId' => $reportId,
'reportUuid' => $report->getUuid(),
]);
$this->warn('Report is inactive — processing anyway (manual override).');
}
$team = $report->getTeam();
if ($team->getStatus() !== Team::STATUS_ACTIVE) {
$this->logger->warning(self::LOG_PREFIX . ' Team is not active, processing anyway (manual override)', [
'reportId' => $reportId,
'reportUuid' => $report->getUuid(),
'teamId' => $report->getTeamId(),
'teamStatus' => $team->getStatus(),
]);
$this->warn("Team #{$report->getTeamId()} is not active — processing anyway (manual override).");
}
if ($report->isExpired()) {
$this->logger->warning(self::LOG_PREFIX . ' Report is expired, processing anyway (manual override)', [
'reportId' => $reportId,
'reportUuid' => $report->getUuid(),
'expiresAt' => $report->getExpiresAt()?->toDateString(),
]);
$this->warn('Report is expired (expires_at: ' . $report->getExpiresAt()?->toDateString() . ') — processing anyway (manual override).');
}
return collect([$report]);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl, folder
ActionItems, folder
Activity, folder
ActivityAnalytics, folder
ActivitySearch, folder...
|
11223
|
|
11227
|
223
|
12
|
2026-04-14T09:20:36.091676+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158436091_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditFV faVsco.s vProjectvO package-loc PhpStormFileEditFV faVsco.s vProjectvO package-lock.jsonE phpstan.neon.dist= phpstan-baseline.neon< phpunit.xmlTaraw_sqlLquery.sqlM+R-ADME,moso sonar-proiect propertiesE test.py<> Untitled Diagram.xmlIs vetur.config.jsM+ WEBHOOK_FILTERING_IMPLEMEI› Ih External Librariesv E° Scratches and Consoles~ D Database ConsolesViewNavigateCodeLaravelRefactorToolsWindowHelp#11894 on JY-18909-automated-reports-ask-jiminny k ~© ReportController.php© JiminnyDebugCommand.php© AutomatedReportsRepository.phpC AutomatedReportsService.php© UserPilotActivityListener.php© ActivityLogged.php© AutomatedReportResult.phpclass AutomatedReportsCommand extends CommandAjiminny@localhost4 console [jiminny@localhost4 DI [jiminny@localhost]c nooca minnvolocanos4 SF [iiminny@localhost]s cono dev minny clocaine> A PRODservices~ D DatabaseV dEUA consolev djiminny@localhostans ocallASF 4 sV A PRODconsoleV A STAGINGsconsole 1s los ms& Docker© AutomatedReportsCommand.php x© AutomatedReportsSendCommand.phpCreateHeldActivityEvent.php• TrackProviderInstalledEvent.php© AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.php© AddLayoutEntities.php© Team.phpCreateActivityLoggedEvent.php© RequestGenerateReportJob.php* Oreturn intpublic function handle(): int58$this->logger->info(self::LOG_PREFIX . ' Started');$now = Carbon: :now();$isMonday = $now->isMonday();$isFirstDay0fMonth = $now->day === 1;$currentMonth = $now->month;// Check if the current month is a quarterly month (January, April, July, October)$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10],strict: true);$this->logger->info(self::LOG_PREFIX' Checking conditions', I"Istonday = $1sMonday,Output8 rowsvDid Yf # 00UO400000pB6fpMAC x5 0,4 QMuvid (UUID with time-low and time-h...JosYodetar-sor-4aos-aos,-so allosdytol266 65671360-459c-4092-9823-ffe013dbc808267 319094f0-7368-4ec1-8f2b-a15b99bb37ec269 d3037407-091e-438a-8c8e-6745c5bf8df9271 09fd931c-117a-47b7-8ccb-abe2e5fe01a1274 6f18db25-c836-4a21-8542-927b3b9f01bf275 ff55bec0-961d-493f-b8fb-dbc2e1d25279276 8617904b-71f4-485f-861c-c045e9cbf2a7Imedia_type Tpdfpdfpdfpdfpdfpdfpdfpdf; status Y• type Y4 ask_jiminny4 ask_jiminny1 ask_jiminny4 ask iiminnv4 ask_jiminny1 ask_jiminny3 ask_jiminny4 ask_J1m1nny, 0Support Daily • in 2h 40 mAAskJiminnyReportActivityServiceT...Defaults v100% C•Tue 14 Apr 12:20:35= custom.logElaravel.logA SF [jiminny@localhost] >4 HS_local [jiminny@localhost]Al console [PROD]A console [EU]Á console [STAGING]© AskJiminnyReportActivityService.php© ActivitySearch.phpc Onbemanavzcontroller.onoC HistoryService.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpRequestGenerateAskJiminnyReportJobTest.phpX:Auto vPlaygroundMa lminnv vIselect * from activities where crm confiquration id = 39 and tvoe = 'conferencel010 A12 V.2 У.4 л179and crm_provider_id IS NOT NULL ORDER by id desc;1180select * from activities where id = 422003; # 00U0400000pB6fpМAC|181182v183184185186SELECT ar.id, ar.uuid, ar.media type, ar.status, a.tvReFbM automated_report_results arJOIN automated_ reports a ON a.ig = ar.repontaidWHERE a.tyRg = 'ask_jiminnx'LIMIT 10;187188f"request_id": "edc47759-160a-4f61-82fc-c8cdf5e55464", "status": "completed", "timestamp" : "2026-03-31T15:52:05.828229-189191s3://dev.jiminny.client-data/5f0f4810-7e77-4086-8f69-93429ae4d70b/panorama-reports/test_req_q_1.MDs3://dev.jiminny.client-data/5f0f4810-7e77-4086-8f69-93429ae4d70b/panorama-reports/test_req_q_1.pdf=• : -CSV8 rows retrieved starting from 1 in 942 ms (execution: 105 ms, fetching: 837 ms)W Windsurf Teams4 spaces...
|
NULL
|
-8083243336204367386
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileEditFV faVsco.s vProjectvO package-loc PhpStormFileEditFV faVsco.s vProjectvO package-lock.jsonE phpstan.neon.dist= phpstan-baseline.neon< phpunit.xmlTaraw_sqlLquery.sqlM+R-ADME,moso sonar-proiect propertiesE test.py<> Untitled Diagram.xmlIs vetur.config.jsM+ WEBHOOK_FILTERING_IMPLEMEI› Ih External Librariesv E° Scratches and Consoles~ D Database ConsolesViewNavigateCodeLaravelRefactorToolsWindowHelp#11894 on JY-18909-automated-reports-ask-jiminny k ~© ReportController.php© JiminnyDebugCommand.php© AutomatedReportsRepository.phpC AutomatedReportsService.php© UserPilotActivityListener.php© ActivityLogged.php© AutomatedReportResult.phpclass AutomatedReportsCommand extends CommandAjiminny@localhost4 console [jiminny@localhost4 DI [jiminny@localhost]c nooca minnvolocanos4 SF [iiminny@localhost]s cono dev minny clocaine> A PRODservices~ D DatabaseV dEUA consolev djiminny@localhostans ocallASF 4 sV A PRODconsoleV A STAGINGsconsole 1s los ms& Docker© AutomatedReportsCommand.php x© AutomatedReportsSendCommand.phpCreateHeldActivityEvent.php• TrackProviderInstalledEvent.php© AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.php© AddLayoutEntities.php© Team.phpCreateActivityLoggedEvent.php© RequestGenerateReportJob.php* Oreturn intpublic function handle(): int58$this->logger->info(self::LOG_PREFIX . ' Started');$now = Carbon: :now();$isMonday = $now->isMonday();$isFirstDay0fMonth = $now->day === 1;$currentMonth = $now->month;// Check if the current month is a quarterly month (January, April, July, October)$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10],strict: true);$this->logger->info(self::LOG_PREFIX' Checking conditions', I"Istonday = $1sMonday,Output8 rowsvDid Yf # 00UO400000pB6fpMAC x5 0,4 QMuvid (UUID with time-low and time-h...JosYodetar-sor-4aos-aos,-so allosdytol266 65671360-459c-4092-9823-ffe013dbc808267 319094f0-7368-4ec1-8f2b-a15b99bb37ec269 d3037407-091e-438a-8c8e-6745c5bf8df9271 09fd931c-117a-47b7-8ccb-abe2e5fe01a1274 6f18db25-c836-4a21-8542-927b3b9f01bf275 ff55bec0-961d-493f-b8fb-dbc2e1d25279276 8617904b-71f4-485f-861c-c045e9cbf2a7Imedia_type Tpdfpdfpdfpdfpdfpdfpdfpdf; status Y• type Y4 ask_jiminny4 ask_jiminny1 ask_jiminny4 ask iiminnv4 ask_jiminny1 ask_jiminny3 ask_jiminny4 ask_J1m1nny, 0Support Daily • in 2h 40 mAAskJiminnyReportActivityServiceT...Defaults v100% C•Tue 14 Apr 12:20:35= custom.logElaravel.logA SF [jiminny@localhost] >4 HS_local [jiminny@localhost]Al console [PROD]A console [EU]Á console [STAGING]© AskJiminnyReportActivityService.php© ActivitySearch.phpc Onbemanavzcontroller.onoC HistoryService.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpRequestGenerateAskJiminnyReportJobTest.phpX:Auto vPlaygroundMa lminnv vIselect * from activities where crm confiquration id = 39 and tvoe = 'conferencel010 A12 V.2 У.4 л179and crm_provider_id IS NOT NULL ORDER by id desc;1180select * from activities where id = 422003; # 00U0400000pB6fpМAC|181182v183184185186SELECT ar.id, ar.uuid, ar.media type, ar.status, a.tvReFbM automated_report_results arJOIN automated_ reports a ON a.ig = ar.repontaidWHERE a.tyRg = 'ask_jiminnx'LIMIT 10;187188f"request_id": "edc47759-160a-4f61-82fc-c8cdf5e55464", "status": "completed", "timestamp" : "2026-03-31T15:52:05.828229-189191s3://dev.jiminny.client-data/5f0f4810-7e77-4086-8f69-93429ae4d70b/panorama-reports/test_req_q_1.MDs3://dev.jiminny.client-data/5f0f4810-7e77-4086-8f69-93429ae4d70b/panorama-reports/test_req_q_1.pdf=• : -CSV8 rows retrieved starting from 1 in 942 ms (execution: 105 ms, fetching: 837 ms)W Windsurf Teams4 spaces...
|
NULL
|
|
11229
|
223
|
13
|
2026-04-14T09:20:38.154258+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158438154_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditFV faVsco.s vProject vO package-lo PhpStormFileEditFV faVsco.s vProject vO package-lock.jsonE phpstan.neon.dist= phpstan-baseline.neon< phpunit.xmlTaraw_sqlLquery.sqlM+R-ADME,moso sonar-proiect propertiesE test.py<> Untitled Diagram.xmlIs vetur.config.jsM+ WEBHOOK_FILTERING_IMPLEMEI› Ih External Librariesv E° Scratches and Consoles~ D Database ConsolesViewNavigateCodeLaravelRefactorToolsWindowHelp#11894 on JY-18909-automated-reports-ask-jiminny k ~© ReportController.php© JiminnyDebugCommand.php© AutomatedReportsRepository.phpC AutomatedReportsService.php© UserPilotActivityListener.php© ActivityLogged.php© AutomatedReportResult.phpclass AutomatedReportsCommand extends CommandAjiminny@localhost4 console [jiminny@localhost4 DI [jiminny@localhost]c nooca minnvolocanos4 SF [iiminny@localhost]s cono dev minny clocaine> A PRODservices~ D DatabaseV dEUA consolev djiminny@localhostansocallASF 4 sV A PRODconsoleV A STAGING&console Is losmsDocker© AutomatedReportsCommand.php x© AutomatedReportsSendCommand.phpCreateHeldActivityEvent.php• TrackProviderInstalledEvent.php© AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.php© AddLayoutEntities.php© Team.phpCreateActivityLoggedEvent.php© RequestGenerateReportJob.php* Oreturn intpublic function handle(): int58$this->logger->info(self::LOG_PREFIX . ' Started');$now = Carbon: :now();$isMonday = $now->isMonday();$isFirstDay0fMonth = $now->day === 1;$currentMonth = $now->month;// Check if the current month is a quarterly month (January, April, July, October)$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10],strict: true);$this->logger->info(self::LOG_PREFIX' Checking conditions', I"Istonday = $1sMonday,Output8 rowsDid Yf # 00UO400000pB6fpMAC x5 0,Muvid (UUID with time-low and time-h...265 926befa2-5d77-4ab3-a553-587a1d5d9$5d166 [CREDIT_CARD]-9895-77001560689%267 319094f0-7368-4ec1-8f2b-a15b99bb37ec269 d3037407-091e-438a-8c8e-6745c5bf8df9271 09fd931c-117a-47b7-8ccb-abe2e5fe01a1274 6f18db25-c836-4a21-8542-927b3b9f01bf275 ff55bec0-961d-493f-b8fb-dbc2e1d25279276 8617904b-71f4-485f-861c-c045e9cbf2a7ID media_type Tpdfpdfpdfpdfpdfpdfpdfpdf÷ Wstatus Y" type Y4 ask_jiminny4 ask_jiminny1 ask_jiminny4 ask iiminnv4 ask_jiminny1 ask_jiminny3 ask_jiminny4 ask iiminny, 0Support Daily • in 2h 40 mAAskJiminnyReportActivityServiceT...Defaults v100% C•Tue 14 Apr 12:20:38= custom.logElaravel.logA SF [jiminny@localhost]4 HS_local [jiminny@localhost]Al console [PROD]A console [EU]Á console [STAGING]© AskJiminnyReportActivityService.php© ActivitySearch.phpc Onbemanavzcontroller.onoC HistoryService.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpRequestGenerateAskJiminnyReportJobTest.phpX:Auto vPlaygroundMa lminnv vIselect * from activities where crm confiquration id = 39 and tvoe = 'conferencel010 A12 V.2 У.4 л179and crm_provider_id IS NOT NULL ORDER by id desc;1180select * from activities where id = 422003; # 00U0400000pB6fpМAC|181182v183184185186SELECT ar.id, ar.uuid, ar.media type, ar.status, a.tvReFbM automated_report_results arJOIN automated_reports a ON a.ig = ar. repontaidWHERE a.tyRg = 'ask_jiminnx'LIMIT 10;187188f"request_id": "edc47759-160a-4f61-82fc-c8cdf5e55464", "status": "completed", "timestamp" : "2026-03-31T15:52:05.828229-189191s3://dev.jiminny.client-data/5f0f4810-7e77-4086-8f69-93429ae4d70b/panorama-reports/test_req_q_1.MDs3://dev.jiminny.client-data/5f0f4810-7e77-4086-8f69-93429ae4d70b/panorama-reports/test_req_q_1.pdf=• : -CSV8 rows retrieved starting from 1 in 942 ms (execution: 105 ms, fetching: 837 ms)SUM: 265 1:1 W Windsurf TeamsUTF-84 spaces...
|
NULL
|
-637619740535269990
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileEditFV faVsco.s vProject vO package-lo PhpStormFileEditFV faVsco.s vProject vO package-lock.jsonE phpstan.neon.dist= phpstan-baseline.neon< phpunit.xmlTaraw_sqlLquery.sqlM+R-ADME,moso sonar-proiect propertiesE test.py<> Untitled Diagram.xmlIs vetur.config.jsM+ WEBHOOK_FILTERING_IMPLEMEI› Ih External Librariesv E° Scratches and Consoles~ D Database ConsolesViewNavigateCodeLaravelRefactorToolsWindowHelp#11894 on JY-18909-automated-reports-ask-jiminny k ~© ReportController.php© JiminnyDebugCommand.php© AutomatedReportsRepository.phpC AutomatedReportsService.php© UserPilotActivityListener.php© ActivityLogged.php© AutomatedReportResult.phpclass AutomatedReportsCommand extends CommandAjiminny@localhost4 console [jiminny@localhost4 DI [jiminny@localhost]c nooca minnvolocanos4 SF [iiminny@localhost]s cono dev minny clocaine> A PRODservices~ D DatabaseV dEUA consolev djiminny@localhostansocallASF 4 sV A PRODconsoleV A STAGING&console Is losmsDocker© AutomatedReportsCommand.php x© AutomatedReportsSendCommand.phpCreateHeldActivityEvent.php• TrackProviderInstalledEvent.php© AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.php© AddLayoutEntities.php© Team.phpCreateActivityLoggedEvent.php© RequestGenerateReportJob.php* Oreturn intpublic function handle(): int58$this->logger->info(self::LOG_PREFIX . ' Started');$now = Carbon: :now();$isMonday = $now->isMonday();$isFirstDay0fMonth = $now->day === 1;$currentMonth = $now->month;// Check if the current month is a quarterly month (January, April, July, October)$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10],strict: true);$this->logger->info(self::LOG_PREFIX' Checking conditions', I"Istonday = $1sMonday,Output8 rowsDid Yf # 00UO400000pB6fpMAC x5 0,Muvid (UUID with time-low and time-h...265 926befa2-5d77-4ab3-a553-587a1d5d9$5d166 [CREDIT_CARD]-9895-77001560689%267 319094f0-7368-4ec1-8f2b-a15b99bb37ec269 d3037407-091e-438a-8c8e-6745c5bf8df9271 09fd931c-117a-47b7-8ccb-abe2e5fe01a1274 6f18db25-c836-4a21-8542-927b3b9f01bf275 ff55bec0-961d-493f-b8fb-dbc2e1d25279276 8617904b-71f4-485f-861c-c045e9cbf2a7ID media_type Tpdfpdfpdfpdfpdfpdfpdfpdf÷ Wstatus Y" type Y4 ask_jiminny4 ask_jiminny1 ask_jiminny4 ask iiminnv4 ask_jiminny1 ask_jiminny3 ask_jiminny4 ask iiminny, 0Support Daily • in 2h 40 mAAskJiminnyReportActivityServiceT...Defaults v100% C•Tue 14 Apr 12:20:38= custom.logElaravel.logA SF [jiminny@localhost]4 HS_local [jiminny@localhost]Al console [PROD]A console [EU]Á console [STAGING]© AskJiminnyReportActivityService.php© ActivitySearch.phpc Onbemanavzcontroller.onoC HistoryService.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpRequestGenerateAskJiminnyReportJobTest.phpX:Auto vPlaygroundMa lminnv vIselect * from activities where crm confiquration id = 39 and tvoe = 'conferencel010 A12 V.2 У.4 л179and crm_provider_id IS NOT NULL ORDER by id desc;1180select * from activities where id = 422003; # 00U0400000pB6fpМAC|181182v183184185186SELECT ar.id, ar.uuid, ar.media type, ar.status, a.tvReFbM automated_report_results arJOIN automated_reports a ON a.ig = ar. repontaidWHERE a.tyRg = 'ask_jiminnx'LIMIT 10;187188f"request_id": "edc47759-160a-4f61-82fc-c8cdf5e55464", "status": "completed", "timestamp" : "2026-03-31T15:52:05.828229-189191s3://dev.jiminny.client-data/5f0f4810-7e77-4086-8f69-93429ae4d70b/panorama-reports/test_req_q_1.MDs3://dev.jiminny.client-data/5f0f4810-7e77-4086-8f69-93429ae4d70b/panorama-reports/test_req_q_1.pdf=• : -CSV8 rows retrieved starting from 1 in 942 ms (execution: 105 ms, fetching: 837 ms)SUM: 265 1:1 W Windsurf TeamsUTF-84 spaces...
|
11227
|
|
11231
|
223
|
14
|
2026-04-14T09:20:47.471864+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158447471_m2.jpg...
|
iTerm2
|
DEV (docker)
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Last login: Sat Apr 11 12:38:35 on ttys006
Poetry Last login: Sat Apr 11 12:38:35 on ttys006
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 (JY-18909-automated-reports-ask-jiminny) $ dev
root@docker_lamp_1:/home/jiminny# php artisan automated-reports
DOCKER
Close Tab
DEV (docker)
Close Tab
APP (-zsh)
Close Tab
ec2-user@ip-10-30-93-249:~ (nc)
Close Tab
-zsh
Close Tab
-zsh
Close Tab
-zsh
Close Tab
✳ Unable to access screenpipe activity data (claude)
Close Tab
⌥⌘1
DEV (docker)...
|
[{"role":"AXTextArea","text [{"role":"AXTextArea","text":"Last login: Sat Apr 11 12:38:35 on ttys006\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 (JY-18909-automated-reports-ask-jiminny) $ dev\nroot@docker_lamp_1:/home/jiminny# php artisan automated-reports","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.5566406,"height":-0.05486107},"value":"Last login: Sat Apr 11 12:38:35 on ttys006\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 (JY-18909-automated-reports-ask-jiminny) $ dev\nroot@docker_lamp_1:/home/jiminny# php artisan automated-reports","is_focused":true},{"role":"AXRadioButton","text":"DOCKER","depth":2,"bounds":{"left":0.23320313,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.23554687,"top":1.0,"width":0.00625,"height":-0.039583325},"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.30234376,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.3046875,"top":1.0,"width":0.00625,"height":-0.039583325},"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.37148437,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.3738281,"top":1.0,"width":0.00625,"height":-0.039583325},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"ec2-user@ip-10-30-93-249:~ (nc)","depth":2,"bounds":{"left":0.440625,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.44296876,"top":1.0,"width":0.00625,"height":-0.039583325},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"-zsh","depth":2,"bounds":{"left":0.5097656,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.5121094,"top":1.0,"width":0.00625,"height":-0.039583325},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"-zsh","depth":2,"bounds":{"left":0.57890624,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.58125,"top":1.0,"width":0.00625,"height":-0.039583325},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"-zsh","depth":2,"bounds":{"left":0.64804685,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.6503906,"top":1.0,"width":0.00625,"height":-0.039583325},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"✳ Unable to access screenpipe activity data (claude)","depth":2,"bounds":{"left":0.7171875,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.71953124,"top":1.0,"width":0.00625,"height":-0.039583325},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"⌥⌘1","depth":1,"bounds":{"left":0.7703125,"top":1.0,"width":0.021875,"height":-0.02013886},"automation_id":"_NS:8","role_description":"text"},{"role":"AXStaticText","text":"DEV (docker)","depth":1,"bounds":{"left":0.496875,"top":1.0,"width":0.03515625,"height":-0.020833373},"role_description":"text"}]...
|
149369918600881871
|
5009021114700230289
|
click
|
accessibility
|
NULL
|
Last login: Sat Apr 11 12:38:35 on ttys006
Poetry Last login: Sat Apr 11 12:38:35 on ttys006
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 (JY-18909-automated-reports-ask-jiminny) $ dev
root@docker_lamp_1:/home/jiminny# php artisan automated-reports
DOCKER
Close Tab
DEV (docker)
Close Tab
APP (-zsh)
Close Tab
ec2-user@ip-10-30-93-249:~ (nc)
Close Tab
-zsh
Close Tab
-zsh
Close Tab
-zsh
Close Tab
✳ Unable to access screenpipe activity data (claude)
Close Tab
⌥⌘1
DEV (docker)...
|
NULL
|
|
11234
|
223
|
15
|
2026-04-14T09:21:01.927486+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158461927_m2.jpg...
|
iTerm2
|
DEV (docker)
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Last login: Sat Apr 11 12:38:35 on ttys006
Poetry Last login: Sat Apr 11 12:38:35 on ttys006
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 (JY-18909-automated-reports-ask-jiminny) $ dev
root@docker_lamp_1:/home/jiminny# php artisan automated-reports 265
No arguments expected for "automated-reports" command, got "265".
root@docker_lamp_1:/home/jiminny#
DOCKER
Close Tab
DEV (docker)
Close Tab
APP (-zsh)
Close Tab
ec2-user@ip-10-30-93-249:~ (nc)
Close Tab
-zsh
Close Tab
-zsh
Close Tab
-zsh
Close Tab
✳ Unable to access screenpipe activity data (claude)
Close Tab
⌥⌘1
DEV (docker)...
|
[{"role":"AXTextArea","text [{"role":"AXTextArea","text":"Last login: Sat Apr 11 12:38:35 on ttys006\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 (JY-18909-automated-reports-ask-jiminny) $ dev\nroot@docker_lamp_1:/home/jiminny# php artisan automated-reports 265\n\n \n No arguments expected for \"automated-reports\" command, got \"265\". \n \n\nroot@docker_lamp_1:/home/jiminny#","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.5566406,"height":-0.05486107},"value":"Last login: Sat Apr 11 12:38:35 on ttys006\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 (JY-18909-automated-reports-ask-jiminny) $ dev\nroot@docker_lamp_1:/home/jiminny# php artisan automated-reports 265\n\n \n No arguments expected for \"automated-reports\" command, got \"265\". \n \n\nroot@docker_lamp_1:/home/jiminny#","is_focused":true},{"role":"AXRadioButton","text":"DOCKER","depth":2,"bounds":{"left":0.23320313,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.23554687,"top":1.0,"width":0.00625,"height":-0.039583325},"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.30234376,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.3046875,"top":1.0,"width":0.00625,"height":-0.039583325},"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.37148437,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.3738281,"top":1.0,"width":0.00625,"height":-0.039583325},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"ec2-user@ip-10-30-93-249:~ (nc)","depth":2,"bounds":{"left":0.440625,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.44296876,"top":1.0,"width":0.00625,"height":-0.039583325},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"-zsh","depth":2,"bounds":{"left":0.5097656,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.5121094,"top":1.0,"width":0.00625,"height":-0.039583325},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"-zsh","depth":2,"bounds":{"left":0.57890624,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.58125,"top":1.0,"width":0.00625,"height":-0.039583325},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"-zsh","depth":2,"bounds":{"left":0.64804685,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.6503906,"top":1.0,"width":0.00625,"height":-0.039583325},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"✳ Unable to access screenpipe activity data (claude)","depth":2,"bounds":{"left":0.7171875,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.71953124,"top":1.0,"width":0.00625,"height":-0.039583325},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"⌥⌘1","depth":1,"bounds":{"left":0.7703125,"top":1.0,"width":0.021875,"height":-0.02013886},"automation_id":"_NS:8","role_description":"text"},{"role":"AXStaticText","text":"DEV (docker)","depth":1,"bounds":{"left":0.496875,"top":1.0,"width":0.03515625,"height":-0.020833373},"role_description":"text"}]...
|
1019121305684409762
|
550527820152130705
|
click
|
accessibility
|
NULL
|
Last login: Sat Apr 11 12:38:35 on ttys006
Poetry Last login: Sat Apr 11 12:38:35 on ttys006
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 (JY-18909-automated-reports-ask-jiminny) $ dev
root@docker_lamp_1:/home/jiminny# php artisan automated-reports 265
No arguments expected for "automated-reports" command, got "265".
root@docker_lamp_1:/home/jiminny#
DOCKER
Close Tab
DEV (docker)
Close Tab
APP (-zsh)
Close Tab
ec2-user@ip-10-30-93-249:~ (nc)
Close Tab
-zsh
Close Tab
-zsh
Close Tab
-zsh
Close Tab
✳ Unable to access screenpipe activity data (claude)
Close Tab
⌥⌘1
DEV (docker)...
|
11231
|
|
11239
|
223
|
16
|
2026-04-14T09:21:33.891329+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158493891_m2.jpg...
|
iTerm2
|
DEV (docker)
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Last login: Sat Apr 11 12:38:35 on ttys006
Poetry Last login: Sat Apr 11 12:38:35 on ttys006
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 (JY-18909-automated-reports-ask-jiminny) $ dev
root@docker_lamp_1:/home/jiminny# php artisan automated-reports 265
No arguments expected for "automated-reports" command, got "265".
root@docker_lamp_1:/home/jiminny# php artisan optimize:clear && supervisorctl restart all
INFO Clearing cached bootstrap files.
config [PASSWORD_DOTS] 41.20ms DONE
cache [PASSWORD_DOTS] 61.54ms DONE
compiled [PASSWORD_DOTS] 3.39ms DONE
events [PASSWORD_DOTS] 5.01ms DONE
routes [PASSWORD_DOTS] 3.37ms DONE
views [PASSWORD_DOTS] 43.92ms DONE
DOCKER
Close Tab
DEV (docker)
Close Tab
APP (-zsh)
Close Tab
ec2-user@ip-10-30-93-249:~ (nc)
Close Tab
-zsh
Close Tab
-zsh
Close Tab
-zsh
Close Tab
✳ Unable to access screenpipe activity data (claude)
Close Tab
⌥⌘1
DEV (docker)...
|
[{"role":"AXTextArea","text [{"role":"AXTextArea","text":"Last login: Sat Apr 11 12:38:35 on ttys006\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 (JY-18909-automated-reports-ask-jiminny) $ dev\nroot@docker_lamp_1:/home/jiminny# php artisan automated-reports 265\n\n \n No arguments expected for \"automated-reports\" command, got \"265\". \n \n\nroot@docker_lamp_1:/home/jiminny# php artisan optimize:clear && supervisorctl restart all\n\n INFO Clearing cached bootstrap files. \n\n config .............................................................................................................................. 41.20ms DONE\n cache ............................................................................................................................... 61.54ms DONE\n compiled ............................................................................................................................. 3.39ms DONE\n events ............................................................................................................................... 5.01ms DONE\n routes ............................................................................................................................... 3.37ms DONE\n views ............................................................................................................................... 43.92ms DONE","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.5566406,"height":-0.05486107},"value":"Last login: Sat Apr 11 12:38:35 on ttys006\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 (JY-18909-automated-reports-ask-jiminny) $ dev\nroot@docker_lamp_1:/home/jiminny# php artisan automated-reports 265\n\n \n No arguments expected for \"automated-reports\" command, got \"265\". \n \n\nroot@docker_lamp_1:/home/jiminny# php artisan optimize:clear && supervisorctl restart all\n\n INFO Clearing cached bootstrap files. \n\n config .............................................................................................................................. 41.20ms DONE\n cache ............................................................................................................................... 61.54ms DONE\n compiled ............................................................................................................................. 3.39ms DONE\n events ............................................................................................................................... 5.01ms DONE\n routes ............................................................................................................................... 3.37ms DONE\n views ............................................................................................................................... 43.92ms DONE","is_focused":true},{"role":"AXRadioButton","text":"DOCKER","depth":2,"bounds":{"left":0.23320313,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.23554687,"top":1.0,"width":0.00625,"height":-0.039583325},"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.30234376,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.3046875,"top":1.0,"width":0.00625,"height":-0.039583325},"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.37148437,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.3738281,"top":1.0,"width":0.00625,"height":-0.039583325},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"ec2-user@ip-10-30-93-249:~ (nc)","depth":2,"bounds":{"left":0.440625,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.44296876,"top":1.0,"width":0.00625,"height":-0.039583325},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"-zsh","depth":2,"bounds":{"left":0.5097656,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.5121094,"top":1.0,"width":0.00625,"height":-0.039583325},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"-zsh","depth":2,"bounds":{"left":0.57890624,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.58125,"top":1.0,"width":0.00625,"height":-0.039583325},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"-zsh","depth":2,"bounds":{"left":0.64804685,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.6503906,"top":1.0,"width":0.00625,"height":-0.039583325},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"✳ Unable to access screenpipe activity data (claude)","depth":2,"bounds":{"left":0.7171875,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.71953124,"top":1.0,"width":0.00625,"height":-0.039583325},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"⌥⌘1","depth":1,"bounds":{"left":0.7703125,"top":1.0,"width":0.021875,"height":-0.02013886},"automation_id":"_NS:8","role_description":"text"},{"role":"AXStaticText","text":"DEV (docker)","depth":1,"bounds":{"left":0.496875,"top":1.0,"width":0.03515625,"height":-0.020833373},"role_description":"text"}]...
|
2997950504001719161
|
5017957912142899863
|
idle
|
accessibility
|
NULL
|
Last login: Sat Apr 11 12:38:35 on ttys006
Poetry Last login: Sat Apr 11 12:38:35 on ttys006
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 (JY-18909-automated-reports-ask-jiminny) $ dev
root@docker_lamp_1:/home/jiminny# php artisan automated-reports 265
No arguments expected for "automated-reports" command, got "265".
root@docker_lamp_1:/home/jiminny# php artisan optimize:clear && supervisorctl restart all
INFO Clearing cached bootstrap files.
config [PASSWORD_DOTS] 41.20ms DONE
cache [PASSWORD_DOTS] 61.54ms DONE
compiled [PASSWORD_DOTS] 3.39ms DONE
events [PASSWORD_DOTS] 5.01ms DONE
routes [PASSWORD_DOTS] 3.37ms DONE
views [PASSWORD_DOTS] 43.92ms DONE
DOCKER
Close Tab
DEV (docker)
Close Tab
APP (-zsh)
Close Tab
ec2-user@ip-10-30-93-249:~ (nc)
Close Tab
-zsh
Close Tab
-zsh
Close Tab
-zsh
Close Tab
✳ Unable to access screenpipe activity data (claude)
Close Tab
⌥⌘1
DEV (docker)...
|
NULL
|
|
11243
|
223
|
17
|
2026-04-14T09:22:04.301728+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158524301_m2.jpg...
|
iTerm2
|
DEV (docker)
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Last login: Sat Apr 11 12:38:35 on ttys006
Poetry Last login: Sat Apr 11 12:38:35 on ttys006
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 (JY-18909-automated-reports-ask-jiminny) $ dev
root@docker_lamp_1:/home/jiminny# php artisan automated-reports 265
No arguments expected for "automated-reports" command, got "265".
root@docker_lamp_1:/home/jiminny# php artisan optimize:clear && supervisorctl restart all
INFO Clearing cached bootstrap files.
config [PASSWORD_DOTS] 41.20ms DONE
cache [PASSWORD_DOTS] 61.54ms DONE
compiled [PASSWORD_DOTS] 3.39ms DONE
events [PASSWORD_DOTS] 5.01ms DONE
routes [PASSWORD_DOTS] 3.37ms DONE
views [PASSWORD_DOTS] 43.92ms DONE
jiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00: stopped
jiminny-worker-processing-2:jiminny-worker-processing-2_00: stopped
jiminny-worker-processing-3:jiminny-worker-processing-3_00: stopped
jiminny-worker-processing-4:jiminny-worker-processing-4_00: stopped
jiminny-worker-processing-5:jiminny-worker-processing-5_00: stopped
worker-analytics:worker-analytics_00: stopped
worker-crm-update:worker-crm-update_00: stopped
worker-download:worker-download_00: stopped
worker-nudges:worker-nudges_00: stopped
worker-emails:worker-emails_00: stopped
worker-crm-sync:worker-crm-sync_00: stopped
jiminny-worker-processing-1:jiminny-worker-processing-1_00: stopped
worker-calendar:worker-calendar_00: stopped
worker-audio:worker-audio_00: stopped
worker-conferences:worker-conferences_00: stopped
worker:worker_00: stopped
worker-es-update:worker-es-update_00: stopped
artisan-schedule:artisan-schedule_00: stopped
artisan-schedule:artisan-schedule_00: started
jiminny-worker-processing-1:jiminny-worker-processing-1_00: started
jiminny-worker-processing-2:jiminny-worker-processing-2_00: started
jiminny-worker-processing-3:jiminny-worker-processing-3_00: started
jiminny-worker-processing-4:jiminny-worker-processing-4_00: started
jiminny-worker-processing-5:jiminny-worker-processing-5_00: started
jiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00: started
worker:worker_00: started
worker-analytics:worker-analytics_00: started
worker-audio:worker-audio_00: started
worker-calendar:worker-calendar_00: started
worker-conferences:worker-conferences_00: started
worker-crm-sync:worker-crm-sync_00: started
worker-crm-update:worker-crm-update_00: started
worker-download:worker-download_00: started
worker-emails:worker-emails_00: started
worker-es-update:worker-es-update_00: started
worker-nudges:worker-nudges_00: started
root@docker_lamp_1:/home/jiminny#
DOCKER
Close Tab
DEV (docker)
Close Tab
APP (-zsh)
Close Tab
ec2-user@ip-10-30-93-249:~ (nc)
Close Tab
-zsh
Close Tab
-zsh
Close Tab
-zsh
Close Tab
✳ Unable to access screenpipe activity data (claude)
Close Tab
⌥⌘1
DEV (docker)...
|
[{"role":"AXTextArea","text [{"role":"AXTextArea","text":"Last login: Sat Apr 11 12:38:35 on ttys006\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 (JY-18909-automated-reports-ask-jiminny) $ dev\nroot@docker_lamp_1:/home/jiminny# php artisan automated-reports 265\n\n \n No arguments expected for \"automated-reports\" command, got \"265\". \n \n\nroot@docker_lamp_1:/home/jiminny# php artisan optimize:clear && supervisorctl restart all\n\n INFO Clearing cached bootstrap files. \n\n config .............................................................................................................................. 41.20ms DONE\n cache ............................................................................................................................... 61.54ms DONE\n compiled ............................................................................................................................. 3.39ms DONE\n events ............................................................................................................................... 5.01ms DONE\n routes ............................................................................................................................... 3.37ms DONE\n views ............................................................................................................................... 43.92ms DONE\n\njiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00: stopped\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\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-emails:worker-emails_00: stopped\nworker-crm-sync:worker-crm-sync_00: stopped\njiminny-worker-processing-1:jiminny-worker-processing-1_00: stopped\nworker-calendar:worker-calendar_00: stopped\nworker-audio:worker-audio_00: stopped\nworker-conferences:worker-conferences_00: stopped\nworker:worker_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\nroot@docker_lamp_1:/home/jiminny#","depth":4,"bounds":{"left":0.23320313,"top":0.8673611,"width":0.5566406,"height":0.13263887},"value":"Last login: Sat Apr 11 12:38:35 on ttys006\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 (JY-18909-automated-reports-ask-jiminny) $ dev\nroot@docker_lamp_1:/home/jiminny# php artisan automated-reports 265\n\n \n No arguments expected for \"automated-reports\" command, got \"265\". \n \n\nroot@docker_lamp_1:/home/jiminny# php artisan optimize:clear && supervisorctl restart all\n\n INFO Clearing cached bootstrap files. \n\n config .............................................................................................................................. 41.20ms DONE\n cache ............................................................................................................................... 61.54ms DONE\n compiled ............................................................................................................................. 3.39ms DONE\n events ............................................................................................................................... 5.01ms DONE\n routes ............................................................................................................................... 3.37ms DONE\n views ............................................................................................................................... 43.92ms DONE\n\njiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00: stopped\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\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-emails:worker-emails_00: stopped\nworker-crm-sync:worker-crm-sync_00: stopped\njiminny-worker-processing-1:jiminny-worker-processing-1_00: stopped\nworker-calendar:worker-calendar_00: stopped\nworker-audio:worker-audio_00: stopped\nworker-conferences:worker-conferences_00: stopped\nworker:worker_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\nroot@docker_lamp_1:/home/jiminny#","is_focused":true},{"role":"AXRadioButton","text":"DOCKER","depth":2,"bounds":{"left":0.23320313,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.23554687,"top":1.0,"width":0.00625,"height":-0.039583325},"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.30234376,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.3046875,"top":1.0,"width":0.00625,"height":-0.039583325},"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.37148437,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.3738281,"top":1.0,"width":0.00625,"height":-0.039583325},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"ec2-user@ip-10-30-93-249:~ (nc)","depth":2,"bounds":{"left":0.440625,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.44296876,"top":1.0,"width":0.00625,"height":-0.039583325},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"-zsh","depth":2,"bounds":{"left":0.5097656,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.5121094,"top":1.0,"width":0.00625,"height":-0.039583325},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"-zsh","depth":2,"bounds":{"left":0.57890624,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.58125,"top":1.0,"width":0.00625,"height":-0.039583325},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"-zsh","depth":2,"bounds":{"left":0.64804685,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.6503906,"top":1.0,"width":0.00625,"height":-0.039583325},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"✳ Unable to access screenpipe activity data (claude)","depth":2,"bounds":{"left":0.7171875,"top":1.0,"width":0.06914063,"height":-0.03680551},"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.71953124,"top":1.0,"width":0.00625,"height":-0.039583325},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"⌥⌘1","depth":1,"bounds":{"left":0.7703125,"top":1.0,"width":0.021875,"height":-0.02013886},"automation_id":"_NS:8","role_description":"text"},{"role":"AXStaticText","text":"DEV (docker)","depth":1,"bounds":{"left":0.496875,"top":1.0,"width":0.03515625,"height":-0.020833373},"role_description":"text"}]...
|
-3276818620804590007
|
405592464249055517
|
idle
|
accessibility
|
NULL
|
Last login: Sat Apr 11 12:38:35 on ttys006
Poetry Last login: Sat Apr 11 12:38:35 on ttys006
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 (JY-18909-automated-reports-ask-jiminny) $ dev
root@docker_lamp_1:/home/jiminny# php artisan automated-reports 265
No arguments expected for "automated-reports" command, got "265".
root@docker_lamp_1:/home/jiminny# php artisan optimize:clear && supervisorctl restart all
INFO Clearing cached bootstrap files.
config [PASSWORD_DOTS] 41.20ms DONE
cache [PASSWORD_DOTS] 61.54ms DONE
compiled [PASSWORD_DOTS] 3.39ms DONE
events [PASSWORD_DOTS] 5.01ms DONE
routes [PASSWORD_DOTS] 3.37ms DONE
views [PASSWORD_DOTS] 43.92ms DONE
jiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00: stopped
jiminny-worker-processing-2:jiminny-worker-processing-2_00: stopped
jiminny-worker-processing-3:jiminny-worker-processing-3_00: stopped
jiminny-worker-processing-4:jiminny-worker-processing-4_00: stopped
jiminny-worker-processing-5:jiminny-worker-processing-5_00: stopped
worker-analytics:worker-analytics_00: stopped
worker-crm-update:worker-crm-update_00: stopped
worker-download:worker-download_00: stopped
worker-nudges:worker-nudges_00: stopped
worker-emails:worker-emails_00: stopped
worker-crm-sync:worker-crm-sync_00: stopped
jiminny-worker-processing-1:jiminny-worker-processing-1_00: stopped
worker-calendar:worker-calendar_00: stopped
worker-audio:worker-audio_00: stopped
worker-conferences:worker-conferences_00: stopped
worker:worker_00: stopped
worker-es-update:worker-es-update_00: stopped
artisan-schedule:artisan-schedule_00: stopped
artisan-schedule:artisan-schedule_00: started
jiminny-worker-processing-1:jiminny-worker-processing-1_00: started
jiminny-worker-processing-2:jiminny-worker-processing-2_00: started
jiminny-worker-processing-3:jiminny-worker-processing-3_00: started
jiminny-worker-processing-4:jiminny-worker-processing-4_00: started
jiminny-worker-processing-5:jiminny-worker-processing-5_00: started
jiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00: started
worker:worker_00: started
worker-analytics:worker-analytics_00: started
worker-audio:worker-audio_00: started
worker-calendar:worker-calendar_00: started
worker-conferences:worker-conferences_00: started
worker-crm-sync:worker-crm-sync_00: started
worker-crm-update:worker-crm-update_00: started
worker-download:worker-download_00: started
worker-emails:worker-emails_00: started
worker-es-update:worker-es-update_00: started
worker-nudges:worker-nudges_00: started
root@docker_lamp_1:/home/jiminny#
DOCKER
Close Tab
DEV (docker)
Close Tab
APP (-zsh)
Close Tab
ec2-user@ip-10-30-93-249:~ (nc)
Close Tab
-zsh
Close Tab
-zsh
Close Tab
-zsh
Close Tab
✳ Unable to access screenpipe activity data (claude)
Close Tab
⌥⌘1
DEV (docker)...
|
11239
|
|
11244
|
223
|
18
|
2026-04-14T09:22:14.029644+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158534029_m2.jpg...
|
PhpStorm
|
faVsco.js – SF [jiminny@localhost]
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…
In-Editor Results
Tx: Auto
Cancel Running Statements
Playground
jiminny
Code changed:
Hide
Sync Changes
Hide This Notification
10
12
2
4
Previous Highlighted Error
Next Highlighted Error
SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o
JOIN activities a ON o.id = a.opportunity_id
WHERE a.crm_configuration_id = 39
AND a.actual_start_time > '2025-10-13'
AND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM activities
WHERE crm_configuration_id = 39 and user_id = 143
and actual_start_time >= '2025-10-13'
AND type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM opportunities WHERE account_id IN (178);
select * from activities where id IN (620137, 620187, 620188, 620189, 620230);
# HS
SELECT * FROM opportunities WHERE id IN (238);
select * from activities where id IN (477,2076);
select * from users;
SELECT COUNT(*) FROM users;
SELECT COUNT(*) FROM activities;
SELECT COUNT(*) FROM opportunities;
UPDATE activities
SET
actual_start_time = '2025-12-19 09:00:00',
actual_end_time = '2025-12-19 10:30:00',
scheduled_start_time = '2025-12-19 09:00:00',
scheduled_end_time = '2025-12-19 10:30:00'
WHERE id IN (407509,407375);
select * from partners;
SELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id
FROM activities
WHERE user_id = 143
AND actual_start_time >= '2025-10-13 00:00:00'
AND actual_start_time <= '2026-01-13 23:59:59'
ORDER BY actual_start_time DESC;
SELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;
SELECT * FROM crm_layouts where crm_configuration_id = 39;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
# lead_id
# account_id 177
# contact_id 3969
# opportunity_id
# stage_id 203
SELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;
SELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'
AND user_id = 143 and actual_start_time >= '2025-10-13';
SELECT * FROM activities a
# JOIN opportunities o ON a.opportunity_id = o.id
WHERE a.crm_configuration_id = 39 AND a.type = 'conference'
and status = 'completed' and recording_state = 'recorded'
and a.actual_start_time >= '2025-10-13'
AND a.user_id = 143
;
select * from leads
where crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310);
SELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198
SELECT * FROM activities WHERE id IN (356001, 356008); # contacts:
SELECT * FROM opportunities WHERE id IN (1707);
SELECT * FROM stages where id IN (204, 198);
SELECT * FROM opportunities WHERE account_id IN (178);
SELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';
SELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal
SELECT * FROM activities where crm_configuration_id = 39
AND opportunity_id IS NULL
AND is_internal = false
and status = 'completed' and recording_state = 'recorded'
AND actual_start_time >= '2025-10-13'
AND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)
# AND lead_id IN (112, 109)
;
SELECT * FROM crm_profiles WHERE user_id = 143;
select * from inboxes; # 212
select * from users where id = 143; # 143
select * from inbox_email_batches where inbox_id = 212
and updated_at >= '2026-01-28 00:00:00' order by id desc;
select * from inbox_emails where inbox_id = 212
and batch_id = 95885 order by id desc;
select * from email_messages where origin_user_id = 143;
select * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';
select * from participants where activity_id = 620247;
select * from crm_profiles where user_id = 143;
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001
select * from transcription where activity_id = 356001; # 6943
select * from ai_prompts where transcription_id = 6943;
SELECT * FROM activity_summary_logs where activity_id = 356001;
SELECT * FROM social_accounts WHERE sociable_id = 143;
# [PASSWORD_DOTS]
SELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;
# 422515 softphone tr. 8100
SELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;
# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS
select * from ai_prompts where transcription_id IN (8100, 7670);
select * from activity_summary_logs where activity_id = 407509;
select * from sidekick_settings;
select * from default_activity_types;
SELECT * FROM contacts WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM leads WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM activity_searches where user_id = 143;
SELECT * FROM groups where team_id = 1;
select * from teams where id = 1;
select * from groups where team_id = 1; # 1150 - 7e75f8025c22
select id, name, group_id, status, deleted_at, email
from users where team_id = 1 order by group_id desc ;
select * from activity_searches where id in (1977, 1978, 1979);
select * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);
select * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277
select * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879
INSERT INTO `activity_search_filters`
(`activity_search_id`, `filter`, `value`) VALUES
(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')
;
select * from crm_configurations where id = 39;
select * from teams where id = 1;
select * from team_features where team_id = 1;
select * from features;
SELECT * FROM activity_searches where id = 1982; # 1981
SELECT * FROM activity_search_filters WHERE activity_search_id = 1982;
SELECT * FROM automated_reports where id = 68;
SELECT * FROM automated_report_results where id = 275;
SELECT * FROM automated_reports order by id desc;
SELECT * FROM automated_report_results order by id desc;
select * from activity_searches where user_id = 143;
select * from ask_anything_prompts;
SELECT * FROM groups WHERE id = 1439;
SELECT * FROM users WHERE group_id = 1439;
select * from permissions; # 158
select * from roles;
select * from permission_role
select * from teams where id = 1;
select * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;
select * from groups where id = 28;
select * from playbooks where team_id = 1;
select * from playbooks where id = 179;
select * from playbook_categories where id = 1391;
select * from users where id = 143;
select * from crm_profiles where user_id = 143;
select * from activities where crm_configuration_id = 39 and type = 'conference'
and crm_provider_id IS NOT NULL ORDER by id desc;
select * from activities where id = 422003; # 00UO400000pB6fpMAC
SELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type
FROM automated_report_results ar
JOIN automated_reports a ON a.id = ar.report_id
WHERE a.type = 'ask_jiminny'
LIMIT 10;
{"request_id":"edc47759-160a-4f61-82fc-c8cdf5e55464","status":"completed","timestamp":"2026-03-31T15:52:05.828229+00:00","s3_url":"s3:\/\/dev.jiminny.client-data\/5f0f4810-7e77-4086-8f69-93429ae4d70b\/panorama-reports\/test_req_q_1.MD","report_type":"exec_summary","pdf_url":"s3:\/\/dev.jiminny.client-data\/5f0f4810-7e77-4086-8f69-93429ae4d70b\/panorama-reports\/test_req_q_1.pdf"}
s3://dev.jiminny.client-data/5f0f4810-7e77-4086-8f69-93429ae4d70b/panorama-reports/test_req_q_1.MD
s3://dev.jiminny.client-data/5f0f4810-7e77-4086-8f69-93429ae4d70b/panorama-reports/test_req_q_1.pdf...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","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.7589844,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceT…Defaults","depth":6,"bounds":{"left":0.7769531,"top":0.017361112,"width":0.12382813,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Execute","depth":4,"bounds":{"left":0.6171875,"top":0.10763889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Explain Plan","depth":4,"bounds":{"left":0.6273438,"top":0.10763889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Browse Query History","depth":4,"bounds":{"left":0.64023435,"top":0.10763889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"View Parameters","depth":4,"bounds":{"left":0.6503906,"top":0.10763889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open Query Execution Settings…","depth":4,"bounds":{"left":0.6605469,"top":0.10763889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"In-Editor Results","depth":4,"bounds":{"left":0.6734375,"top":0.10763889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tx: Auto","depth":4,"bounds":{"left":0.6863281,"top":0.10763889,"width":0.028515626,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Cancel Running Statements","depth":4,"bounds":{"left":0.7175781,"top":0.10763889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Playground","depth":4,"bounds":{"left":0.73046875,"top":0.10763889,"width":0.034765624,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"jiminny","depth":4,"bounds":{"left":0.9515625,"top":0.10763889,"width":0.033203125,"height":0.016666668},"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.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"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.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"10","depth":4,"bounds":{"left":0.91914064,"top":0.12916666,"width":0.011328125,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"12","depth":4,"bounds":{"left":0.9328125,"top":0.12916666,"width":0.011328125,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.9464844,"top":0.12916666,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.95820314,"top":0.12916666,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.96953124,"top":0.12777779,"width":0.00859375,"height":0.015972223},"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.978125,"top":0.12777779,"width":0.008203125,"height":0.015972223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o\nJOIN activities a ON o.id = a.opportunity_id\nWHERE a.crm_configuration_id = 39\nAND a.actual_start_time > '2025-10-13'\nAND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM activities\nWHERE crm_configuration_id = 39 and user_id = 143\nand actual_start_time >= '2025-10-13'\nAND type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM opportunities WHERE account_id IN (178);\nselect * from activities where id IN (620137, 620187, 620188, 620189, 620230);\n\n# HS\nSELECT * FROM opportunities WHERE id IN (238);\nselect * from activities where id IN (477,2076);\n\nselect * from users;\n\nSELECT COUNT(*) FROM users;\nSELECT COUNT(*) FROM activities;\nSELECT COUNT(*) FROM opportunities;\n\nUPDATE activities\nSET\n actual_start_time = '2025-12-19 09:00:00',\n actual_end_time = '2025-12-19 10:30:00',\n scheduled_start_time = '2025-12-19 09:00:00',\n scheduled_end_time = '2025-12-19 10:30:00'\nWHERE id IN (407509,407375);\n\nselect * from partners;\n\nSELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id\nFROM activities\nWHERE user_id = 143\nAND actual_start_time >= '2025-10-13 00:00:00'\nAND actual_start_time <= '2026-01-13 23:59:59'\nORDER BY actual_start_time DESC;\n\nSELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;\nSELECT * FROM crm_layouts where crm_configuration_id = 39;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\n# lead_id\n# account_id 177\n# contact_id 3969\n# opportunity_id\n# stage_id 203\n\nSELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;\n\nSELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'\nAND user_id = 143 and actual_start_time >= '2025-10-13';\n\nSELECT * FROM activities a\n# JOIN opportunities o ON a.opportunity_id = o.id\nWHERE a.crm_configuration_id = 39 AND a.type = 'conference'\nand status = 'completed' and recording_state = 'recorded'\nand a.actual_start_time >= '2025-10-13'\nAND a.user_id = 143\n;\n\nselect * from leads\nwhere crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707\n\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310);\nSELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198\nSELECT * FROM activities WHERE id IN (356001, 356008); # contacts:\n\nSELECT * FROM opportunities WHERE id IN (1707);\nSELECT * FROM stages where id IN (204, 198);\nSELECT * FROM opportunities WHERE account_id IN (178);\nSELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';\nSELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal\n\nSELECT * FROM activities where crm_configuration_id = 39\nAND opportunity_id IS NULL\nAND is_internal = false\nand status = 'completed' and recording_state = 'recorded'\nAND actual_start_time >= '2025-10-13'\nAND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)\n# AND lead_id IN (112, 109)\n;\n\nSELECT * FROM crm_profiles WHERE user_id = 143;\n\nselect * from inboxes; # 212\nselect * from users where id = 143; # 143\nselect * from inbox_email_batches where inbox_id = 212\nand updated_at >= '2026-01-28 00:00:00' order by id desc;\nselect * from inbox_emails where inbox_id = 212\nand batch_id = 95885 order by id desc;\nselect * from email_messages where origin_user_id = 143;\nselect * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';\nselect * from participants where activity_id = 620247;\n\nselect * from crm_profiles where user_id = 143;\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001\nselect * from transcription where activity_id = 356001; # 6943\nselect * from ai_prompts where transcription_id = 6943;\nSELECT * FROM activity_summary_logs where activity_id = 356001;\n\nSELECT * FROM social_accounts WHERE sociable_id = 143;\n\n# ************************************************************************************\nSELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;\n# 422515 softphone tr. 8100\n\nSELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;\n# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS\n\nselect * from ai_prompts where transcription_id IN (8100, 7670);\nselect * from activity_summary_logs where activity_id = 407509;\n\nselect * from sidekick_settings;\nselect * from default_activity_types;\n\nSELECT * FROM contacts WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\nSELECT * FROM leads WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\n\nSELECT * FROM activity_searches where user_id = 143;\nSELECT * FROM groups where team_id = 1;\n\nselect * from teams where id = 1;\nselect * from groups where team_id = 1; # 1150 - 7e75f8025c22\nselect id, name, group_id, status, deleted_at, email\nfrom users where team_id = 1 order by group_id desc ;\n\nselect * from activity_searches where id in (1977, 1978, 1979);\nselect * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);\nselect * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277\nselect * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879\n\nINSERT INTO `activity_search_filters`\n(`activity_search_id`, `filter`, `value`) VALUES\n(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')\n;\n\nselect * from crm_configurations where id = 39;\n\nselect * from teams where id = 1;\nselect * from team_features where team_id = 1;\nselect * from features;\n\nSELECT * FROM activity_searches where id = 1982; # 1981\nSELECT * FROM activity_search_filters WHERE activity_search_id = 1982;\n\nSELECT * FROM automated_reports where id = 68;\nSELECT * FROM automated_report_results where id = 275;\n\nSELECT * FROM automated_reports order by id desc;\nSELECT * FROM automated_report_results order by id desc;\nselect * from activity_searches where user_id = 143;\nselect * from ask_anything_prompts;\n\nSELECT * FROM groups WHERE id = 1439;\nSELECT * FROM users WHERE group_id = 1439;\n\nselect * from permissions; # 158\nselect * from roles;\nselect * from permission_role\n\nselect * from teams where id = 1;\nselect * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;\nselect * from groups where id = 28;\nselect * from playbooks where team_id = 1;\nselect * from playbooks where id = 179;\nselect * from playbook_categories where id = 1391;\nselect * from users where id = 143;\nselect * from crm_profiles where user_id = 143;\nselect * from activities where crm_configuration_id = 39 and type = 'conference'\nand crm_provider_id IS NOT NULL ORDER by id desc;\nselect * from activities where id = 422003; # 00UO400000pB6fpMAC\n\nSELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type\nFROM automated_report_results ar\nJOIN automated_reports a ON a.id = ar.report_id\nWHERE a.type = 'ask_jiminny'\nLIMIT 10;\n\n{\"request_id\":\"edc47759-160a-4f61-82fc-c8cdf5e55464\",\"status\":\"completed\",\"timestamp\":\"2026-03-31T15:52:05.828229+00:00\",\"s3_url\":\"s3:\\/\\/dev.jiminny.client-data\\/5f0f4810-7e77-4086-8f69-93429ae4d70b\\/panorama-reports\\/test_req_q_1.MD\",\"report_type\":\"exec_summary\",\"pdf_url\":\"s3:\\/\\/dev.jiminny.client-data\\/5f0f4810-7e77-4086-8f69-93429ae4d70b\\/panorama-reports\\/test_req_q_1.pdf\"}\n\ns3://dev.jiminny.client-data/5f0f4810-7e77-4086-8f69-93429ae4d70b/panorama-reports/test_req_q_1.MD\ns3://dev.jiminny.client-data/5f0f4810-7e77-4086-8f69-93429ae4d70b/panorama-reports/test_req_q_1.pdf","depth":4,"value":"SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o\nJOIN activities a ON o.id = a.opportunity_id\nWHERE a.crm_configuration_id = 39\nAND a.actual_start_time > '2025-10-13'\nAND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM activities\nWHERE crm_configuration_id = 39 and user_id = 143\nand actual_start_time >= '2025-10-13'\nAND type IN ('conference', 'softphone-inbound', 'softphone-outbound')\n;\n\nSELECT * FROM opportunities WHERE account_id IN (178);\nselect * from activities where id IN (620137, 620187, 620188, 620189, 620230);\n\n# HS\nSELECT * FROM opportunities WHERE id IN (238);\nselect * from activities where id IN (477,2076);\n\nselect * from users;\n\nSELECT COUNT(*) FROM users;\nSELECT COUNT(*) FROM activities;\nSELECT COUNT(*) FROM opportunities;\n\nUPDATE activities\nSET\n actual_start_time = '2025-12-19 09:00:00',\n actual_end_time = '2025-12-19 10:30:00',\n scheduled_start_time = '2025-12-19 09:00:00',\n scheduled_end_time = '2025-12-19 10:30:00'\nWHERE id IN (407509,407375);\n\nselect * from partners;\n\nSELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id\nFROM activities\nWHERE user_id = 143\nAND actual_start_time >= '2025-10-13 00:00:00'\nAND actual_start_time <= '2026-01-13 23:59:59'\nORDER BY actual_start_time DESC;\n\nSELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;\nSELECT * FROM crm_layouts where crm_configuration_id = 39;\nSELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;\n# lead_id\n# account_id 177\n# contact_id 3969\n# opportunity_id\n# stage_id 203\n\nSELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;\n\nSELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'\nAND user_id = 143 and actual_start_time >= '2025-10-13';\n\nSELECT * FROM activities a\n# JOIN opportunities o ON a.opportunity_id = o.id\nWHERE a.crm_configuration_id = 39 AND a.type = 'conference'\nand status = 'completed' and recording_state = 'recorded'\nand a.actual_start_time >= '2025-10-13'\nAND a.user_id = 143\n;\n\nselect * from leads\nwhere crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707\n\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);\nSELECT * FROM activities WHERE id IN (356013,616188,616202,616310);\nSELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198\nSELECT * FROM activities WHERE id IN (356001, 356008); # contacts:\n\nSELECT * FROM opportunities WHERE id IN (1707);\nSELECT * FROM stages where id IN (204, 198);\nSELECT * FROM opportunities WHERE account_id IN (178);\nSELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';\nSELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal\n\nSELECT * FROM activities where crm_configuration_id = 39\nAND opportunity_id IS NULL\nAND is_internal = false\nand status = 'completed' and recording_state = 'recorded'\nAND actual_start_time >= '2025-10-13'\nAND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)\n# AND lead_id IN (112, 109)\n;\n\nSELECT * FROM crm_profiles WHERE user_id = 143;\n\nselect * from inboxes; # 212\nselect * from users where id = 143; # 143\nselect * from inbox_email_batches where inbox_id = 212\nand updated_at >= '2026-01-28 00:00:00' order by id desc;\nselect * from inbox_emails where inbox_id = 212\nand batch_id = 95885 order by id desc;\nselect * from email_messages where origin_user_id = 143;\nselect * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';\nselect * from participants where activity_id = 620247;\n\nselect * from crm_profiles where user_id = 143;\n\nSELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001\nselect * from transcription where activity_id = 356001; # 6943\nselect * from ai_prompts where transcription_id = 6943;\nSELECT * FROM activity_summary_logs where activity_id = 356001;\n\nSELECT * FROM social_accounts WHERE sociable_id = 143;\n\n# ************************************************************************************\nSELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;\n# 422515 softphone tr. 8100\n\nSELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;\n# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS\n\nselect * from ai_prompts where transcription_id IN (8100, 7670);\nselect * from activity_summary_logs where activity_id = 407509;\n\nselect * from sidekick_settings;\nselect * from default_activity_types;\n\nSELECT * FROM contacts WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\nSELECT * FROM leads WHERE crm_configuration_id = 39 and email = 'm.kogoj@gmx.at';\n\nSELECT * FROM activity_searches where user_id = 143;\nSELECT * FROM groups where team_id = 1;\n\nselect * from teams where id = 1;\nselect * from groups where team_id = 1; # 1150 - 7e75f8025c22\nselect id, name, group_id, status, deleted_at, email\nfrom users where team_id = 1 order by group_id desc ;\n\nselect * from activity_searches where id in (1977, 1978, 1979);\nselect * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);\nselect * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277\nselect * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879\n\nINSERT INTO `activity_search_filters`\n(`activity_search_id`, `filter`, `value`) VALUES\n(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),\n(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')\n;\n\nselect * from crm_configurations where id = 39;\n\nselect * from teams where id = 1;\nselect * from team_features where team_id = 1;\nselect * from features;\n\nSELECT * FROM activity_searches where id = 1982; # 1981\nSELECT * FROM activity_search_filters WHERE activity_search_id = 1982;\n\nSELECT * FROM automated_reports where id = 68;\nSELECT * FROM automated_report_results where id = 275;\n\nSELECT * FROM automated_reports order by id desc;\nSELECT * FROM automated_report_results order by id desc;\nselect * from activity_searches where user_id = 143;\nselect * from ask_anything_prompts;\n\nSELECT * FROM groups WHERE id = 1439;\nSELECT * FROM users WHERE group_id = 1439;\n\nselect * from permissions; # 158\nselect * from roles;\nselect * from permission_role\n\nselect * from teams where id = 1;\nselect * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;\nselect * from groups where id = 28;\nselect * from playbooks where team_id = 1;\nselect * from playbooks where id = 179;\nselect * from playbook_categories where id = 1391;\nselect * from users where id = 143;\nselect * from crm_profiles where user_id = 143;\nselect * from activities where crm_configuration_id = 39 and type = 'conference'\nand crm_provider_id IS NOT NULL ORDER by id desc;\nselect * from activities where id = 422003; # 00UO400000pB6fpMAC\n\nSELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type\nFROM automated_report_results ar\nJOIN automated_reports a ON a.id = ar.report_id\nWHERE a.type = 'ask_jiminny'\nLIMIT 10;\n\n{\"request_id\":\"edc47759-160a-4f61-82fc-c8cdf5e55464\",\"status\":\"completed\",\"timestamp\":\"2026-03-31T15:52:05.828229+00:00\",\"s3_url\":\"s3:\\/\\/dev.jiminny.client-data\\/5f0f4810-7e77-4086-8f69-93429ae4d70b\\/panorama-reports\\/test_req_q_1.MD\",\"report_type\":\"exec_summary\",\"pdf_url\":\"s3:\\/\\/dev.jiminny.client-data\\/5f0f4810-7e77-4086-8f69-93429ae4d70b\\/panorama-reports\\/test_req_q_1.pdf\"}\n\ns3://dev.jiminny.client-data/5f0f4810-7e77-4086-8f69-93429ae4d70b/panorama-reports/test_req_q_1.MD\ns3://dev.jiminny.client-data/5f0f4810-7e77-4086-8f69-93429ae4d70b/panorama-reports/test_req_q_1.pdf","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-5323297815712742799
|
6830445021786150477
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Execute
Explain Plan
Browse Query History
View Parameters
Open Query Execution Settings…
In-Editor Results
Tx: Auto
Cancel Running Statements
Playground
jiminny
Code changed:
Hide
Sync Changes
Hide This Notification
10
12
2
4
Previous Highlighted Error
Next Highlighted Error
SELECT a.id, a.uuid, a.actual_start_time, o.id, o.uuid FROM opportunities o
JOIN activities a ON o.id = a.opportunity_id
WHERE a.crm_configuration_id = 39
AND a.actual_start_time > '2025-10-13'
AND a.type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM activities
WHERE crm_configuration_id = 39 and user_id = 143
and actual_start_time >= '2025-10-13'
AND type IN ('conference', 'softphone-inbound', 'softphone-outbound')
;
SELECT * FROM opportunities WHERE account_id IN (178);
select * from activities where id IN (620137, 620187, 620188, 620189, 620230);
# HS
SELECT * FROM opportunities WHERE id IN (238);
select * from activities where id IN (477,2076);
select * from users;
SELECT COUNT(*) FROM users;
SELECT COUNT(*) FROM activities;
SELECT COUNT(*) FROM opportunities;
UPDATE activities
SET
actual_start_time = '2025-12-19 09:00:00',
actual_end_time = '2025-12-19 10:30:00',
scheduled_start_time = '2025-12-19 09:00:00',
scheduled_end_time = '2025-12-19 10:30:00'
WHERE id IN (407509,407375);
select * from partners;
SELECT id, uuid, type, actual_start_time, user_id, crm_configuration_id
FROM activities
WHERE user_id = 143
AND actual_start_time >= '2025-10-13 00:00:00'
AND actual_start_time <= '2026-01-13 23:59:59'
ORDER BY actual_start_time DESC;
SELECT * FROM activities WHERE uuid_to_bin('78eda160-3086-435f-88a5-bb0c71b6008d') = uuid;
SELECT * FROM crm_layouts where crm_configuration_id = 39;
SELECT * FROM crm_layout_entities WHERE crm_layout_id = 282;
# lead_id
# account_id 177
# contact_id 3969
# opportunity_id
# stage_id 203
SELECT * FROM opportunities WHERE opportunities.crm_configuration_id = id = 282;
SELECT * FROM activities where crm_configuration_id = 39 AND type = 'conference'
AND user_id = 143 and actual_start_time >= '2025-10-13';
SELECT * FROM activities a
# JOIN opportunities o ON a.opportunity_id = o.id
WHERE a.crm_configuration_id = 39 AND a.type = 'conference'
and status = 'completed' and recording_state = 'recorded'
and a.actual_start_time >= '2025-10-13'
AND a.user_id = 143
;
select * from leads
where crm_configuration_id = 39; # 112 -> ac. 178, 109 => op. 1707
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310,407509,407375,356001,356008);
SELECT * FROM activities WHERE id IN (356013,616188,616202,616310);
SELECT * FROM activities WHERE id IN (407509,407375); # leads: 112, 109 | status - 198
SELECT * FROM activities WHERE id IN (356001, 356008); # contacts:
SELECT * FROM opportunities WHERE id IN (1707);
SELECT * FROM stages where id IN (204, 198);
SELECT * FROM opportunities WHERE account_id IN (178);
SELECT * FROM opportunities WHERE crm_configuration_id = 39 AND created_at > '2025-01-01';
SELECT * FROM contacts WHERE account_id IN (178); # 4118 Musaibe, 4448 Ceco Personal
SELECT * FROM activities where crm_configuration_id = 39
AND opportunity_id IS NULL
AND is_internal = false
and status = 'completed' and recording_state = 'recorded'
AND actual_start_time >= '2025-10-13'
AND (lead_id IS NOT NULL OR contact_id IS NOT NULL OR account_id IS NOT NULL)
# AND lead_id IN (112, 109)
;
SELECT * FROM crm_profiles WHERE user_id = 143;
select * from inboxes; # 212
select * from users where id = 143; # 143
select * from inbox_email_batches where inbox_id = 212
and updated_at >= '2026-01-28 00:00:00' order by id desc;
select * from inbox_emails where inbox_id = 212
and batch_id = 95885 order by id desc;
select * from email_messages where origin_user_id = 143;
select * from activities where user_id = 143 and updated_at >= '2026-01-28 00:00:00';
select * from participants where activity_id = 620247;
select * from crm_profiles where user_id = 143;
SELECT * FROM activities WHERE uuid_to_bin('458cf915-b914-4000-b083-5687b32b2956') = uuid; # 356001
select * from transcription where activity_id = 356001; # 6943
select * from ai_prompts where transcription_id = 6943;
SELECT * FROM activity_summary_logs where activity_id = 356001;
SELECT * FROM social_accounts WHERE sociable_id = 143;
# [PASSWORD_DOTS]
SELECT * FROM activities WHERE uuid_to_bin('0164a4fb-cb95-454e-9edd-4d804e4999bd') = uuid;
# 422515 softphone tr. 8100
SELECT * FROM activities WHERE uuid_to_bin('7520add8-8d87-41a5-98e5-fc4edf96f21e') = uuid;
# 407509 conference tr. 7670 crmId: 00UD1000002J9aTMAS
select * from ai_prompts where transcription_id IN (8100, 7670);
select * from activity_summary_logs where activity_id = 407509;
select * from sidekick_settings;
select * from default_activity_types;
SELECT * FROM contacts WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM leads WHERE crm_configuration_id = 39 and email = '[EMAIL]';
SELECT * FROM activity_searches where user_id = 143;
SELECT * FROM groups where team_id = 1;
select * from teams where id = 1;
select * from groups where team_id = 1; # 1150 - 7e75f8025c22
select id, name, group_id, status, deleted_at, email
from users where team_id = 1 order by group_id desc ;
select * from activity_searches where id in (1977, 1978, 1979);
select * from activity_search_filters where activity_search_id IN (1977, 1978, 1979);
select * from activity_search_filters where filter = 'group_id' and value = '443f26b8-8512-437e-a9f9-7e75f8025c22'; # 10268, 10272, 10277
select * from nudges where activity_search_id IN (1977, 1978, 1979); # 877, 878, 879
INSERT INTO `activity_search_filters`
(`activity_search_id`, `filter`, `value`) VALUES
(1977, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1978, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22'),
(1979, 'group_id', '443f26b8-8512-437e-a9f9-7e75f8025c22')
;
select * from crm_configurations where id = 39;
select * from teams where id = 1;
select * from team_features where team_id = 1;
select * from features;
SELECT * FROM activity_searches where id = 1982; # 1981
SELECT * FROM activity_search_filters WHERE activity_search_id = 1982;
SELECT * FROM automated_reports where id = 68;
SELECT * FROM automated_report_results where id = 275;
SELECT * FROM automated_reports order by id desc;
SELECT * FROM automated_report_results order by id desc;
select * from activity_searches where user_id = 143;
select * from ask_anything_prompts;
SELECT * FROM groups WHERE id = 1439;
SELECT * FROM users WHERE group_id = 1439;
select * from permissions; # 158
select * from roles;
select * from permission_role
select * from teams where id = 1;
select * from groups g JOIN playbooks p on g.playbook_id = p.id where g.team_id = 1;
select * from groups where id = 28;
select * from playbooks where team_id = 1;
select * from playbooks where id = 179;
select * from playbook_categories where id = 1391;
select * from users where id = 143;
select * from crm_profiles where user_id = 143;
select * from activities where crm_configuration_id = 39 and type = 'conference'
and crm_provider_id IS NOT NULL ORDER by id desc;
select * from activities where id = 422003; # 00UO400000pB6fpMAC
SELECT ar.id, ar.uuid, ar.media_type, ar.status, a.type
FROM automated_report_results ar
JOIN automated_reports a ON a.id = ar.report_id
WHERE a.type = 'ask_jiminny'
LIMIT 10;
{"request_id":"edc47759-160a-4f61-82fc-c8cdf5e55464","status":"completed","timestamp":"2026-03-31T15:52:05.828229+00:00","s3_url":"s3:\/\/dev.jiminny.client-data\/5f0f4810-7e77-4086-8f69-93429ae4d70b\/panorama-reports\/test_req_q_1.MD","report_type":"exec_summary","pdf_url":"s3:\/\/dev.jiminny.client-data\/5f0f4810-7e77-4086-8f69-93429ae4d70b\/panorama-reports\/test_req_q_1.pdf"}
s3://dev.jiminny.client-data/5f0f4810-7e77-4086-8f69-93429ae4d70b/panorama-reports/test_req_q_1.MD
s3://dev.jiminny.client-data/5f0f4810-7e77-4086-8f69-93429ae4d70b/panorama-reports/test_req_q_1.pdf...
|
NULL
|
|
11246
|
223
|
19
|
2026-04-14T09:22:16.982246+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158536982_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditFV faVsco.s vProject vO package-lo PhpStormFileEditFV faVsco.s vProject vO package-lock.jsonE phpstan.neon.dist= phpstan-baseline.neon< phpunit.xmlTaraw_sqlLquery.sqlM+R-ADME,moso sonar-proiect propertiesE test.py<> Untitled Diagram.xmlIs vetur.config.jsM+ WEBHOOK_FILTERING_IMPLEMEI› Ih External Librariesv E° Scratches and Consoles~ D Database ConsolesViewNavigateCodeLaravelRefactorToolsWindowHelp#11894 on JY-18909-automated-reports-ask-jiminny k ~© ReportController.php© JiminnyDebugCommand.php© AutomatedReportsRepository.phpC AutomatedReportsService.php© UserPilotActivityListener.php© ActivityLogged.php© AutomatedReportResult.phpclass AutomatedReportsCommand extends CommandAjiminny@localhost4 console [jiminny@localhost4 DI [jiminny@localhost]c nooca minnvolocanos4 SF [iiminny@localhost]s cono dev minny clocaine> A PRODservices~ D DatabaseV dEUA consolev djiminny@localhostansocallASF 4 sV A PRODconsoleV A STAGING&console Is losmsDocker© AutomatedReportsCommand.php x© AutomatedReportsSendCommand.phpCreateHeldActivityEvent.php• TrackProviderInstalledEvent.php© AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.php© AddLayoutEntities.php© Team.phpCreateActivityLoggedEvent.php© RequestGenerateReportJob.php* Oreturn intpublic function handle(): int58$this->logger->info(self::LOG_PREFIX . ' Started');$now = Carbon: :now();$isMonday = $now->isMonday();$isFirstDay0fMonth = $now->day === 1;$currentMonth = $now->month;// Check if the current month is a quarterly month (January, April, July, October)$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10],strict: true);$this->logger->info(self::LOG_PREFIX' Checking conditions', I"Istonday = s1sMonday,Output8 rowsDid Yf # 00UO400000pB6fpMAC x5 0,Muvid (UUID with time-low and time-h...265 926befa2-5d77-4ab3-a553-587a1d5d9$5d166 [CREDIT_CARD]-9895-77001560689%267 319094f0-7368-4ec1-8f2b-a15b99bb37ec269 d3037407-091e-438a-8c8e-6745c5bf8df9271 09fd931c-117a-47b7-8ccb-abe2e5fe01a1274 6f18db25-c836-4a21-8542-927b3b9f01bf275 ff55bec0-961d-493f-b8fb-dbc2e1d25279276 8617904b-71f4-485f-861c-c045e9cbf2a7ID media_type Tpdfpdfpdfpdfpdfpdfpdfpdf÷ Wstatus Y" type Y4 ask_jiminny4 ask_jiminny1 ask_jiminny4 ask iiminnv4 ask_jiminny1 ask_jiminny3 ask_jiminny4 ask iiminny, 0Support Daily - in 2h 38mAAskJiminnyReportActivityServiceT...Defaults v100% C•Tue 14 Apr 12:22:16= custom.logElaravel.logA SF [jiminny@localhost]4 HS_local [jiminny@localhost]Al console [PROD]A console [EU]Á console [STAGING]C AskJiminnyReportActivityService.php© ActivitySearch.phpc Onbemanavzcontroller.onoC HistoryService.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpRequestGenerateAskJiminnyReportJobTest.phpX:Auto vPlaygroundMa lminnv vIselect * from activities where crm confiquration id = 39 and tvoe = 'conferencel010 A12 V.2 У.4 л179and crm_provider_id IS NOT NULL ORDER by id desc;1180select * from activities where id = 422003; # 00U0400000pB6fpМAC|181182v183184SELECT ar.id, ar.uid, ar.mediantype, ar.status, a.tyRsFROM automated_report_results arJOIN automated_reports a ON a.ig = ar. repontaidWHERE a.tyRg = 'ask_jiminnx'186LIMIT 10;187188189f"request_id": "edc47759-160a-4f61-82fc-c8cdf5e55464", "status": "completed", "timestamp" : "2026-03-31T15:52:05.828229-191s3://dev.jiminny.client-data/5f0f4810-7e77-4086-8f69-93429ae4d70b/panorama-reports/test_req_q_1.MDs3://dev.jiminny.client-data/5f0f4810-7e77-4086-8f69-93429ae4d70b/panorama-reports/test_req_q_1.pdf=• : -CSV8 rows retrieved starting from 1 in 942 ms (execution: 105 ms, fetching: 837 ms)SUM: 265 1:1 W Windsurf TeamsUTF-84 spaces...
|
NULL
|
-2561865584686653034
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileEditFV faVsco.s vProject vO package-lo PhpStormFileEditFV faVsco.s vProject vO package-lock.jsonE phpstan.neon.dist= phpstan-baseline.neon< phpunit.xmlTaraw_sqlLquery.sqlM+R-ADME,moso sonar-proiect propertiesE test.py<> Untitled Diagram.xmlIs vetur.config.jsM+ WEBHOOK_FILTERING_IMPLEMEI› Ih External Librariesv E° Scratches and Consoles~ D Database ConsolesViewNavigateCodeLaravelRefactorToolsWindowHelp#11894 on JY-18909-automated-reports-ask-jiminny k ~© ReportController.php© JiminnyDebugCommand.php© AutomatedReportsRepository.phpC AutomatedReportsService.php© UserPilotActivityListener.php© ActivityLogged.php© AutomatedReportResult.phpclass AutomatedReportsCommand extends CommandAjiminny@localhost4 console [jiminny@localhost4 DI [jiminny@localhost]c nooca minnvolocanos4 SF [iiminny@localhost]s cono dev minny clocaine> A PRODservices~ D DatabaseV dEUA consolev djiminny@localhostansocallASF 4 sV A PRODconsoleV A STAGING&console Is losmsDocker© AutomatedReportsCommand.php x© AutomatedReportsSendCommand.phpCreateHeldActivityEvent.php• TrackProviderInstalledEvent.php© AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.php© AddLayoutEntities.php© Team.phpCreateActivityLoggedEvent.php© RequestGenerateReportJob.php* Oreturn intpublic function handle(): int58$this->logger->info(self::LOG_PREFIX . ' Started');$now = Carbon: :now();$isMonday = $now->isMonday();$isFirstDay0fMonth = $now->day === 1;$currentMonth = $now->month;// Check if the current month is a quarterly month (January, April, July, October)$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10],strict: true);$this->logger->info(self::LOG_PREFIX' Checking conditions', I"Istonday = s1sMonday,Output8 rowsDid Yf # 00UO400000pB6fpMAC x5 0,Muvid (UUID with time-low and time-h...265 926befa2-5d77-4ab3-a553-587a1d5d9$5d166 [CREDIT_CARD]-9895-77001560689%267 319094f0-7368-4ec1-8f2b-a15b99bb37ec269 d3037407-091e-438a-8c8e-6745c5bf8df9271 09fd931c-117a-47b7-8ccb-abe2e5fe01a1274 6f18db25-c836-4a21-8542-927b3b9f01bf275 ff55bec0-961d-493f-b8fb-dbc2e1d25279276 8617904b-71f4-485f-861c-c045e9cbf2a7ID media_type Tpdfpdfpdfpdfpdfpdfpdfpdf÷ Wstatus Y" type Y4 ask_jiminny4 ask_jiminny1 ask_jiminny4 ask iiminnv4 ask_jiminny1 ask_jiminny3 ask_jiminny4 ask iiminny, 0Support Daily - in 2h 38mAAskJiminnyReportActivityServiceT...Defaults v100% C•Tue 14 Apr 12:22:16= custom.logElaravel.logA SF [jiminny@localhost]4 HS_local [jiminny@localhost]Al console [PROD]A console [EU]Á console [STAGING]C AskJiminnyReportActivityService.php© ActivitySearch.phpc Onbemanavzcontroller.onoC HistoryService.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpRequestGenerateAskJiminnyReportJobTest.phpX:Auto vPlaygroundMa lminnv vIselect * from activities where crm confiquration id = 39 and tvoe = 'conferencel010 A12 V.2 У.4 л179and crm_provider_id IS NOT NULL ORDER by id desc;1180select * from activities where id = 422003; # 00U0400000pB6fpМAC|181182v183184SELECT ar.id, ar.uid, ar.mediantype, ar.status, a.tyRsFROM automated_report_results arJOIN automated_reports a ON a.ig = ar. repontaidWHERE a.tyRg = 'ask_jiminnx'186LIMIT 10;187188189f"request_id": "edc47759-160a-4f61-82fc-c8cdf5e55464", "status": "completed", "timestamp" : "2026-03-31T15:52:05.828229-191s3://dev.jiminny.client-data/5f0f4810-7e77-4086-8f69-93429ae4d70b/panorama-reports/test_req_q_1.MDs3://dev.jiminny.client-data/5f0f4810-7e77-4086-8f69-93429ae4d70b/panorama-reports/test_req_q_1.pdf=• : -CSV8 rows retrieved starting from 1 in 942 ms (execution: 105 ms, fetching: 837 ms)SUM: 265 1:1 W Windsurf TeamsUTF-84 spaces...
|
11244
|
|
11248
|
223
|
20
|
2026-04-14T09:22:19.379719+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158539379_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditFV faVsco.s vProject vO package-lo PhpStormFileEditFV faVsco.s vProject vO package-lock.jsonE phpstan.neon.dist= phpstan-baseline.neon< phpunit.xmlTa raw_sql_query.sqlM+R-ADME,moso sonar-proiect propertiesE test.py<> Untitled Diagram.xmlIs vetur.config.jsM+ WEBHOOK_FILTERING_IMPLEMEI› Ih External Librariesv E° Scratches and Consoles~ D Database ConsolesViewNavigateCodeLaravelRefactorToolsWindowHelp( #11894 on JY-18909-automated-reports-ask-jiminny k ~© ReportController.php© JiminnyDebugCommand.php© AutomatedReportsRepository.phpC AutomatedReportsService.php© UserPilotActivityListener.php© ActivityLogged.php© AutomatedReportResult.phpclass AutomatedReportsCommand extends CommandAjiminny@localhost4 console [jiminny@localhost4 DI [jiminny@localhost]c noocaminnvolocanos4 SF [iiminny@localhost]s cono dev minny clocaine> A PRODservices~ D DatabaseV dEUA consolev djiminny@localhostansocallASF 4 sV A PRODconsoleV A STAGING&console Is losms& Docker© AutomatedReportsCommand.php x© AutomatedReportsSendCommand.phpCreateHeldActivityEvent.php• TrackProviderInstalledEvent.php© AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.php© AddLayoutEntities.php© Team.phpCreateActivityLoggedEvent.php© RequestGenerateReportJob.php* Oreturn intpublic function handle(): int58$this->logger->info(self::LOG_PREFIX . ' Started');$now = Carbon: :now();$isMonday = $now->isMonday();$isFirstDay0fMonth = $now->day === 1;$currentMonth = $now->month;// Check if the current month is a quarterly month (January, April, July, October)$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10],strict: true);$this->logger->info(self::LOG_PREFIX' Checking conditions', I"Istonday = $1sMonday,Output8 rowsDid Yf # 00UO400000pB6fpMAC x5 0,Muvid (UUID with time-low and time-h...265 926befa2-5d77-4ab3-a553-587a1d5d9$5d166 [CREDIT_CARD]-9895-77001560689%267 319094f0-7368-4ec1-8f2b-a15b99bb37ec269 d3037407-091e-438a-8c8e-6745c5bf8df9271 09fd931c-117a-47b7-8ccb-abe2e5fe01a1274 6f18db25-c836-4a21-8542-927b3b9f01bf275 ff55bec0-961d-493f-b8fb-dbc2e1d25279276 8617904b-71f4-485f-861c-c045e9cbf2a7I media_type Tpdfpdfpdfpdfpdfpdfpdfpdf; status Y" type Y4 ask_jiminny4 ask_jiminny1 ask_jiminny4 ask iiminnv4 ask_jiminny1 ask_jiminny3 ask_jiminny4 ask_J1m1nny, 0Support Daily - in 2h 38mAAskJiminnyReportActivityServiceT...Defaults v100% C•Tue 14 Apr 12:22:19= custom.logElaravel.logA SF ljiminny@localhost]4 HS_local [jiminny@localhost]Al console [PROD]A console [EU]Á console [STAGING]© AskJiminnyReportActivityService.php© ActivitySearch.phpOnbemanavzcontroller.onoC HistoryService.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpRequestGenerateAskJiminnyReportJobTest.phpX:Auto vPlavaroundvMa lminnv vIselect * from activities where crm confiquration id = 39 and tvoe = 'conferencel010 A12 V.2 У.4 л179and crm_provider_id IS NOT NULL ORDER by id desc;1180select * from activities where id = 422003; # 00U0400000pB6fpМAC|181182v183184SELECT ar.id, ar.wid, ar.mediantype, ar.status, a.tyReFROM automated_report_results arJOIN automated_reports a ON a.ig = ar. repont.idWHERE a.tyRg = 'ask_jiminnx'186LIMIT 10;187188189f"request_id": "edc47759-160a-4f61-82fc-c8cdf5e55464", "status": "completed", "timestamp" : "2026-03-31T15:52:05.828229-191s3://dev.jiminny.client-data/5f0f4810-7e77-4086-8f69-93429ae4d70b/panorama-reports/test_req_q_1.MDs3://dev.jiminny.client-data/5f0f4810-7e77-4086-8f69-93429ae4d70b/panorama-reports/test_req_q_1.pdfCSVTests passed: 1 (13 minutes ago)SUM: 265 1:1 W Windsurf Teams 184:17UTF-84 spa...
|
NULL
|
-1967788352290010493
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormFileEditFV faVsco.s vProject vO package-lo PhpStormFileEditFV faVsco.s vProject vO package-lock.jsonE phpstan.neon.dist= phpstan-baseline.neon< phpunit.xmlTa raw_sql_query.sqlM+R-ADME,moso sonar-proiect propertiesE test.py<> Untitled Diagram.xmlIs vetur.config.jsM+ WEBHOOK_FILTERING_IMPLEMEI› Ih External Librariesv E° Scratches and Consoles~ D Database ConsolesViewNavigateCodeLaravelRefactorToolsWindowHelp( #11894 on JY-18909-automated-reports-ask-jiminny k ~© ReportController.php© JiminnyDebugCommand.php© AutomatedReportsRepository.phpC AutomatedReportsService.php© UserPilotActivityListener.php© ActivityLogged.php© AutomatedReportResult.phpclass AutomatedReportsCommand extends CommandAjiminny@localhost4 console [jiminny@localhost4 DI [jiminny@localhost]c noocaminnvolocanos4 SF [iiminny@localhost]s cono dev minny clocaine> A PRODservices~ D DatabaseV dEUA consolev djiminny@localhostansocallASF 4 sV A PRODconsoleV A STAGING&console Is losms& Docker© AutomatedReportsCommand.php x© AutomatedReportsSendCommand.phpCreateHeldActivityEvent.php• TrackProviderInstalledEvent.php© AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.php© AddLayoutEntities.php© Team.phpCreateActivityLoggedEvent.php© RequestGenerateReportJob.php* Oreturn intpublic function handle(): int58$this->logger->info(self::LOG_PREFIX . ' Started');$now = Carbon: :now();$isMonday = $now->isMonday();$isFirstDay0fMonth = $now->day === 1;$currentMonth = $now->month;// Check if the current month is a quarterly month (January, April, July, October)$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10],strict: true);$this->logger->info(self::LOG_PREFIX' Checking conditions', I"Istonday = $1sMonday,Output8 rowsDid Yf # 00UO400000pB6fpMAC x5 0,Muvid (UUID with time-low and time-h...265 926befa2-5d77-4ab3-a553-587a1d5d9$5d166 [CREDIT_CARD]-9895-77001560689%267 319094f0-7368-4ec1-8f2b-a15b99bb37ec269 d3037407-091e-438a-8c8e-6745c5bf8df9271 09fd931c-117a-47b7-8ccb-abe2e5fe01a1274 6f18db25-c836-4a21-8542-927b3b9f01bf275 ff55bec0-961d-493f-b8fb-dbc2e1d25279276 8617904b-71f4-485f-861c-c045e9cbf2a7I media_type Tpdfpdfpdfpdfpdfpdfpdfpdf; status Y" type Y4 ask_jiminny4 ask_jiminny1 ask_jiminny4 ask iiminnv4 ask_jiminny1 ask_jiminny3 ask_jiminny4 ask_J1m1nny, 0Support Daily - in 2h 38mAAskJiminnyReportActivityServiceT...Defaults v100% C•Tue 14 Apr 12:22:19= custom.logElaravel.logA SF ljiminny@localhost]4 HS_local [jiminny@localhost]Al console [PROD]A console [EU]Á console [STAGING]© AskJiminnyReportActivityService.php© ActivitySearch.phpOnbemanavzcontroller.onoC HistoryService.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpRequestGenerateAskJiminnyReportJobTest.phpX:Auto vPlavaroundvMa lminnv vIselect * from activities where crm confiquration id = 39 and tvoe = 'conferencel010 A12 V.2 У.4 л179and crm_provider_id IS NOT NULL ORDER by id desc;1180select * from activities where id = 422003; # 00U0400000pB6fpМAC|181182v183184SELECT ar.id, ar.wid, ar.mediantype, ar.status, a.tyReFROM automated_report_results arJOIN automated_reports a ON a.ig = ar. repont.idWHERE a.tyRg = 'ask_jiminnx'186LIMIT 10;187188189f"request_id": "edc47759-160a-4f61-82fc-c8cdf5e55464", "status": "completed", "timestamp" : "2026-03-31T15:52:05.828229-191s3://dev.jiminny.client-data/5f0f4810-7e77-4086-8f69-93429ae4d70b/panorama-reports/test_req_q_1.MDs3://dev.jiminny.client-data/5f0f4810-7e77-4086-8f69-93429ae4d70b/panorama-reports/test_req_q_1.pdfCSVTests passed: 1 (13 minutes ago)SUM: 265 1:1 W Windsurf Teams 184:17UTF-84 spa...
|
NULL
|
|
11250
|
223
|
21
|
2026-04-14T09:22:22.701700+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158542701_m2.jpg...
|
PhpStorm
|
faVsco.js – SF [jiminny@localhost]
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","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.7589844,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceT…Defaults","depth":6,"bounds":{"left":0.7769531,"top":0.017361112,"width":0.12382813,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"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.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-6884388984026562300
|
-8636777060039973950
|
click
|
hybrid
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceT…Defaults
Run 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
Debug 'AskJiminnyReportActivityServiceTest.tes…uenceNumberToDisableFirstRequestDefaults'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
PhpStormFileEditFV faVsco.s vProject v=.prettierignore= wino sunrulesphp_ide_helper.phppnpce neloermoces.onepnpalrsani composer.isoni composer.lockdependency-checker.jsonO dev.jsonEids.txt=infection.json.distM-INSALLmdM-INIERNAL WE.nOOK S-IUP.mojiminny_storageMvcenses.meMIMakerleO package-lock.json= phpstan.neon.distE phpstan-baseline.neon<phpunit.xmlTe raw_sql_query.sqlM.README.molsonar-project.properties= test.py<> Untitled Diagram.xmlIs vetur.config.jsM+ WEBHOOK_FILTERING_IMPLEMEI› iib External Librariesv E® Scratches and Consolesv D Database Consoles> A EUv A jiminny@localhostA console [jiminny@localhost4 DI [jiminny@localhost]A HS_local [iminny@localhosA SF [jiminny@localhost]4 zoho_dev [jiminny@localha7CPRODÁ QA> L QAI4 QAI PRODA STAGINGA console [STAGING]A console_1 [STAGING]« uranus [STAGING]ViewNavigateCodeLaravelRefactorToolsWindowHelp#11894 on JY-18909-automated-reports-ask-jiminny k ~© ReportController.phpJiminnybeouecommana.ong© AutomatedReportsCommand.php x© AutomatedReportsRepository.phpC AutomatedReportsService.phpCreateHeldActivityEvent.php© UserPilotActivityListener.php© ActivityLogged.php© AutomatedReportsCallbackService.php© AutomatedReportResult.phpclass AutomatedReportsCommand extends Command© AutomatedReportsSendCommand.php• TrackProviderInstalledEvent.php© RequestGenerateAskJiminnyReportJob.php© AddLayoutEntities.php© Team.phpCreateActivityLoggedEvent.php• RequestGenerateReportJob.php* Oreturn intpublic function handle(): int$this->logger->info(self::LOG_PREFIX . ' Started');$now = Carbon: :now();$isMonday = $now->isMonday();$isFirstDay0fMonth = $now->day === 1;$currentMonth = $now->month;// Check if the current month is a quarterly month (January, April, July, October)$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10],strict: true);$this->logger->info(self::LOG_PREFIX' Checking conditions', I"isrondav"→ $1sronday,'isFirstDay0fMonth'→ $isFirstDay0fMonth,'currentMonth' => $currentMonth,'isQuarterlyMonth' => SisQuarterlyMonth.I);// Process daily reports$this->processReports( frequency: AutomatedReportsService::FREQUENCY_DAILY);// Process weekly reports on Mondaysif ($isMonday) {nunus-›orocesskeoorts, trequency: Auronaredreportsservce..rrcouaNcy weckLyon// Process monthly reports on the first day of the monthif ($isFirstDay0fMonth) {$this->processReports( frequency: AutomatedReportsService: :FREQUENCY_MONTHLY);// Process quarterly reports on the first day of January, April, July, and Octoberif ($isFirstDay0fMonth && $isQuarterLyMonth) {nuns-orocessre.ortsrecuencv:Autolaredrenoriscery..cer.Fk-OUENCY WUARIEKLYservicesv _ DatabasevdtuA consolev&jiminny@localhostc moocallASF 4:V A PRODs consoleV A STAGING4 console 1 s 153 msDockerOutput8 rowsMid Tf # 00UO400000pB6fpMAC500Iuuid UUID with time-low and time-h.265 926befa2-5d77-4ab3-a553-587a1d5d9f5d266 656 [CREDIT_CARD]-5F201500c808267 319094f0-7368-4ec1-8f2b-a15b99bb37ec269 d3037407-091e-438a-8c8e-6745c5bf8df9271 09fd931c-117a-47b7-8ccb-abe2e5fe01a174 [CREDIT_CARD]-8542-927050970101275 ff55bec0-961d-493f-b8fb-dbc2e1d25279T : media_type Y00TipdfpdfpdfpdfpdfI status Y• type Y4 ask jiminny4 ask_jiminny1 ask jiminny4 ask_jiminny4 ask_jiminny1lask jiminnv3 ask_jiminnyTests passed: 1 (13 minutes ago), 0f Support Daily • in 2h 38 mAAsk. JiminnvRenortActivitvServicet..Defaultsv100% C•Tue 14 Apr 12:22:22= custom.log= laravel.logA SF [jiminny@localhost]4 HS_local [jiminny@localhost]Al console [PROD]A console [EU]Á console [STAGING]Аsmnлукеpoнaсiмly serиice.рпр© ActivitySearch.phpcOnbemanavzcontroller.oneC HistoryService.php© FilterDefinitionCollection.php© Criteria.php© AskJiminnyReportActivityServiceTest.phpRequestGenerateAskJiminnyReportJobTest.phpX:Auto vPlaygroundMa lminnv v153SELECT * FROM activity_search_filters WHERE activity_search_id = 1982;010 A12 V.2 У.4 л154155156SELECT * FROM automated_reports where id = 68;SELECT * FROM automated_report_results where id = 275;157158SELECT * FROM automated_reports order by id desc;159SELECT * FROM automated_report_results order by id desc;160select * from activity_searches where user_id = 143;161Iselect * from ask anvthina promots:162163SELECT * FROM groups WHERE id = 1439;164SELECT * FROM users WHERE group_id = 1439;165166select * from permissions; # 158167select * from roles;168select * from permission_role169170171172select * from teams where id = 1;select * from groups g JOIN playbooks p 1.n<→>1: on g.playbook_id = p.id where g.team_id = 1;173174175176select * from playbook_categories where id = 1391;177178179180select * from crm_profiles where user_id = 143;select * from activities where crm_configuration_id = 39 and type ='conference'and crm_provider_id IS NOT NULL ORDER by id desc;select * from activities where id = 422003; # 00U0400000pB6fрМАC181182 v183184SELECT ar.ig, ar.uuig, ar.mediantyke, ar.status, a.LVRSIFROM automated report results anJOINautomated_reports a ON a.id = ar.cepontoid185186LIMIT 10;187188{"request_id": "edc47759-160a-4f61-82fc-c8cdf5e55464", "status": "completed", "timestamp" :"2026-03-31T15:52:05.82822189190|_191s3://dev.jiminny.client-data/5f0f4810-7e77-4086-8f69-93429ae4d70b/panorama-reports/test_req_q_1.MDs3://dev.jiminny.client-data/5f0f4810-7e77-4086-8f69-93429ae4d70b/panorama-reports/test_req_q_1.pdf• : -esVySUM: 265 1:1 W Windsurf Teams184:17 UTF-8 4 spa...
|
11248
|
|
11251
|
223
|
22
|
2026-04-14T09:22:25.874103+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158545874_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileFditViewNavigateCodeLaravelPetactorToo PhpStormFileFditViewNavigateCodeLaravelPetactorToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject v(©) ReportController.php© JiminnyDebugCommand.phpC AutomatedReportsCommand.php XC) AutomatedReportsSendCommand.phpC AddLayoutEntities.php(C) Team.php= custom.loaC AutomatedReportsRepository.phpC AutomatedReportsService.php© CreateHeldActivityEvent.php© TrackProviderInstalledEvent.phpC CreateActivityLoggedEvent.php= hubspot-iournal-poll.loo= laravel.log<» phpunit.xm.Is ttt.js= oauth-private.key© UserPilotActivityListener.php© ActivityLogged.php© AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.php© RequestGenerateReportJob.php(©) AutomatedReportResult.phpclass AutomatedReportsCommand extends Command= oauth-public.key=storage= supervisoro,oid* dreturn intpubuic tunccion nandlel: int"rexceav.sonv Mtests> _ Feature5758$this->logger->info(self::LOG_PREFIX . ' Started');> Integration$now = Carbon::nowO:› _ ServicesW Unit>D Actions_ component$isMonday = Snow->isMondayO:SisFirstDay0fMonth = Snow->day === 1:$currentMonth = Snow->month;_ contigurationM ConsoleM ContractsM DomainMDTOEnums_Events• ExceptionsO fixturesHelpersHttp_ Integrations/ Check if the current month is a quarterly month (January, April, July, Uctober)s1sQuarterlyMonth = 1n_array($currentMonth, l1, 4, 7, 10J,strict: true)фuhis->logger->inro(selt::LUG_PREFLX •' Checking conditions', ["Istonday = s1sMonday,'isFirstDav0fMonth'= SisFirstdayutMonch,'currentMonth' => ScurrentMonth.'isQuarterlyMonth' => SisQuarterlyMonth.D :/ Process danly reportssthis->processReports trequency: AutomatedReportsservice::FREQUENCY_DAILYJ*_Interactionsv D Jobs>_ActivityM AiAutomation>M Audio// Process weekly reporus on MondaysIt (p1sMlonday)nunus-›orocesskeoorts, trequency: Auronaredreportsservce..rrcouaNcy weckLyonv _ AutomatedReports©) CreateResultsTest.p©) RequestGenerateAsh// Process monthly reports on the first day of the monthif SisFirstDay0fMonth)(C) RequestGenerateRersthis->processReports( frequency: AutomatedReportsService::FREQUENCY_MONTHLY):(c) SendReportJobTest.(ch SendRenortMailJobtcallendari1erm/ Process quarterly reports on the first day of January, April, July, and Uctoberif ($isFirstDay0fMonth && $isQuarterlyMonth) {DealRisksSnuns-orocessreoortsrecuencv: Autolaredke.ortscery ce.trk-ouENeY WUAKlEKLY|MalloOXM StreaminaselvicesТОGЛU Output:OOU0400000036t0MAC Xv DatabaseV AEU8 rowsvDid YDuuid (UUID with time-low and time-h.. Y : media_type YWstatus VW type uc consoev diminny@localhost265 926befa2-5d77-4ab3-a553-587a1d5d9f5ds ho local4SF 4 gV L PRODd consolev ¿ STAGNGpatodf4 ask jiminny266 656713b0-459c-4094-9823-ffe013dbc8084 ask iininnv26/ 319094f0-7368-4eC1-8f2b-a15b99bb5/ec269 d3037407-091e-438a-8c8e-6745c5bf8df9271 09fd931c-117a-47b7-8ccb-abe2e5fe01a124 01 00029-0050-4841-0342-7205070101d console 1s 153 ms,, Docker275 ff55bec0-961d-495f-b8fb-dbc2e1d252/9pdfpdfpdfpdfpdf1 ask_jiminny4 ask Timinny4 ask jiminny1 ask_jiminny3 ask_J1m1nnylests passed: 1 (13 minutes ago)Suobort Dailv • in 2h 38mTve 14 Aor12:22:25= custom.log#concole f.unl4 console [STAGING]C HistoryService.php(Ch RequestGenerateAsk.liminnvRenort.JohTest.nhoThe file size (7.86 MB) exceeds the configured limit (2.56 MB). Code insight features are not available.IZUZo-VFe Urarzol Tocur arror Tcncoyo cedrorenanaoer veneraqmo access corenr mode Tеdai12789147858ZY80Y298602986129862298652986629864780047807278/0ZY8/29872298732987429875298762987729878298791478802988129882298832988429888298892989014020-04-14 07.4120 LOCOL. LNrUrSocialAccountServicel Refreshing token from provider {"socialA12026-04-14 09:21:281 Zocal.ERROR: Failed to refresh HubSpot token {"account id":306.2026-04-14 09:21:28 local.INFO:Trying to refresh HubSpot token "account_ id":13722026-04-14 09:21:28 local.INFO:EncryptedTokenManager Generating access token. "mode":"Le2026-04-14SocialAccountService Refreshing token from provider12026-04-1409.91.90 ocal FRROr• SaTled to nornach Huhsnot token C'account 101.152)12026-04-14ncai Mner. Renainind Huhsnot tokens end c"totalles "tiyedied.n12026-04-14LocaL.INFO: Jiminny Console\Commands \Command::run Memory usage before starting command 1"17070-04-14Jiminny \console commands command::run Memory usage berore staruing command ?1070-04-1409:21:391|Jiminny\consoLe commanas (command::run Memory usage for commana i"command"."J1Г2026-04-1409:21:391Huosoor Journal rouunol bertno ottser tron caranase -"oti12026-04-1409:21:391 ZocalCommandl Starting polling service12026-04-14 09:21:391 ZocalPollinal Service starting {"me[2026-04-14 09:21:391Pollingl Acquired polling lock {"expi2026-04-14 09:21:39]Polling Getting offset from database2026-04-14 09:21:39]API. Fetching latest journal entry "urlmLuos. dol.nuvdo.L2026-04-14 09:21:39JAuth Requesting new client credentials token12026-04-14 09:21:39Jand• • nun Memony ucade Fon commandl[2026-04-14 09:21:39]Tocal. INF0:[HubSpot JournalAuth] Successfullyoptained new access token {"expires_in":18L2026-04-14 09:21:59J local. INF0:Hubsoot JournalPoluino No data{"correlation id"."316142e2-a958-41a5-8eef.[2026-04-14 09:21:441 Zocal. TNF0:Huosoor dournaliPollinal Getting offset from database[2026-04-14 09:21:441 Zocal. TNF0:Huosoor dournalirerchne arest ournal entryToS:ao.nuoaon12026-04-14 09:21:441 Zocal. INF0:HubSpot Journal2e2-a958-41a5-8eef-12026-04-14 09:21:461 Zocal. INF0:Jiminny Console Commands Command::run Memory usage before starting command {"(12026-04-14 09:21:461 Zocal. INF0:Jiminny Console Commands Command:: run Memory usage for command {"command". "crn2026-04-14 09:21:50 local.INFO:HubSpot Journal Polling Getting offset from database "offset":"""Jiminny12026-04-14 09:21:50 local.INFO:HubSpot Journal API. Fetching latest journal entry"url":"https:/api.hubapi2026-04-14 09:21:50 local.INFO:HubSpot JournalL2026-04-14 09:21:52) local.INFO:Jiminny Console \Commands \Command::run Memory usage before starting command 1"c12[PHONE]9-91.52 Ocal TNE0"Jiminny Console \Commands \Command::run Memory usage for command 1"command":"cr.[2026-04-14 09:22:05] Zocal.INF0: [HubSpot Journal Polling] Getting offset from database {"offset":"" "jiminny_Г2026-04-14 09:22:051 Zoca1.TNF0: [HubSpot Journal APTl Fetching latest iournal entry {"ur]"."httos: //ani hubaniГ2026-04-14 09:22-051 Zoca1. TNF0•fHubSpot JournallPolLuine ilSlol4er-ayn8-4la0-seet12026-04-14 09:22:151 Zocal. INF0:Commands/AsyncUpdateEsEntitiesl Starting ESupdate worker {"pid":37760. "workCsv | 2 L →| 0, 8W Windsurf Teams 29891:1 UTF-8 ( 4 spa...
|
NULL
|
-8120252217347244867
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileFditViewNavigateCodeLaravelPetactorToo PhpStormFileFditViewNavigateCodeLaravelPetactorToolsWindowHelpFV faVsco.s v#11894 on JY-18909-automated-reports-ask-iminny K vProject v(©) ReportController.php© JiminnyDebugCommand.phpC AutomatedReportsCommand.php XC) AutomatedReportsSendCommand.phpC AddLayoutEntities.php(C) Team.php= custom.loaC AutomatedReportsRepository.phpC AutomatedReportsService.php© CreateHeldActivityEvent.php© TrackProviderInstalledEvent.phpC CreateActivityLoggedEvent.php= hubspot-iournal-poll.loo= laravel.log<» phpunit.xm.Is ttt.js= oauth-private.key© UserPilotActivityListener.php© ActivityLogged.php© AutomatedReportsCallbackService.php© RequestGenerateAskJiminnyReportJob.php© RequestGenerateReportJob.php(©) AutomatedReportResult.phpclass AutomatedReportsCommand extends Command= oauth-public.key=storage= supervisoro,oid* dreturn intpubuic tunccion nandlel: int"rexceav.sonv Mtests> _ Feature5758$this->logger->info(self::LOG_PREFIX . ' Started');> Integration$now = Carbon::nowO:› _ ServicesW Unit>D Actions_ component$isMonday = Snow->isMondayO:SisFirstDay0fMonth = Snow->day === 1:$currentMonth = Snow->month;_ contigurationM ConsoleM ContractsM DomainMDTOEnums_Events• ExceptionsO fixturesHelpersHttp_ Integrations/ Check if the current month is a quarterly month (January, April, July, Uctober)s1sQuarterlyMonth = 1n_array($currentMonth, l1, 4, 7, 10J,strict: true)фuhis->logger->inro(selt::LUG_PREFLX •' Checking conditions', ["Istonday = s1sMonday,'isFirstDav0fMonth'= SisFirstdayutMonch,'currentMonth' => ScurrentMonth.'isQuarterlyMonth' => SisQuarterlyMonth.D :/ Process danly reportssthis->processReports trequency: AutomatedReportsservice::FREQUENCY_DAILYJ*_Interactionsv D Jobs>_ActivityM AiAutomation>M Audio// Process weekly reporus on MondaysIt (p1sMlonday)nunus-›orocesskeoorts, trequency: Auronaredreportsservce..rrcouaNcy weckLyonv _ AutomatedReports©) CreateResultsTest.p©) RequestGenerateAsh// Process monthly reports on the first day of the monthif SisFirstDay0fMonth)(C) RequestGenerateRersthis->processReports( frequency: AutomatedReportsService::FREQUENCY_MONTHLY):(c) SendReportJobTest.(ch SendRenortMailJobtcallendari1erm/ Process quarterly reports on the first day of January, April, July, and Uctoberif ($isFirstDay0fMonth && $isQuarterlyMonth) {DealRisksSnuns-orocessreoortsrecuencv: Autolaredke.ortscery ce.trk-ouENeY WUAKlEKLY|MalloOXM StreaminaselvicesТОGЛU Output:OOU0400000036t0MAC Xv DatabaseV AEU8 rowsvDid YDuuid (UUID with time-low and time-h.. Y : media_type YWstatus VW type uc consoev diminny@localhost265 926befa2-5d77-4ab3-a553-587a1d5d9f5ds ho local4SF 4 gV L PRODd consolev ¿ STAGNGpatodf4 ask jiminny266 656713b0-459c-4094-9823-ffe013dbc8084 ask iininnv26/ 319094f0-7368-4eC1-8f2b-a15b99bb5/ec269 d3037407-091e-438a-8c8e-6745c5bf8df9271 09fd931c-117a-47b7-8ccb-abe2e5fe01a124 01 00029-0050-4841-0342-7205070101d console 1s 153 ms,, Docker275 ff55bec0-961d-495f-b8fb-dbc2e1d252/9pdfpdfpdfpdfpdf1 ask_jiminny4 ask Timinny4 ask jiminny1 ask_jiminny3 ask_J1m1nnylests passed: 1 (13 minutes ago)Suobort Dailv • in 2h 38mTve 14 Aor12:22:25= custom.log#concole f.unl4 console [STAGING]C HistoryService.php(Ch RequestGenerateAsk.liminnvRenort.JohTest.nhoThe file size (7.86 MB) exceeds the configured limit (2.56 MB). Code insight features are not available.IZUZo-VFe Urarzol Tocur arror Tcncoyo cedrorenanaoer veneraqmo access corenr mode Tеdai12789147858ZY80Y298602986129862298652986629864780047807278/0ZY8/29872298732987429875298762987729878298791478802988129882298832988429888298892989014020-04-14 07.4120 LOCOL. LNrUrSocialAccountServicel Refreshing token from provider {"socialA12026-04-14 09:21:281 Zocal.ERROR: Failed to refresh HubSpot token {"account id":306.2026-04-14 09:21:28 local.INFO:Trying to refresh HubSpot token "account_ id":13722026-04-14 09:21:28 local.INFO:EncryptedTokenManager Generating access token. "mode":"Le2026-04-14SocialAccountService Refreshing token from provider12026-04-1409.91.90 ocal FRROr• SaTled to nornach Huhsnot token C'account 101.152)12026-04-14ncai Mner. Renainind Huhsnot tokens end c"totalles "tiyedied.n12026-04-14LocaL.INFO: Jiminny Console\Commands \Command::run Memory usage before starting command 1"17070-04-14Jiminny \console commands command::run Memory usage berore staruing command ?1070-04-1409:21:391|Jiminny\consoLe commanas (command::run Memory usage for commana i"command"."J1Г2026-04-1409:21:391Huosoor Journal rouunol bertno ottser tron caranase -"oti12026-04-1409:21:391 ZocalCommandl Starting polling service12026-04-14 09:21:391 ZocalPollinal Service starting {"me[2026-04-14 09:21:391Pollingl Acquired polling lock {"expi2026-04-14 09:21:39]Polling Getting offset from database2026-04-14 09:21:39]API. Fetching latest journal entry "urlmLuos. dol.nuvdo.L2026-04-14 09:21:39JAuth Requesting new client credentials token12026-04-14 09:21:39Jand• • nun Memony ucade Fon commandl[2026-04-14 09:21:39]Tocal. INF0:[HubSpot JournalAuth] Successfullyoptained new access token {"expires_in":18L2026-04-14 09:21:59J local. INF0:Hubsoot JournalPoluino No data{"correlation id"."316142e2-a958-41a5-8eef.[2026-04-14 09:21:441 Zocal. TNF0:Huosoor dournaliPollinal Getting offset from database[2026-04-14 09:21:441 Zocal. TNF0:Huosoor dournalirerchne arest ournal entryToS:ao.nuoaon12026-04-14 09:21:441 Zocal. INF0:HubSpot Journal2e2-a958-41a5-8eef-12026-04-14 09:21:461 Zocal. INF0:Jiminny Console Commands Command::run Memory usage before starting command {"(12026-04-14 09:21:461 Zocal. INF0:Jiminny Console Commands Command:: run Memory usage for command {"command". "crn2026-04-14 09:21:50 local.INFO:HubSpot Journal Polling Getting offset from database "offset":"""Jiminny12026-04-14 09:21:50 local.INFO:HubSpot Journal API. Fetching latest journal entry"url":"https:/api.hubapi2026-04-14 09:21:50 local.INFO:HubSpot JournalL2026-04-14 09:21:52) local.INFO:Jiminny Console \Commands \Command::run Memory usage before starting command 1"c12[PHONE]9-91.52 Ocal TNE0"Jiminny Console \Commands \Command::run Memory usage for command 1"command":"cr.[2026-04-14 09:22:05] Zocal.INF0: [HubSpot Journal Polling] Getting offset from database {"offset":"" "jiminny_Г2026-04-14 09:22:051 Zoca1.TNF0: [HubSpot Journal APTl Fetching latest iournal entry {"ur]"."httos: //ani hubaniГ2026-04-14 09:22-051 Zoca1. TNF0•fHubSpot JournallPolLuine ilSlol4er-ayn8-4la0-seet12026-04-14 09:22:151 Zocal. INF0:Commands/AsyncUpdateEsEntitiesl Starting ESupdate worker {"pid":37760. "workCsv | 2 L →| 0, 8W Windsurf Teams 29891:1 UTF-8 ( 4 spa...
|
NULL
|
|
11254
|
223
|
23
|
2026-04-14T09:22:31.960729+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158551960_m2.jpg...
|
Claude
|
Claude
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Close sidebar
Back
Forward
Chat
Cowork
Code
New ch Close sidebar
Back
Forward
Chat
Cowork
Code
New chat
New chat
⇧⌘O
Search
Search
⌘K
Customize
Customize
Chats
Chats
Projects
Projects
Artifacts
Artifacts
Starred
Starred
Bulgarian citizenship application process for EU residents
Bulgarian citizenship application process for EU residents
Dawarich location tracking project
Dawarich location tracking project
Recents Hide
Recents
Hide
Claude API 500 internal server error
Claude API 500 internal server error
More options for Claude API 500 internal server error
Screenpipe query capabilities and usage
Screenpipe query capabilities and usage
eGPU compatibility with Mac mini and Studio
eGPU compatibility with Mac mini and Studio
Understanding OpenRouter API gateway
Understanding OpenRouter API gateway
Screenpipe 14-day retention explained
Screenpipe 14-day retention explained
Reddit homepage feed overview
Reddit homepage feed overview
Docker container not visible in console
Docker container not visible in console
DIA browser RAM configuration
DIA browser RAM configuration
Screenpipe company background
Screenpipe company background
DSK Bank Bulgaria secure investing explained
DSK Bank Bulgaria secure investing explained
Building a comprehensive personal homelab system
Building a comprehensive personal homelab system
Importing Google Timeline data to Owntracks
Importing Google Timeline data to Owntracks
Chromecast remote volume buttons not working
Chromecast remote volume buttons not working
Screenpipe free version guide
Screenpipe free version guide
Self-hosted LLM alternatives to Claude Sonnet
Self-hosted LLM alternatives to Claude Sonnet
Screenpipe database query setup
Screenpipe database query setup
Running screenpipe for free
Running screenpipe for free
Mac Studio network switch setup
Mac Studio network switch setup
Claude extension in Vivaldi browser
Claude extension in Vivaldi browser
General information request
General information request
Red dots on neck causes
Red dots on neck causes
Change approval
Change approval
Querying Screenpipe with Claude AI
Querying Screenpipe with Claude AI
Setting up daily backups in Ugreen NAS
Setting up daily backups in Ugreen NAS
Upcoming reminders
Upcoming reminders
Accessing tools in Open WebUI
Accessing tools in Open WebUI
Laravel issue troubleshooting
Laravel issue troubleshooting
Reminder to take rodný list
Reminder to take rodný list
Setting up reminders in Open WebUI
Setting up reminders in Open WebUI
NAS reverse proxy access issues after UGOS update
NAS reverse proxy access issues after UGOS update
All chats
All chats
Updated to 1.2278.0
Relaunch to apply
Relaunch
Lukas Kovalik, Settings
LK
Lukas Kovalik
Pro plan
Get apps and extensions
Claude API 500 internal server error
Claude API 500 internal server error
More options for Claude API 500 internal server error
what is this in claude code API Error: 500 {"type":"error","error":{"type":"api_error","message":"Internal server error"},"request_id":"req_011Ca224nat8vsw4yXaxtFuR"}
18:39
Retry
Edit
Copy
A 500 Internal Server Error from the Anthropic API means the error is on Anthropic's side, not in your code. It's essentially "something went wrong on our servers."
Common causes:
Transient server hiccup — usually resolves on its own in seconds/minutes
The specific model or feature you're using hit an edge case on the backend
Occasionally happens under high load...
|
[{"role":"AXCheckBox","text [{"role":"AXCheckBox","text":"Close sidebar","depth":11,"bounds":{"left":0.031640626,"top":0.021527778,"width":0.0125,"height":0.022222223},"role_description":"toggle button","subrole":"AXToggleButton","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Back","depth":11,"bounds":{"left":0.045703124,"top":0.021527778,"width":0.0125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Forward","depth":11,"bounds":{"left":0.058984376,"top":0.021527778,"width":0.0125,"height":0.022222223},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Chat","depth":12,"bounds":{"left":0.465625,"top":0.022916667,"width":0.023046875,"height":0.019444445},"role_description":"radio button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Cowork","depth":12,"bounds":{"left":0.48828125,"top":0.022916667,"width":0.0234375,"height":0.019444445},"role_description":"radio button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXRadioButton","text":"Code","depth":12,"bounds":{"left":0.5113281,"top":0.022916667,"width":0.023046875,"height":0.019444445},"role_description":"radio button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"New chat","depth":16,"bounds":{"left":0.003125,"top":0.056944445,"width":0.10585938,"height":0.022222223},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"New chat","depth":18,"bounds":{"left":0.0171875,"top":0.061805554,"width":0.024609376,"height":0.0125},"role_description":"text"},{"role":"AXStaticText","text":"⇧⌘O","depth":17,"bounds":{"left":0.0890625,"top":0.0625,"width":0.012890625,"height":0.010416667},"role_description":"text"},{"role":"AXLink","text":"Search","depth":16,"bounds":{"left":0.003125,"top":0.07986111,"width":0.10585938,"height":0.022222223},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Search","depth":18,"bounds":{"left":0.0171875,"top":0.08472222,"width":0.01796875,"height":0.0125},"role_description":"text"},{"role":"AXStaticText","text":"⌘K","depth":17,"bounds":{"left":0.09414063,"top":0.08541667,"width":0.0078125,"height":0.010416667},"role_description":"text"},{"role":"AXLink","text":"Customize","depth":16,"bounds":{"left":0.003125,"top":0.10208333,"width":0.10585938,"height":0.022222223},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Customize","depth":18,"bounds":{"left":0.0171875,"top":0.10694444,"width":0.027734375,"height":0.0125},"role_description":"text"},{"role":"AXLink","text":"Chats","depth":17,"bounds":{"left":0.003125,"top":0.13611111,"width":0.1015625,"height":0.022222223},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Chats","depth":19,"bounds":{"left":0.0171875,"top":0.14097223,"width":0.015625,"height":0.0125},"role_description":"text"},{"role":"AXLink","text":"Projects","depth":17,"bounds":{"left":0.003125,"top":0.15902779,"width":0.1015625,"height":0.022222223},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Projects","depth":19,"bounds":{"left":0.0171875,"top":0.16388889,"width":0.021484375,"height":0.0125},"role_description":"text"},{"role":"AXLink","text":"Artifacts","depth":17,"bounds":{"left":0.003125,"top":0.18194444,"width":0.1015625,"height":0.022222223},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Artifacts","depth":18,"bounds":{"left":0.0171875,"top":0.18680556,"width":0.023046875,"height":0.0125},"role_description":"text"},{"role":"AXHeading","text":"Starred","depth":18,"bounds":{"left":0.003125,"top":0.21805556,"width":0.1015625,"height":0.016666668},"role_description":"heading"},{"role":"AXStaticText","text":"Starred","depth":19,"bounds":{"left":0.00625,"top":0.21805556,"width":0.016796876,"height":0.010416667},"role_description":"text"},{"role":"AXLink","text":"Bulgarian citizenship application process for EU residents","depth":21,"bounds":{"left":0.003125,"top":0.23472223,"width":0.1015625,"height":0.022222223},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Bulgarian citizenship application process for EU residents","depth":22,"bounds":{"left":0.00625,"top":0.23958333,"width":0.08867188,"height":0.0125},"role_description":"text"},{"role":"AXLink","text":"Dawarich location tracking project","depth":21,"bounds":{"left":0.003125,"top":0.2576389,"width":0.1015625,"height":0.022222223},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Dawarich location tracking project","depth":22,"bounds":{"left":0.00625,"top":0.2625,"width":0.087890625,"height":0.0125},"role_description":"text"},{"role":"AXButton","text":"Recents Hide","depth":18,"bounds":{"left":0.003125,"top":0.29375,"width":0.037890624,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Recents","depth":19,"bounds":{"left":0.00625,"top":0.29375,"width":0.018359374,"height":0.010416667},"role_description":"text"},{"role":"AXStaticText","text":"Hide","depth":19,"bounds":{"left":0.02734375,"top":0.29375,"width":0.010546875,"height":0.010416667},"role_description":"text"},{"role":"AXLink","text":"Claude API 500 internal server error","depth":21,"bounds":{"left":0.003125,"top":0.31041667,"width":0.1015625,"height":0.022222223},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Claude API 500 internal server error","depth":22,"bounds":{"left":0.00625,"top":0.31527779,"width":0.087890625,"height":0.0125},"role_description":"text"},{"role":"AXPopUpButton","text":"More options for Claude API 500 internal server error","depth":22,"bounds":{"left":0.0921875,"top":0.31041667,"width":0.0125,"height":0.022222223},"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Screenpipe query capabilities and usage","depth":21,"bounds":{"left":0.003125,"top":0.33333334,"width":0.1015625,"height":0.022222223},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Screenpipe query capabilities and usage","depth":22,"bounds":{"left":0.00625,"top":0.33819443,"width":0.08632813,"height":0.0125},"role_description":"text"},{"role":"AXLink","text":"eGPU compatibility with Mac mini and Studio","depth":21,"bounds":{"left":0.003125,"top":0.35625,"width":0.1015625,"height":0.022222223},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"eGPU compatibility with Mac mini and Studio","depth":22,"bounds":{"left":0.00625,"top":0.3611111,"width":0.0875,"height":0.0125},"role_description":"text"},{"role":"AXLink","text":"Understanding OpenRouter API gateway","depth":21,"bounds":{"left":0.003125,"top":0.37916666,"width":0.1015625,"height":0.022222223},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Understanding OpenRouter API gateway","depth":22,"bounds":{"left":0.00625,"top":0.38402778,"width":0.0875,"height":0.0125},"role_description":"text"},{"role":"AXLink","text":"Screenpipe 14-day retention explained","depth":21,"bounds":{"left":0.003125,"top":0.40208334,"width":0.1015625,"height":0.022222223},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Screenpipe 14-day retention explained","depth":22,"bounds":{"left":0.00625,"top":0.40694445,"width":0.08867188,"height":0.0125},"role_description":"text"},{"role":"AXLink","text":"Reddit homepage feed overview","depth":21,"bounds":{"left":0.003125,"top":0.425,"width":0.1015625,"height":0.022222223},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Reddit homepage feed overview","depth":22,"bounds":{"left":0.00625,"top":0.4298611,"width":0.08320312,"height":0.0125},"role_description":"text"},{"role":"AXLink","text":"Docker container not visible in console","depth":21,"bounds":{"left":0.003125,"top":0.44791666,"width":0.1015625,"height":0.022222223},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Docker container not visible in console","depth":22,"bounds":{"left":0.00625,"top":0.45277777,"width":0.0875,"height":0.0125},"role_description":"text"},{"role":"AXLink","text":"DIA browser RAM configuration","depth":21,"bounds":{"left":0.003125,"top":0.47083333,"width":0.1015625,"height":0.022222223},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DIA browser RAM configuration","depth":22,"bounds":{"left":0.00625,"top":0.47569445,"width":0.08203125,"height":0.0125},"role_description":"text"},{"role":"AXLink","text":"Screenpipe company background","depth":21,"bounds":{"left":0.003125,"top":0.49375,"width":0.1015625,"height":0.022222223},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Screenpipe company background","depth":22,"bounds":{"left":0.00625,"top":0.49861112,"width":0.08632813,"height":0.0125},"role_description":"text"},{"role":"AXLink","text":"DSK Bank Bulgaria secure investing explained","depth":21,"bounds":{"left":0.003125,"top":0.51666665,"width":0.1015625,"height":0.022222223},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"DSK Bank Bulgaria secure investing explained","depth":22,"bounds":{"left":0.00625,"top":0.52152777,"width":0.08828125,"height":0.0125},"role_description":"text"},{"role":"AXLink","text":"Building a comprehensive personal homelab system","depth":21,"bounds":{"left":0.003125,"top":0.5395833,"width":0.1015625,"height":0.022222223},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Building a comprehensive personal homelab system","depth":22,"bounds":{"left":0.00625,"top":0.54444444,"width":0.08710937,"height":0.0125},"role_description":"text"},{"role":"AXLink","text":"Importing Google Timeline data to Owntracks","depth":21,"bounds":{"left":0.003125,"top":0.5625,"width":0.1015625,"height":0.022222223},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Importing Google Timeline data to Owntracks","depth":22,"bounds":{"left":0.00625,"top":0.5673611,"width":0.0890625,"height":0.0125},"role_description":"text"},{"role":"AXLink","text":"Chromecast remote volume buttons not working","depth":21,"bounds":{"left":0.003125,"top":0.5854167,"width":0.1015625,"height":0.022222223},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Chromecast remote volume buttons not working","depth":22,"bounds":{"left":0.00625,"top":0.5902778,"width":0.0890625,"height":0.0125},"role_description":"text"},{"role":"AXLink","text":"Screenpipe free version guide","depth":21,"bounds":{"left":0.003125,"top":0.60833335,"width":0.1015625,"height":0.022222223},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Screenpipe free version guide","depth":22,"bounds":{"left":0.00625,"top":0.61319447,"width":0.07695313,"height":0.0125},"role_description":"text"},{"role":"AXLink","text":"Self-hosted LLM alternatives to Claude Sonnet","depth":21,"bounds":{"left":0.003125,"top":0.63125,"width":0.1015625,"height":0.022222223},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Self-hosted LLM alternatives to Claude Sonnet","depth":22,"bounds":{"left":0.00625,"top":0.63611114,"width":0.087890625,"height":0.0125},"role_description":"text"},{"role":"AXLink","text":"Screenpipe database query setup","depth":21,"bounds":{"left":0.003125,"top":0.65416664,"width":0.1015625,"height":0.022222223},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Screenpipe database query setup","depth":22,"bounds":{"left":0.00625,"top":0.65902776,"width":0.08671875,"height":0.0125},"role_description":"text"},{"role":"AXLink","text":"Running screenpipe for free","depth":21,"bounds":{"left":0.003125,"top":0.6770833,"width":0.1015625,"height":0.022222223},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Running screenpipe for free","depth":22,"bounds":{"left":0.00625,"top":0.68194443,"width":0.071875,"height":0.0125},"role_description":"text"},{"role":"AXLink","text":"Mac Studio network switch setup","depth":21,"bounds":{"left":0.003125,"top":0.7,"width":0.1015625,"height":0.022222223},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Mac Studio network switch setup","depth":22,"bounds":{"left":0.00625,"top":0.7048611,"width":0.0859375,"height":0.0125},"role_description":"text"},{"role":"AXLink","text":"Claude extension in Vivaldi browser","depth":21,"bounds":{"left":0.003125,"top":0.72291666,"width":0.1015625,"height":0.022222223},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Claude extension in Vivaldi browser","depth":22,"bounds":{"left":0.00625,"top":0.7277778,"width":0.0890625,"height":0.0125},"role_description":"text"},{"role":"AXLink","text":"General information request","depth":21,"bounds":{"left":0.003125,"top":0.74583334,"width":0.1015625,"height":0.022222223},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"General information request","depth":22,"bounds":{"left":0.00625,"top":0.75069445,"width":0.07265625,"height":0.0125},"role_description":"text"},{"role":"AXLink","text":"Red dots on neck causes","depth":21,"bounds":{"left":0.003125,"top":0.76875,"width":0.1015625,"height":0.022222223},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Red dots on neck causes","depth":22,"bounds":{"left":0.00625,"top":0.7736111,"width":0.06367187,"height":0.0125},"role_description":"text"},{"role":"AXLink","text":"Change approval","depth":21,"bounds":{"left":0.003125,"top":0.7916667,"width":0.1015625,"height":0.022222223},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Change approval","depth":22,"bounds":{"left":0.00625,"top":0.7965278,"width":0.04375,"height":0.0125},"role_description":"text"},{"role":"AXLink","text":"Querying Screenpipe with Claude AI","depth":21,"bounds":{"left":0.003125,"top":0.81458336,"width":0.1015625,"height":0.0069444445},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Querying Screenpipe with Claude AI","depth":22,"bounds":{"left":0.00625,"top":0.8194444,"width":0.0890625,"height":0.0020833334},"role_description":"text"},{"role":"AXLink","text":"Setting up daily backups in Ugreen NAS","depth":21,"bounds":{"left":0.003125,"top":0.8208333,"width":0.1015625,"height":0.00069444446},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Setting up daily backups in Ugreen NAS","depth":22,"bounds":{"left":0.00625,"top":0.8208333,"width":0.0875,"height":0.00069444446},"role_description":"text"},{"role":"AXLink","text":"Upcoming reminders","depth":21,"bounds":{"left":0.003125,"top":0.8208333,"width":0.1015625,"height":0.00069444446},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Upcoming reminders","depth":22,"bounds":{"left":0.00625,"top":0.8208333,"width":0.05390625,"height":0.00069444446},"role_description":"text"},{"role":"AXLink","text":"Accessing tools in Open WebUI","depth":21,"bounds":{"left":0.003125,"top":0.8208333,"width":0.1015625,"height":0.00069444446},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Accessing tools in Open WebUI","depth":22,"bounds":{"left":0.00625,"top":0.8208333,"width":0.080078125,"height":0.00069444446},"role_description":"text"},{"role":"AXLink","text":"Laravel issue troubleshooting","depth":21,"bounds":{"left":0.003125,"top":0.8208333,"width":0.1015625,"height":0.00069444446},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Laravel issue troubleshooting","depth":22,"bounds":{"left":0.00625,"top":0.8208333,"width":0.07578125,"height":0.00069444446},"role_description":"text"},{"role":"AXLink","text":"Reminder to take rodný list","depth":21,"bounds":{"left":0.003125,"top":0.8208333,"width":0.1015625,"height":0.00069444446},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Reminder to take rodný list","depth":22,"bounds":{"left":0.00625,"top":0.8208333,"width":0.06914063,"height":0.00069444446},"role_description":"text"},{"role":"AXLink","text":"Setting up reminders in Open WebUI","depth":21,"bounds":{"left":0.003125,"top":0.8208333,"width":0.1015625,"height":0.00069444446},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Setting up reminders in Open WebUI","depth":22,"bounds":{"left":0.00625,"top":0.8208333,"width":0.08671875,"height":0.00069444446},"role_description":"text"},{"role":"AXLink","text":"NAS reverse proxy access issues after UGOS update","depth":21,"bounds":{"left":0.003125,"top":0.8208333,"width":0.1015625,"height":0.00069444446},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"NAS reverse proxy access issues after UGOS update","depth":22,"bounds":{"left":0.00625,"top":0.8208333,"width":0.08710937,"height":0.00069444446},"role_description":"text"},{"role":"AXLink","text":"All chats","depth":19,"bounds":{"left":0.003125,"top":0.8208333,"width":0.1015625,"height":0.00069444446},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"All chats","depth":20,"bounds":{"left":0.01796875,"top":0.8208333,"width":0.022265624,"height":0.00069444446},"role_description":"text"},{"role":"AXStaticText","text":"Updated to 1.2278.0","depth":16,"bounds":{"left":0.03046875,"top":0.8840278,"width":0.051171876,"height":0.0125},"role_description":"text"},{"role":"AXStaticText","text":"Relaunch to apply","depth":16,"bounds":{"left":0.036328126,"top":0.8986111,"width":0.039453126,"height":0.010416667},"role_description":"text"},{"role":"AXButton","text":"Relaunch","depth":16,"bounds":{"left":0.008203125,"top":0.91805553,"width":0.095703125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"Lukas Kovalik, Settings","depth":16,"bounds":{"left":0.0,"top":0.95555556,"width":0.11210938,"height":0.04444444},"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"LK","depth":19,"bounds":{"left":0.009375,"top":0.9701389,"width":0.00859375,"height":0.014583333},"role_description":"text"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":17,"bounds":{"left":0.02578125,"top":0.96597224,"width":0.035546876,"height":0.0125},"role_description":"text"},{"role":"AXStaticText","text":"Pro plan","depth":17,"bounds":{"left":0.02578125,"top":0.9791667,"width":0.01796875,"height":0.010416667},"role_description":"text"},{"role":"AXButton","text":"Get apps and extensions","depth":18,"bounds":{"left":0.08476563,"top":0.96666664,"width":0.0125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Claude API 500 internal server error","depth":14,"bounds":{"left":0.125,"top":0.055555556,"width":0.09882812,"height":0.019444445},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Claude API 500 internal server error","depth":16,"bounds":{"left":0.128125,"top":0.058333334,"width":0.09257813,"height":0.013194445},"role_description":"text"},{"role":"AXPopUpButton","text":"More options for Claude API 500 internal server error","depth":14,"bounds":{"left":0.22421876,"top":0.055555556,"width":0.011328125,"height":0.019444445},"role_description":"pop-up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"what is this in claude code API Error: 500 {\"type\":\"error\",\"error\":{\"type\":\"api_error\",\"message\":\"Internal server error\"},\"request_id\":\"req_011Ca224nat8vsw4yXaxtFuR\"}","depth":19,"bounds":{"left":0.46171874,"top":0.08194444,"width":0.184375,"height":0.00069444446},"role_description":"text"},{"role":"AXStaticText","text":"18:39","depth":17,"bounds":{"left":0.6429688,"top":0.08194444,"width":0.011328125,"height":0.00069444446},"role_description":"text"},{"role":"AXButton","text":"Retry","depth":17,"bounds":{"left":0.65703124,"top":0.08194444,"width":0.012890625,"height":0.00069444446},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Edit","depth":17,"bounds":{"left":0.6695312,"top":0.08194444,"width":0.012890625,"height":0.00069444446},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Copy","depth":17,"bounds":{"left":0.6820313,"top":0.08194444,"width":0.012890625,"height":0.00069444446},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"A 500 Internal Server Error from the Anthropic API means the error is on Anthropic's side, not in your code. It's essentially \"something went wrong on our servers.\"","depth":18,"bounds":{"left":0.41640624,"top":0.08194444,"width":0.259375,"height":0.00069444446},"role_description":"text"},{"role":"AXStaticText","text":"Common causes:","depth":19,"bounds":{"left":0.41640624,"top":0.08194444,"width":0.051171876,"height":0.00069444446},"role_description":"text"},{"role":"AXStaticText","text":"Transient server hiccup — usually resolves on its own in seconds/minutes","depth":19,"bounds":{"left":0.42890626,"top":0.08194444,"width":0.21171875,"height":0.00069444446},"role_description":"text"},{"role":"AXStaticText","text":"The specific model or feature you're using hit an edge case on the backend","depth":19,"bounds":{"left":0.42890626,"top":0.08194444,"width":0.21328124,"height":0.00069444446},"role_description":"text"},{"role":"AXStaticText","text":"Occasionally happens under high load","depth":19,"bounds":{"left":0.42890626,"top":0.08194444,"width":0.111328125,"height":0.00069444446},"role_description":"text"}]...
|
-1484847188775537765
|
7788947554462078048
|
visual_change
|
accessibility
|
NULL
|
Close sidebar
Back
Forward
Chat
Cowork
Code
New ch Close sidebar
Back
Forward
Chat
Cowork
Code
New chat
New chat
⇧⌘O
Search
Search
⌘K
Customize
Customize
Chats
Chats
Projects
Projects
Artifacts
Artifacts
Starred
Starred
Bulgarian citizenship application process for EU residents
Bulgarian citizenship application process for EU residents
Dawarich location tracking project
Dawarich location tracking project
Recents Hide
Recents
Hide
Claude API 500 internal server error
Claude API 500 internal server error
More options for Claude API 500 internal server error
Screenpipe query capabilities and usage
Screenpipe query capabilities and usage
eGPU compatibility with Mac mini and Studio
eGPU compatibility with Mac mini and Studio
Understanding OpenRouter API gateway
Understanding OpenRouter API gateway
Screenpipe 14-day retention explained
Screenpipe 14-day retention explained
Reddit homepage feed overview
Reddit homepage feed overview
Docker container not visible in console
Docker container not visible in console
DIA browser RAM configuration
DIA browser RAM configuration
Screenpipe company background
Screenpipe company background
DSK Bank Bulgaria secure investing explained
DSK Bank Bulgaria secure investing explained
Building a comprehensive personal homelab system
Building a comprehensive personal homelab system
Importing Google Timeline data to Owntracks
Importing Google Timeline data to Owntracks
Chromecast remote volume buttons not working
Chromecast remote volume buttons not working
Screenpipe free version guide
Screenpipe free version guide
Self-hosted LLM alternatives to Claude Sonnet
Self-hosted LLM alternatives to Claude Sonnet
Screenpipe database query setup
Screenpipe database query setup
Running screenpipe for free
Running screenpipe for free
Mac Studio network switch setup
Mac Studio network switch setup
Claude extension in Vivaldi browser
Claude extension in Vivaldi browser
General information request
General information request
Red dots on neck causes
Red dots on neck causes
Change approval
Change approval
Querying Screenpipe with Claude AI
Querying Screenpipe with Claude AI
Setting up daily backups in Ugreen NAS
Setting up daily backups in Ugreen NAS
Upcoming reminders
Upcoming reminders
Accessing tools in Open WebUI
Accessing tools in Open WebUI
Laravel issue troubleshooting
Laravel issue troubleshooting
Reminder to take rodný list
Reminder to take rodný list
Setting up reminders in Open WebUI
Setting up reminders in Open WebUI
NAS reverse proxy access issues after UGOS update
NAS reverse proxy access issues after UGOS update
All chats
All chats
Updated to 1.2278.0
Relaunch to apply
Relaunch
Lukas Kovalik, Settings
LK
Lukas Kovalik
Pro plan
Get apps and extensions
Claude API 500 internal server error
Claude API 500 internal server error
More options for Claude API 500 internal server error
what is this in claude code API Error: 500 {"type":"error","error":{"type":"api_error","message":"Internal server error"},"request_id":"req_011Ca224nat8vsw4yXaxtFuR"}
18:39
Retry
Edit
Copy
A 500 Internal Server Error from the Anthropic API means the error is on Anthropic's side, not in your code. It's essentially "something went wrong on our servers."
Common causes:
Transient server hiccup — usually resolves on its own in seconds/minutes
The specific model or feature you're using hit an edge case on the backend
Occasionally happens under high load...
|
11251
|
|
11257
|
223
|
24
|
2026-04-14T09:22:34.994847+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776158554994_m2.jpg...
|
NULL
|
NULL
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormFileEditFV faVsco.s vProject v= custom.loa PhpStormFileEditFV faVsco.s vProject v= custom.loa= hubspot-journal-poll.log= laravel.log< phpunit.xmlIs ttt.js= oauth-private.key= oauth-public.keyE storage= supervisord.pid"rexceav.sonv Mtests> D Feature> D Integration> D ServicesUnit› [ Actions> Component" ConfigurationD ConsoleContractsM DomainO DTOEnumsD Events• ExceptionsO fixturesHelpersD Http> O Integrations_Interactions~ D Jobs>_ActivityM AiAutomation> D Audiov _ AutomatedReports© CreateResultsTest.pl© RequestGenerateAsk© RequestGenerateRer© SendReportJobTest.© SendReportMailJobTcallendarD CrmDealRisksS|MalloOXM StreaminaViewNavigateCodeLaravelRefactorToolsWindowHelp#11894 on JY-18909-automated-reports-ask-jiminny k ~© ReportController.php© JiminnyDebugCommand.php© AutomatedReportsRepository.phpC AutomatedReportsService.php© UserPilotActivityListener.php© ActivityLogged.php© AutomatedReportResult.phpclass AutomatedReportsCommand extends Command© AutomatedReportsCommand.php xCreateHeldActivityEvent.php© AutomatedReportsCallbackService.php© AutomatedReportsSendCommand.php• TrackProviderInstalledEvent.php© RequestGenerateAskJiminnyReportJob.php© AddLayoutEntities.php© Team.phpCreateActivityLoggedEvent.php© RequestGenerateReportJob.php* Oreturn intpublic function handle(): int5758$this->logger->info(self::LOG_PREFIX . ' Started');$now = Carbon: :now();$isMonday = $now->isMonday);$isFirstDay0fMonth = $now->day === 1;$currentMonth = $now->month;// Check if the current month is a quarterly month (January, April, July, October)$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10],strict: true);$this->logger->info(self::LOG_PREFIX' Checking conditions', I"Istonday = s1sMonday,'isFirstDay0fMonth'=> $isFirstDay0fMonth,'currentMonth' => $currentMonth,'isQuarterlyMonth' => $isQuarterlyMonth,I);// Process daily reports$this->processReports( frequency: AutomatedReportsService::FREQUENCY_DAILY);// Process weekly reports on Mondaysif ($isMonday) €nunus-›orocesskeoorts, trequency: Auronaredreportsservce..rrcouaNcy weckLyon// Process monthly reports on the first day of the monthif ($isFirstDay0fMonth) {$this->processReports( frequency: AutomatedReportsService::FREQUENCY_MONTHLY);// Process quarterly reports on the first day of January, April, July, and Octoberif ($isFirstDay0fMonth && $isQuarterlyMonth) {$this->processReports( frequency: AutomatedReportsService::FREQUENCY_QUARTERLY);selvicesv DatabaseV AEUc consoev A jiminny@localhosts ho local4SF 4 sV A PRODA consolev ¿ STAGNG4 console 1 s 153 msDockerOutputDid Y:OOU0400000036t0MAC X8 rowsvG0,0Ouvid (UUID with time-low and time-h.. T ÷ ID media_type T265 926befa2-5d77-4ab3-a553-587a1d5d9f5dpdf266 656713b0-459c-4094-9823-ffe013dbc808pdf26/ 319094f0-7368-4ec1-8f2b-a15b99bb5/ecpdf269 d3037407-091e-438a-8c8e-6745c5bf8df9pdf271 09fd931c-117a-47b7-8ccb-abe2e5fe01a1pdf24 01 00025-0050-4841-0342-72050710101pdf275 ff55bec0-961d-493f-b8fb-dbc2e1d25279pdf• status Y• type Y4 ask_jiminny4 ask iininnv1 ask_jiminny4 ask_jiminny4 ask_jiminny1 ask_jiminny3 ask_jiminnyIne tile size /.80 MB exceeas the conticuSuoport Dailv • in 2h 38mTue 14 Aor 12:22:34= custom.logÁ console [STAGING]© FilterDefinitionCollection.phpE console (EU]© HistoryService.php12789147858ZY80Y298602986129862298662986729868278/6ZY8/298722987329874298752987629877298782987929880298812988229883298842989114787%29893LY0Y4-2989529896The file size (7.86 MB) exceeds the configured limit (2.56 MB). Code insight features are not availableIzUZo-VerUrarzol tocur arror Tcicryocedtoremanqver veneracmo access tokenr mooe теud14020-04-14 07.4120 LOCOL. LNrUr[SocialAccountService] Refreshing token from provider {"socialAu[2026-04-14 09:21:28] Local.ERROR: Failed to refresh HubSpot token {"account_id":306,[2026-04-14 09:21:28] Local. INF0:Trying to refresh HubSpot token {"account_id":1372,[2026-04-14 09:21:28] Local. INFO:[EncryptedTokenManager] Generating access token. {"mode":"?[2026-04-14[SocialAccountService] Refreshing token from provider[2026-04-1409:21:29] local.ERROR: Failed to refresh HubSpot token {"account_id":1372,[2026-04-14Repairing HubSpot tokens end {"total":3, "fixed":0,[2026-04-14LocaL.INFO: Jiminny Console\Commands \Command::run Memory usage before starting command 1"[2026-04-14Jiminny \console commanas command::run Memory usage berore suaruing command i[2026-04-1409:21:39]land::run Memory usage for commana i"command"."J1[2026-04-1409:21:39]nuosoor Journal rouunol bertno ottser tron caranase "ortse[2026-04-14 09:21:39]Commandl Starting polling service[2026-04-14Pollinal Service starting {"m[2026-04-14 09:21:39]Polling] Acquired polling lock {"expires[2026-04-14 09:21:39]Polling] Getting offset from database {"offset"[2026-04-14 09:21:39]API] Fetching latest journal entry {"url": "https://api.hubapi[2026-04-14 09:21:39]Auth Requesting new client credentials token[2026-04-14 09:21:39]nd• • nun Memony ucade Fon commandl[2026-04-14 09:21:39] Local. INFO: [HubSpot JournalAuth] Successfully obtained new access token {"expires_in":18[2026-04-14 09:21:39] local. INF0:[HubSpot JournalPoluino No data{"correlation id"."316142e2-a958-41a5-8eef.[2026-04-14 09:21:44] Local. INFO:[HubSpot JournalPollingl Getting offset from database ("offset":"',"jiminny_t[2026-04-14 09:21:44] Local. INFO:[HubSpot JournalAPI]rerchuno arest ournal entry *"ur"https://api.hubapd[2026-04-14 09:21:44] Local. INFO:[HubSpot JournalPolling] No data{"correlation_id":"316142e2-a958-41a5-8eef-[2026-04-14 09:21:46] Local. INFO:Jiminny\ConsoLe\Commands\Command:: run Memory usage before starting command {"c[2026-04-14 09:21:46] Local. INF0:Jiminny\Console\Commands\Command::run Memory usage for command {"command": "crn[2026-04-14 09:21:50] Local. INFO:[HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_t[2026-04-14 09:21:50] Local. INFO:[HubSpot Journal API] Fetching latest journal entry {"url":"https://api.hubapi[2026-04-14 09:21:50] Local. INFO:[HubSpot Journal Polling] No data{"correlation id":"316142e2-a958-41a5-8eef-[2026-04-14 09:21:52] Local. INF0:Jiminny\Console\Commands\Command: :run Memory usage before starting command {"c[2026-04-14 09:21:52] Local. INFO:Jiminny Console \Commands \Command::run Memory usage for command 1"command":"cr.[2026-04-14 09:22:05] Local. INF0: [HubSpot Journal Polling] Getting offset from database {"offset":"", "jiminny_t[2026-04-14 09:22:05] Local. INFO: [HubSpot Journal API] Fetching latest journal entry {"ur?":"https://api.hubapi[2026-04-14 09:22:05] Local. INFO:[HubSpot Journal Polling] No data{"correlation_id":"316142e2-a958-41a5-8eef-[2026-04-14 09:22:15] Local. INFO:[Commands/AsyncUpdateEsEntities] Starting ES update worker {"pid":37760, "worke[2026-04-14 09:22:28] Local.ERROR: No arguments expected for"automated-reports" command, got"265". {"exceptior[stacktrace]#0 /home/jiminny/vendor/symfony/console/Input/ArgvInput.php(92): Symfony\\Component\\Console\\Input\\ArgvInput-›#1 /home/jiminny/vendor/symfony/console/Input/ArgvInput.php(77): Symfony\\Component\\Console\\Input\\ArgvInput->#2 /home/jiminny/vendor/symfony/console/Input/Input.php(53): Symfony\\Component\\Console\\Input\\ArgvInput->pars#3 /home/jiminny/vendor/symfony/console/Command/Command.php(295): Symfony\\Component\\Console\\Input\\Input->birCsv | 2 L →| 0, 8W Windsurf Teams 29869:25 UTF-8 f 4 spaces...
|
NULL
|
-2988433201528531928
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormFileEditFV faVsco.s vProject v= custom.loa PhpStormFileEditFV faVsco.s vProject v= custom.loa= hubspot-journal-poll.log= laravel.log< phpunit.xmlIs ttt.js= oauth-private.key= oauth-public.keyE storage= supervisord.pid"rexceav.sonv Mtests> D Feature> D Integration> D ServicesUnit› [ Actions> Component" ConfigurationD ConsoleContractsM DomainO DTOEnumsD Events• ExceptionsO fixturesHelpersD Http> O Integrations_Interactions~ D Jobs>_ActivityM AiAutomation> D Audiov _ AutomatedReports© CreateResultsTest.pl© RequestGenerateAsk© RequestGenerateRer© SendReportJobTest.© SendReportMailJobTcallendarD CrmDealRisksS|MalloOXM StreaminaViewNavigateCodeLaravelRefactorToolsWindowHelp#11894 on JY-18909-automated-reports-ask-jiminny k ~© ReportController.php© JiminnyDebugCommand.php© AutomatedReportsRepository.phpC AutomatedReportsService.php© UserPilotActivityListener.php© ActivityLogged.php© AutomatedReportResult.phpclass AutomatedReportsCommand extends Command© AutomatedReportsCommand.php xCreateHeldActivityEvent.php© AutomatedReportsCallbackService.php© AutomatedReportsSendCommand.php• TrackProviderInstalledEvent.php© RequestGenerateAskJiminnyReportJob.php© AddLayoutEntities.php© Team.phpCreateActivityLoggedEvent.php© RequestGenerateReportJob.php* Oreturn intpublic function handle(): int5758$this->logger->info(self::LOG_PREFIX . ' Started');$now = Carbon: :now();$isMonday = $now->isMonday);$isFirstDay0fMonth = $now->day === 1;$currentMonth = $now->month;// Check if the current month is a quarterly month (January, April, July, October)$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10],strict: true);$this->logger->info(self::LOG_PREFIX' Checking conditions', I"Istonday = s1sMonday,'isFirstDay0fMonth'=> $isFirstDay0fMonth,'currentMonth' => $currentMonth,'isQuarterlyMonth' => $isQuarterlyMonth,I);// Process daily reports$this->processReports( frequency: AutomatedReportsService::FREQUENCY_DAILY);// Process weekly reports on Mondaysif ($isMonday) €nunus-›orocesskeoorts, trequency: Auronaredreportsservce..rrcouaNcy weckLyon// Process monthly reports on the first day of the monthif ($isFirstDay0fMonth) {$this->processReports( frequency: AutomatedReportsService::FREQUENCY_MONTHLY);// Process quarterly reports on the first day of January, April, July, and Octoberif ($isFirstDay0fMonth && $isQuarterlyMonth) {$this->processReports( frequency: AutomatedReportsService::FREQUENCY_QUARTERLY);selvicesv DatabaseV AEUc consoev A jiminny@localhosts ho local4SF 4 sV A PRODA consolev ¿ STAGNG4 console 1 s 153 msDockerOutputDid Y:OOU0400000036t0MAC X8 rowsvG0,0Ouvid (UUID with time-low and time-h.. T ÷ ID media_type T265 926befa2-5d77-4ab3-a553-587a1d5d9f5dpdf266 656713b0-459c-4094-9823-ffe013dbc808pdf26/ 319094f0-7368-4ec1-8f2b-a15b99bb5/ecpdf269 d3037407-091e-438a-8c8e-6745c5bf8df9pdf271 09fd931c-117a-47b7-8ccb-abe2e5fe01a1pdf24 01 00025-0050-4841-0342-72050710101pdf275 ff55bec0-961d-493f-b8fb-dbc2e1d25279pdf• status Y• type Y4 ask_jiminny4 ask iininnv1 ask_jiminny4 ask_jiminny4 ask_jiminny1 ask_jiminny3 ask_jiminnyIne tile size /.80 MB exceeas the conticuSuoport Dailv • in 2h 38mTue 14 Aor 12:22:34= custom.logÁ console [STAGING]© FilterDefinitionCollection.phpE console (EU]© HistoryService.php12789147858ZY80Y298602986129862298662986729868278/6ZY8/298722987329874298752987629877298782987929880298812988229883298842989114787%29893LY0Y4-2989529896The file size (7.86 MB) exceeds the configured limit (2.56 MB). Code insight features are not availableIzUZo-VerUrarzol tocur arror Tcicryocedtoremanqver veneracmo access tokenr mooe теud14020-04-14 07.4120 LOCOL. LNrUr[SocialAccountService] Refreshing token from provider {"socialAu[2026-04-14 09:21:28] Local.ERROR: Failed to refresh HubSpot token {"account_id":306,[2026-04-14 09:21:28] Local. INF0:Trying to refresh HubSpot token {"account_id":1372,[2026-04-14 09:21:28] Local. INFO:[EncryptedTokenManager] Generating access token. {"mode":"?[2026-04-14[SocialAccountService] Refreshing token from provider[2026-04-1409:21:29] local.ERROR: Failed to refresh HubSpot token {"account_id":1372,[2026-04-14Repairing HubSpot tokens end {"total":3, "fixed":0,[2026-04-14LocaL.INFO: Jiminny Console\Commands \Command::run Memory usage before starting command 1"[2026-04-14Jiminny \console commanas command::run Memory usage berore suaruing command i[2026-04-1409:21:39]land::run Memory usage for commana i"command"."J1[2026-04-1409:21:39]nuosoor Journal rouunol bertno ottser tron caranase "ortse[2026-04-14 09:21:39]Commandl Starting polling service[2026-04-14Pollinal Service starting {"m[2026-04-14 09:21:39]Polling] Acquired polling lock {"expires[2026-04-14 09:21:39]Polling] Getting offset from database {"offset"[2026-04-14 09:21:39]API] Fetching latest journal entry {"url": "https://api.hubapi[2026-04-14 09:21:39]Auth Requesting new client credentials token[2026-04-14 09:21:39]nd• • nun Memony ucade Fon commandl[2026-04-14 09:21:39] Local. INFO: [HubSpot JournalAuth] Successfully obtained new access token {"expires_in":18[2026-04-14 09:21:39] local. INF0:[HubSpot JournalPoluino No data{"correlation id"."316142e2-a958-41a5-8eef.[2026-04-14 09:21:44] Local. INFO:[HubSpot JournalPollingl Getting offset from database ("offset":"',"jiminny_t[2026-04-14 09:21:44] Local. INFO:[HubSpot JournalAPI]rerchuno arest ournal entry *"ur"https://api.hubapd[2026-04-14 09:21:44] Local. INFO:[HubSpot JournalPolling] No data{"correlation_id":"316142e2-a958-41a5-8eef-[2026-04-14 09:21:46] Local. INFO:Jiminny\ConsoLe\Commands\Command:: run Memory usage before starting command {"c[2026-04-14 09:21:46] Local. INF0:Jiminny\Console\Commands\Command::run Memory usage for command {"command": "crn[2026-04-14 09:21:50] Local. INFO:[HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_t[2026-04-14 09:21:50] Local. INFO:[HubSpot Journal API] Fetching latest journal entry {"url":"https://api.hubapi[2026-04-14 09:21:50] Local. INFO:[HubSpot Journal Polling] No data{"correlation id":"316142e2-a958-41a5-8eef-[2026-04-14 09:21:52] Local. INF0:Jiminny\Console\Commands\Command: :run Memory usage before starting command {"c[2026-04-14 09:21:52] Local. INFO:Jiminny Console \Commands \Command::run Memory usage for command 1"command":"cr.[2026-04-14 09:22:05] Local. INF0: [HubSpot Journal Polling] Getting offset from database {"offset":"", "jiminny_t[2026-04-14 09:22:05] Local. INFO: [HubSpot Journal API] Fetching latest journal entry {"ur?":"https://api.hubapi[2026-04-14 09:22:05] Local. INFO:[HubSpot Journal Polling] No data{"correlation_id":"316142e2-a958-41a5-8eef-[2026-04-14 09:22:15] Local. INFO:[Commands/AsyncUpdateEsEntities] Starting ES update worker {"pid":37760, "worke[2026-04-14 09:22:28] Local.ERROR: No arguments expected for"automated-reports" command, got"265". {"exceptior[stacktrace]#0 /home/jiminny/vendor/symfony/console/Input/ArgvInput.php(92): Symfony\\Component\\Console\\Input\\ArgvInput-›#1 /home/jiminny/vendor/symfony/console/Input/ArgvInput.php(77): Symfony\\Component\\Console\\Input\\ArgvInput->#2 /home/jiminny/vendor/symfony/console/Input/Input.php(53): Symfony\\Component\\Console\\Input\\ArgvInput->pars#3 /home/jiminny/vendor/symfony/console/Command/Command.php(295): Symfony\\Component\\Console\\Input\\Input->birCsv | 2 L →| 0, 8W Windsurf Teams 29869:25 UTF-8 f 4 spaces...
|
NULL
|