add composer-unused, comprehensive docs, and project restructure
- Add icanhazstring/composer-unused as dev dependency for dependency hygiene checks - Add German documentation (docs/) covering architecture, conventions, workflows, and developer checklists - Add API layer (ApiAuth, ApiBootstrap, ApiResponse), audit, scheduler, custom fields, and SSO services - Add Microsoft OIDC SSO, API token management, and user lifecycle features - Add swagger-ui vendor integration and OpenAPI spec - Add production Docker setup and bin/ scripts - Update composer dependencies, config, templates, and frontend assets throughout Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
79
lib/Service/Scheduler/ScheduledJobRegistry.php
Normal file
79
lib/Service/Scheduler/ScheduledJobRegistry.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace MintyPHP\Service\Scheduler;
|
||||
|
||||
use MintyPHP\Service\Scheduler\Handler\ScheduledJobHandlerInterface;
|
||||
use MintyPHP\Service\Scheduler\Handler\UserLifecycleJobHandler;
|
||||
|
||||
class ScheduledJobRegistry
|
||||
{
|
||||
public const USER_LIFECYCLE_RUN = 'user_lifecycle_run';
|
||||
|
||||
/**
|
||||
* Maps job_key => handler class name (must implement ScheduledJobHandlerInterface).
|
||||
*
|
||||
* To register a new job:
|
||||
* 1. Create lib/Service/Scheduler/Handler/YourJobHandler.php implementing the interface.
|
||||
* 2. Add a public const for the job key above.
|
||||
* 3. Add one line here: self::YOUR_JOB_KEY => YourJobHandler::class,
|
||||
*
|
||||
* No other file needs to be changed.
|
||||
*
|
||||
* @return array<string, class-string<ScheduledJobHandlerInterface>>
|
||||
*/
|
||||
private static function handlers(): array
|
||||
{
|
||||
return [
|
||||
self::USER_LIFECYCLE_RUN => UserLifecycleJobHandler::class,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all job definitions keyed by job_key.
|
||||
* Consumed by ScheduledJobService::ensureSystemJobs() to sync registry with the database.
|
||||
*/
|
||||
public static function definitions(): array
|
||||
{
|
||||
$result = [];
|
||||
foreach (self::handlers() as $jobKey => $handlerClass) {
|
||||
$result[$jobKey] = $handlerClass::definition();
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the definition for a single job key, or null if not registered.
|
||||
*/
|
||||
public static function get(string $jobKey): ?array
|
||||
{
|
||||
$jobKey = trim($jobKey);
|
||||
if ($jobKey === '') {
|
||||
return null;
|
||||
}
|
||||
$handlers = self::handlers();
|
||||
return isset($handlers[$jobKey]) ? $handlers[$jobKey]::definition() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches execution to the registered handler for the given job key and returns
|
||||
* a normalized result envelope. Unknown job keys return status 'failed' with
|
||||
* error_code 'job_not_supported' rather than throwing an exception.
|
||||
*
|
||||
* @param string $jobKey Registered job identifier (see class constants).
|
||||
* @param int|null $actorUserId Null for scheduler-triggered runs; user ID for manual runs.
|
||||
* @return array{status:string,error_code:?string,error_message:?string,result:array}
|
||||
*/
|
||||
public static function execute(string $jobKey, ?int $actorUserId): array
|
||||
{
|
||||
$handlers = self::handlers();
|
||||
if (!isset($handlers[$jobKey])) {
|
||||
return [
|
||||
'status' => 'failed',
|
||||
'error_code' => 'job_not_supported',
|
||||
'error_message' => null,
|
||||
'result' => [],
|
||||
];
|
||||
}
|
||||
return $handlers[$jobKey]::execute($actorUserId);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user