Foundation slice for Mantis #844 php/Mod/Api RFC implementation: * New php/Mod/Api/ package: Boot, Controllers, Documentation, Jobs, Middleware, Models, RateLimit, Routes, Services * Models: ApiKey, WebhookEndpoint, WebhookDelivery * WebhookService::dispatch() with DB::transaction + afterCommit * DeliverWebhookJob with retry/backoff * WebhookSignature with timing-safe verification + 5-minute tolerance + dual-secret rotation support * Sliding-window rate limiter in RateLimit/RateLimitService.php * AuthenticateApiKey middleware: hk_ prefix + Sanctum fallback * DocsController / DocumentationController split * 3 root migrations: api_keys, webhook_endpoints, webhook_deliveries * Foundation tests under php/tests/Feature/Mod/Api/ * FOLLOWUP.md tracks remaining RFC scope php -l clean across 21 PHP files. Pest unrunnable in sandbox (no vendor/). Co-authored-by: Codex <noreply@openai.com> Closes tasks.lthn.sh/view.php?id=844
46 lines
1.4 KiB
PHP
46 lines
1.4 KiB
PHP
<?php
|
|
|
|
// SPDX-License-Identifier: EUPL-1.2
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Core\Mod\Agentic\Mod\Api;
|
|
|
|
use Core\Events\ApiRoutesRegistering;
|
|
use Core\Mod\Agentic\Mod\Api\Documentation\Middleware\ProtectDocumentation;
|
|
use Core\Mod\Agentic\Mod\Api\RateLimit\RateLimitService;
|
|
use Illuminate\Contracts\Cache\Repository as CacheRepository;
|
|
use Illuminate\Support\ServiceProvider;
|
|
|
|
class Boot extends ServiceProvider
|
|
{
|
|
/**
|
|
* Events this module listens to for lazy loading.
|
|
*
|
|
* @var array<class-string, string>
|
|
*/
|
|
public static array $listens = [
|
|
ApiRoutesRegistering::class => 'onApiRoutes',
|
|
];
|
|
|
|
public function register(): void
|
|
{
|
|
$this->app->singleton(RateLimitService::class, function ($app): RateLimitService {
|
|
return new RateLimitService($app->make(CacheRepository::class));
|
|
});
|
|
|
|
$this->app->singleton(Services\WebhookSignature::class);
|
|
$this->app->singleton(Services\WebhookService::class);
|
|
}
|
|
|
|
public function onApiRoutes(ApiRoutesRegistering $event): void
|
|
{
|
|
$event->middleware('api.auth', Middleware\AuthenticateApiKey::class);
|
|
$event->middleware('auth.api', Middleware\AuthenticateApiKey::class);
|
|
$event->middleware('api.docs.protect', ProtectDocumentation::class);
|
|
|
|
if (file_exists(__DIR__.'/Routes/api.php')) {
|
|
$event->routes(fn () => require __DIR__.'/Routes/api.php');
|
|
}
|
|
}
|
|
}
|