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
49 lines
1.3 KiB
PHP
49 lines
1.3 KiB
PHP
<?php
|
|
|
|
// SPDX-License-Identifier: EUPL-1.2
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Core\Mod\Agentic\Mod\Api\Services;
|
|
|
|
use Core\Mod\Agentic\Mod\Api\Jobs\DeliverWebhookJob;
|
|
use Core\Mod\Agentic\Mod\Api\Models\WebhookDelivery;
|
|
use Core\Mod\Agentic\Mod\Api\Models\WebhookEndpoint;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class WebhookService
|
|
{
|
|
/**
|
|
* Dispatch an event to every active endpoint subscribed to the event type.
|
|
*
|
|
* Example:
|
|
* `dispatch(12, 'mcp.tool.executed', ['tool' => 'brain_recall'])`
|
|
*
|
|
* @return array<int, WebhookDelivery>
|
|
*/
|
|
public function dispatch(int $workspaceId, string $eventType, array $data): array
|
|
{
|
|
$endpoints = WebhookEndpoint::query()
|
|
->forWorkspace($workspaceId)
|
|
->active()
|
|
->forEvent($eventType)
|
|
->get();
|
|
|
|
if ($endpoints->isEmpty()) {
|
|
return [];
|
|
}
|
|
|
|
$deliveries = [];
|
|
|
|
DB::transaction(function () use ($data, $endpoints, $eventType, $workspaceId, &$deliveries): void {
|
|
foreach ($endpoints as $endpoint) {
|
|
$delivery = WebhookDelivery::createForEvent($endpoint, $eventType, $data, $workspaceId);
|
|
$deliveries[] = $delivery;
|
|
|
|
DeliverWebhookJob::dispatch($delivery)->afterCommit();
|
|
}
|
|
});
|
|
|
|
return $deliveries;
|
|
}
|
|
}
|