Skip to content

Commit f3db256

Browse files
author
Sebastian BURGIN-FIX (ext)
committed
Fixed
1 parent 54f1a21 commit f3db256

306 files changed

Lines changed: 1650 additions & 1781 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env.example

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,22 @@
11
APP_NAME="codebar Solutions AG"
22
APP_ENV=local
3-
APP_KEY=base64:F+mHMDBbavrsp/I3WYA5lDSwDJJI/0wQG4eM3csq/lo=
3+
APP_KEY=
44
APP_DEBUG=true
55
APP_URL=https://web.codebar.test
66

7-
NOVA_LICENSE_KEY=
8-
97
LOG_CHANNEL=stack
108
LOG_STACK=single,flare
119
LOG_DEPRECATIONS_CHANNEL=null
1210
LOG_LEVEL=debug
1311

1412
FLARE_KEY=
1513

16-
DB_CONNECTION=mysql
14+
DB_CONNECTION=pgsql
1715
DB_HOST=127.0.0.1
18-
DB_PORT=3306
19-
DB_DATABASE=laravel-template
20-
DB_USERNAME=root
21-
DB_PASSWORD=
16+
DB_PORT=5432
17+
DB_DATABASE=web-codebar
18+
DB_USERNAME=postgres
19+
DB_PASSWORD=postgres
2220

2321
FPH_ENABLED=true
2422
CSP_ENABLED=true

app/Actions/FetchLlmUsageAction.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
namespace App\Actions;
46

57
use Carbon\CarbonImmutable;

app/Actions/LlmUsageStatsAction.php

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
namespace App\Actions;
46

57
use App\Models\AiModelDailyUsage;
@@ -66,16 +68,6 @@ public function lastSyncedAt(): ?Carbon
6668
});
6769
}
6870

69-
/**
70-
* The most recent day usage data is available for.
71-
*/
72-
public function latestDate(): ?Carbon
73-
{
74-
return $this->remember('latest_date', function (): ?Carbon {
75-
return $this->toDate(AiModelDailyUsage::query()->max('date'));
76-
});
77-
}
78-
7971
private function toDate(mixed $value): ?Carbon
8072
{
8173
return match (true) {

app/Actions/LocaleAction.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
namespace App\Actions;
46

57
use App\Enums\SessionKeyEnum;

app/Actions/PageAction.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
namespace App\Actions;
46

57
use App\DTO\PageDTO;

app/Actions/StoreLlmUsageAction.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
namespace App\Actions;
46

57
use App\Models\AiModel;

app/Actions/ViewDataAction.php

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
namespace App\Actions;
46

57
use App\DTO\ContactDTO;
68
use App\Enums\AiModelCategoryEnum;
9+
use App\Enums\CacheKeyEnum;
710
use App\Enums\ContactSectionEnum;
811
use App\Models\AiModel;
912
use App\Models\Contact;
@@ -14,7 +17,6 @@
1417
use App\Models\Technology;
1518
use Illuminate\Support\Collection;
1619
use Illuminate\Support\Facades\Cache;
17-
use Illuminate\Support\Str;
1820

1921
class ViewDataAction
2022
{
@@ -23,7 +25,7 @@ class ViewDataAction
2325
*/
2426
public function products(string $locale): Collection
2527
{
26-
$key = Str::slug("products_published_{$locale}");
28+
$key = CacheKeyEnum::PRODUCTS_PUBLISHED->forLocale($locale);
2729

2830
return Cache::rememberForever($key, function () {
2931
return Product::where('published', true)->orderBy('order')->get();
@@ -35,7 +37,7 @@ public function products(string $locale): Collection
3537
*/
3638
public function services(string $locale): Collection
3739
{
38-
$key = Str::slug("services_published_{$locale}");
40+
$key = CacheKeyEnum::SERVICES_PUBLISHED->forLocale($locale);
3941

4042
return Cache::rememberForever($key, function () {
4143
return Service::where('published', true)->orderBy('order')->get();
@@ -47,7 +49,7 @@ public function services(string $locale): Collection
4749
*/
4850
public function news(string $locale): Collection
4951
{
50-
$key = Str::slug("news_published_{$locale}");
52+
$key = CacheKeyEnum::NEWS_PUBLISHED->forLocale($locale);
5153

5254
return Cache::rememberForever($key, function () {
5355
// Eager loaded: the cards read the series title and the author's picture,
@@ -65,7 +67,7 @@ public function news(string $locale): Collection
6567
*/
6668
public function technologies(string $locale): Collection
6769
{
68-
$key = Str::slug("technologies_published_{$locale}");
70+
$key = CacheKeyEnum::TECHNOLOGIES_PUBLISHED->forLocale($locale);
6971

7072
return Cache::rememberForever($key, function () {
7173
return Technology::where('published', true)->orderBy('order')->get();
@@ -77,7 +79,7 @@ public function technologies(string $locale): Collection
7779
*/
7880
public function aiModelGroups(): Collection
7981
{
80-
return Cache::rememberForever('ai_models_active', function () {
82+
return Cache::rememberForever(CacheKeyEnum::AI_MODELS_ACTIVE->value, function () {
8183
return $this->groupAiModelsByCategory(
8284
AiModel::whereNull('archived_at')->orderBy('order')->get()
8385
);
@@ -89,7 +91,7 @@ public function aiModelGroups(): Collection
8991
*/
9092
public function aiModelArchive(): Collection
9193
{
92-
return Cache::rememberForever('ai_models_archived', function () {
94+
return Cache::rememberForever(CacheKeyEnum::AI_MODELS_ARCHIVED->value, function () {
9395
return $this->groupAiModelsByCategory(
9496
AiModel::whereNotNull('archived_at')->with('replacedBy')->orderBy('order')->get()
9597
);
@@ -116,7 +118,7 @@ private function groupAiModelsByCategory(Collection $models): Collection
116118
*/
117119
public function openSource(string $locale): Collection
118120
{
119-
$key = Str::slug("open_source_published_{$locale}");
121+
$key = CacheKeyEnum::OPEN_SOURCE_PUBLISHED->forLocale($locale);
120122

121123
return Cache::rememberForever($key, function () {
122124
return OpenSource::where('published', true)->orderByDesc('downloads')->get();
@@ -125,7 +127,7 @@ public function openSource(string $locale): Collection
125127

126128
public function contacts(string $locale): \stdClass
127129
{
128-
$key = Str::slug("contacts_published_{$locale}");
130+
$key = CacheKeyEnum::CONTACTS_PUBLISHED->forLocale($locale);
129131

130132
return Cache::rememberForever($key, function () use ($locale) {
131133
// Ordered by the `sort` field from the YAML files rather than alphabetically:

app/Checks/FailedJobsCheck.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
namespace App\Checks;
46

57
use Illuminate\Support\Facades\DB;

app/Checks/FilesystemsDefaultCheck.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
namespace App\Checks;
46

57
use App\Enums\CacheKeyEnum;

app/Checks/JobsCheck.php

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,53 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
namespace App\Checks;
46

5-
use Illuminate\Support\Collection;
7+
use Illuminate\Support\Carbon;
68
use Illuminate\Support\Facades\DB;
79
use Spatie\Health\Checks\Check;
810
use Spatie\Health\Checks\Result;
911

12+
/**
13+
* A queue is healthy when it is either empty or moving. Depth alone says nothing —
14+
* a thousand jobs dispatched a second ago is fine, one job stuck for an hour is not.
15+
* The age of the oldest pending job is what separates the two, and it costs one query
16+
* rather than sampling the depth once a second for a minute and a half.
17+
*/
1018
class JobsCheck extends Check
1119
{
12-
public const int TIME = 90;
20+
public const int STALLED_AFTER_MINUTES = 5;
1321

1422
public function run(): Result
1523
{
16-
$count = DB::table('jobs')->count();
24+
$pending = DB::table('jobs')->count();
1725

18-
$result = Result::make();
19-
$result->shortSummary("jobs table count: {$count}");
26+
$result = Result::make()->shortSummary("pending jobs: {$pending}");
2027

21-
if ($count <= 0) {
28+
if ($pending === 0) {
2229
return $result->ok();
2330
}
2431

25-
$newCounts = Collection::times(self::TIME, function () {
26-
$count = DB::table('jobs')->count();
27-
sleep(1);
32+
$waitingMinutes = $this->oldestPendingJobAgeInMinutes();
2833

29-
return $count;
30-
});
34+
if ($waitingMinutes === null || $waitingMinutes < self::STALLED_AFTER_MINUTES) {
35+
return $result->ok();
36+
}
3137

32-
$allMatch = $newCounts->every(fn (int $value) => $value === $count);
38+
return $result->failed(
39+
"The queue is not draining: {$pending} pending job(s), the oldest waiting {$waitingMinutes} minute(s)."
40+
);
41+
}
3342

34-
$result->shortSummary("jobs table count: {$allMatch}");
43+
private function oldestPendingJobAgeInMinutes(): ?int
44+
{
45+
$availableAt = DB::table('jobs')->min('available_at');
3546

36-
if ($count != $allMatch) {
37-
return $result->ok();
47+
if (! is_numeric($availableAt)) {
48+
return null;
3849
}
3950

40-
return $result->failed();
41-
51+
return (int) Carbon::createFromTimestamp((int) $availableAt)->diffInMinutes(absolute: true);
4252
}
4353
}

0 commit comments

Comments
 (0)