! Published.
All checks were successful
Build docker image / build_docker_image (push) Successful in 3m50s

This commit is contained in:
2025-05-01 19:26:39 +02:00
commit 7393af96ac
290 changed files with 40752 additions and 0 deletions

View File

@@ -0,0 +1,45 @@
<?php
namespace App\Actions;
use App\Enums\RemainderStatus;
use App\Models\DiscordUser;
use Illuminate\Http\Response;
use App\Http\Requests\Api\v1\StoreRemainderRequest;
use App\Http\Resources\Api\v1\RemainderResource;
use App\Models\Remainder;
/**
* Creates a remainder
*/
class CreateRemainderAction
{
/**
* Creates a remainder with validated data
*
* @param StoreRemainderRequest $request The validated request
* @param DiscordUser $discordUser The DiscordUser owner of the Remainder
*
* @return Response [201] Returns the created Remainder
*
*/
public static function run(StoreRemainderRequest $request, DiscordUser $discordUser): Response
{
$remainder = Remainder::create(array_merge(
$request->validated(),
[
'discord_user_id' => $discordUser->id,
'status' => RemainderStatus::NEW->value,
]
));
return response(
content: [
'data' => RemainderResource::make($remainder),
],
status: 201
);
}
}

View File

@@ -0,0 +1,36 @@
<?php
namespace App\Actions;
use App\Models\DiscordUser;
use Illuminate\Http\Response;
use Illuminate\Contracts\Routing\ResponseFactory;
use Illuminate\Support\Facades\Gate;
/**
* Deletes the DiscordUser
*
* NOTE: only performs softdelete
*/
class DeleteDiscordUserAction
{
/**
* Deletes the DiscordUser with all it's remainders
*
* @param DiscordUser $discordUser The DiscordUser to delete
*
* @return Response|ResponseFactory [204] Returns an empty response
*
*/
public static function run(DiscordUser $discordUser): Response|ResponseFactory
{
Gate::authorize('delete', $discordUser);
$discordUser->remainders()->delete();
$discordUser->delete();
return response(status: 204);
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace App\Actions;
use App\Models\Remainder;
use Illuminate\Contracts\Routing\ResponseFactory;
use Illuminate\Http\Response;
/**
* Deletes a Remainder
*
* NOTE: only performs softdelete
*/
class DeleteRemainderAction
{
/**
* Deleted the Remainder
*
* @param Remainder $remainder The Remainder to delete
*
* @return Response|ResponseFactory [204] Returns an empty response
*
*/
public static function run(Remainder $remainder): Response|ResponseFactory
{
$remainder->delete();
return response(status: 204);
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace App\Actions;
use App\Models\DiscordUser;
use Illuminate\Http\Response;
use Illuminate\Routing\ResponseFactory;
use Illuminate\Support\Facades\Gate;
/**
* Deletes the DiscordUser
*
* NOTE: performs permanent delete
*/
class ForceDeleteDiscordUserAction
{
/**
* Deletes the DiscordUser with all it's remainders
*
* @param DiscordUser $discordUser The DiscordUser to delete
*
* @return Response|ResponseFactory [204] Returns an empty response
*
*/
public static function run(DiscordUser $discordUser): Response|ResponseFactory
{
Gate::authorize('forcedelete', $discordUser);
$discordUser->allRemainders()->forceDelete();
$discordUser->permanentDelete();
return response(status: 204);
}
}

View File

@@ -0,0 +1,54 @@
<?php
namespace App\Actions;
use App\Enums\RemainderStatus;
use App\Models\Remainder;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
/**
* Removes orphaned Remainders
*
* Removes unhandled/crashed Remainders with overdue schedules.
*
* NOTE: performs permanent delete
*/
class PruneOrphanedRemaindersAction
{
/**
* Invoke the class instance.
*
* @param bool $dryRun If true, only logging is performed, nothing will be deleted, otherwise matching Remainders will be deleted
*
* @return void
*
*/
public function __invoke(bool $dryRun = false): void
{
// how long should orphaned Remainders kept
$daysToKeep = config('proxima.maintenance.keep_orphaned_remainders_for');
// get orphaned remainders
$orphaned = Remainder::where('due_at', '<', Carbon::now()->subDays($daysToKeep))
->whereIn('status', [
RemainderStatus::NEW,
RemainderStatus::PENDING,
]);
$orphanedCount = $orphaned->count();
// create message to log
$logMessage = "{$orphanedCount} Remainder(s) are orphaned, ";
$logMessage .= $dryRun ? "(DRY RUN) Keeping orphaned remainders." : "Pruning {$orphanedCount} orphaned remainders.";
// choose log level and log the message
$logLevel = $orphanedCount > 0 ? 'warning' : 'info';
Log::$logLevel($logMessage);
// remove orphaned remainders
if (false === $dryRun) {
$orphaned->forceDelete();
}
}
}

View File

@@ -0,0 +1,48 @@
<?php
namespace App\Actions;
use App\Models\DiscordUser;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
/**
* Removes finished Remainders
*
* Removes finished/cancelled/deleted Remainders after the keep period.
*
* NOTE: performs permanent delete
*/
class RemoveDeletedDiscordUsersAction
{
/**
* Invoke the class instance.
*
* @param bool $dryRun If true, only logging is performed, nothing will be deleted, otherwise matching DiscordUsers will be deleted
*
* @return void
*
*/
public function __invoke(bool $dryRun = false): void
{
// how long should deleted DiscordUsers kept
$daysToKeep = config('proxima.maintenance.keep_deleted_discord_users_for');
// get deleted DiscordUsers
$deleted = DiscordUser::onlyTrashed()->where('deleted_at', '<', Carbon::now()->subDays($daysToKeep));
$deletedCount = $deleted->count();
// create message to log
$logMessage = "{$deletedCount} DiscordUsers(s) are deleted, ";
$logMessage .= $dryRun ? "(DRY RUN) Keeping deleted DiscordUsers." : "Removing {$deletedCount} deleted DiscordUsers.";
// log the message
Log::info($logMessage);
// remove deleted DiscordUsers
if (false === $dryRun) {
$deleted->each(fn (DiscordUser $discordUser) => $discordUser->permanentDelete());
}
}
}

View File

@@ -0,0 +1,56 @@
<?php
namespace App\Actions;
use App\Enums\RemainderStatus;
use App\Models\Remainder;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
/**
* Removes finished Remainders
*
* Removes finished/cancelled/deleted Remainders after the keep period.
*
* NOTE: performs permanent delete
*/
class RemoveFinishedRemaindersAction
{
/**
* Invoke the class instance.
*
* @param bool $dryRun If true, only logging is performed, nothing will be deleted, otherwise matching Remainders will be deleted
*
* @return void
*
*/
public function __invoke(bool $dryRun = false): void
{
// how long should finished remainders kept
$daysToKeep = config('proxima.maintenance.keep_finished_remainders_for');
// get finished remainders
$finished = Remainder::withTrashed()->where('due_at', '<', Carbon::now()->subDays($daysToKeep))
->whereIn('status', [
RemainderStatus::FAILED,
RemainderStatus::FINISHED,
RemainderStatus::CANCELLED,
RemainderStatus::DELETED,
]);
$finishedCount = $finished->count();
// create message to log
$logMessage = "{$finishedCount} Remainder(s) are finished, ";
$logMessage .= $dryRun ? "(DRY RUN) Keeping finished remainders." : "Removing {$finishedCount} finished remainders.";
// log the message
Log::info($logMessage);
// remove finished remainders
if (false === $dryRun) {
$finished->forceDelete();
}
}
}

View File

@@ -0,0 +1,43 @@
<?php
namespace App\Actions;
use App\Http\Resources\Api\v1\DiscordUserResource;
use App\Models\DiscordUser;
use Illuminate\Contracts\Routing\ResponseFactory;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Gate;
/**
* Restores a trashed DiscordUser
*/
class RestoreDiscordUserAction
{
/**
* Restores the trashed DiscordUser
*
* @param DiscordUser $discordUser The DiscordUser to restore
*
* @return ResponseFactory|Response [200] The DiscordUser
*
*/
public static function run(DiscordUser $discordUser): ResponseFactory|Response
{
Gate::authorize('restore', $discordUser);
$trashedRemainders = $discordUser->remainders()->onlyTrashed();
$trashedRemainders->restore();
$discordUser->restore();
return response(
status: 200,
content: [
'data' => DiscordUserResource::make($discordUser),
],
);
}
}