new changes
This commit is contained in:
55
panel-api/app/Modules/Agents/AgentController.php
Normal file
55
panel-api/app/Modules/Agents/AgentController.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\Agents;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller;
|
||||
|
||||
class AgentController extends Controller
|
||||
{
|
||||
public function __construct(private readonly AgentSessionRepository $sessionsRepo)
|
||||
{
|
||||
}
|
||||
|
||||
public function issueEnrollmentToken(string $server): JsonResponse
|
||||
{
|
||||
return response()->json([
|
||||
'data' => [
|
||||
'server_id' => $server,
|
||||
'token_type' => 'bootstrap',
|
||||
'expires_in_sec' => 900,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function capabilities(string $server): JsonResponse
|
||||
{
|
||||
return response()->json([
|
||||
'data' => [
|
||||
'server_id' => $server,
|
||||
'capabilities' => [],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function sessions(string $server): JsonResponse
|
||||
{
|
||||
return response()->json([
|
||||
'data' => [
|
||||
'server_id' => $server,
|
||||
'sessions' => $this->sessionsRepo->listByServer($server),
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function heartbeat(Request $request, string $server): JsonResponse
|
||||
{
|
||||
$agentUid = (string) $request->input('agent_uid', '');
|
||||
$session = $this->sessionsRepo->touchHeartbeat($server, $agentUid, $request->all());
|
||||
|
||||
return response()->json([
|
||||
'data' => $session,
|
||||
]);
|
||||
}
|
||||
}
|
||||
22
panel-api/app/Modules/Agents/AgentSessionRepository.php
Normal file
22
panel-api/app/Modules/Agents/AgentSessionRepository.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\Agents;
|
||||
|
||||
class AgentSessionRepository
|
||||
{
|
||||
public function listByServer(string $serverId): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function touchHeartbeat(string $serverId, string $agentUid, array $payload): array
|
||||
{
|
||||
return [
|
||||
'server_id' => $serverId,
|
||||
'agent_uid' => $agentUid,
|
||||
'status' => 'online',
|
||||
'last_seen_at' => now()->toISOString(),
|
||||
'payload' => $payload,
|
||||
];
|
||||
}
|
||||
}
|
||||
48
panel-api/app/Modules/Auth/AuthController.php
Normal file
48
panel-api/app/Modules/Auth/AuthController.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\Auth;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller;
|
||||
|
||||
class AuthController extends Controller
|
||||
{
|
||||
public function login(Request $request): JsonResponse
|
||||
{
|
||||
return response()->json([
|
||||
'data' => [
|
||||
'access_token' => 'placeholder-token',
|
||||
'token_type' => 'Bearer',
|
||||
'expires_in' => 3600,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function refresh(Request $request): JsonResponse
|
||||
{
|
||||
return response()->json([
|
||||
'data' => [
|
||||
'access_token' => 'placeholder-token-refreshed',
|
||||
'token_type' => 'Bearer',
|
||||
'expires_in' => 3600,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function me(Request $request): JsonResponse
|
||||
{
|
||||
return response()->json([
|
||||
'data' => [
|
||||
'id' => null,
|
||||
'email' => null,
|
||||
'tenants' => [],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function logout(Request $request): JsonResponse
|
||||
{
|
||||
return response()->json([], 204);
|
||||
}
|
||||
}
|
||||
54
panel-api/app/Modules/Jobs/CommandOrchestrator.php
Normal file
54
panel-api/app/Modules/Jobs/CommandOrchestrator.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\Jobs;
|
||||
|
||||
class CommandOrchestrator
|
||||
{
|
||||
private array $acceptedTypes = [
|
||||
'SITE_CREATE',
|
||||
'SITE_UPDATE',
|
||||
'SITE_DELETE',
|
||||
'DOMAIN_ADD',
|
||||
'DOMAIN_REMOVE',
|
||||
'SSL_ISSUE',
|
||||
'SSL_APPLY',
|
||||
'SSL_RENEW',
|
||||
'WEBSERVER_RELOAD',
|
||||
'FILE_LIST',
|
||||
'FILE_READ',
|
||||
'FILE_WRITE',
|
||||
'CRON_LIST',
|
||||
'CRON_CREATE',
|
||||
'CRON_DELETE',
|
||||
'FIREWALL_RULE_LIST',
|
||||
'DOCKER_DEPLOY',
|
||||
'PLUGIN_INSTALL',
|
||||
'PLUGIN_UPDATE',
|
||||
'PLUGIN_REMOVE',
|
||||
'FIREWALL_RULE_ADD',
|
||||
'FIREWALL_RULE_DELETE',
|
||||
'BACKUP_RUN',
|
||||
'BACKUP_RESTORE',
|
||||
];
|
||||
|
||||
public function dispatch(array $commandEnvelope): array
|
||||
{
|
||||
$type = (string) ($commandEnvelope['type'] ?? '');
|
||||
if (!in_array($type, $this->acceptedTypes, true)) {
|
||||
return [
|
||||
'job_status' => 'rejected',
|
||||
'error' => 'Unsupported command type',
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'job_status' => 'queued',
|
||||
'job_id' => uniqid('job_', true),
|
||||
'tenant_id' => $commandEnvelope['tenant_id'] ?? null,
|
||||
'type' => $type,
|
||||
'idempotency_key' => $commandEnvelope['idempotency_key'] ?? null,
|
||||
'args' => $commandEnvelope['args'] ?? [],
|
||||
'message' => 'Command accepted for execution plane dispatch',
|
||||
];
|
||||
}
|
||||
}
|
||||
25
panel-api/app/Modules/Jobs/JobController.php
Normal file
25
panel-api/app/Modules/Jobs/JobController.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\Jobs;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller;
|
||||
|
||||
class JobController extends Controller
|
||||
{
|
||||
public function __construct(private readonly CommandOrchestrator $orchestrator)
|
||||
{
|
||||
}
|
||||
|
||||
public function dispatch(Request $request): JsonResponse
|
||||
{
|
||||
$tenantId = (string) $request->attributes->get('tenant_id', '');
|
||||
$payload = $request->all();
|
||||
$payload['tenant_id'] = $tenantId;
|
||||
|
||||
$result = $this->orchestrator->dispatch($payload);
|
||||
|
||||
return response()->json(['data' => $result], 202);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\Marketplace;
|
||||
|
||||
class MarketplaceCommandFactory
|
||||
{
|
||||
public function installPlugin(string $tenantId, array $input): array
|
||||
{
|
||||
return [
|
||||
'tenant_id' => $tenantId,
|
||||
'type' => 'PLUGIN_INSTALL',
|
||||
'idempotency_key' => $input['idempotency_key'] ?? uniqid('plugin_install_', true),
|
||||
'args' => $input,
|
||||
];
|
||||
}
|
||||
|
||||
public function updatePlugin(string $tenantId, array $input): array
|
||||
{
|
||||
return [
|
||||
'tenant_id' => $tenantId,
|
||||
'type' => 'PLUGIN_UPDATE',
|
||||
'idempotency_key' => $input['idempotency_key'] ?? uniqid('plugin_update_', true),
|
||||
'args' => $input,
|
||||
];
|
||||
}
|
||||
|
||||
public function removePlugin(string $tenantId, array $input): array
|
||||
{
|
||||
return [
|
||||
'tenant_id' => $tenantId,
|
||||
'type' => 'PLUGIN_REMOVE',
|
||||
'idempotency_key' => $input['idempotency_key'] ?? uniqid('plugin_remove_', true),
|
||||
'args' => $input,
|
||||
];
|
||||
}
|
||||
}
|
||||
42
panel-api/app/Modules/Marketplace/MarketplaceController.php
Normal file
42
panel-api/app/Modules/Marketplace/MarketplaceController.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\Marketplace;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller;
|
||||
|
||||
class MarketplaceController extends Controller
|
||||
{
|
||||
public function __construct(private readonly MarketplaceWorkflowService $workflow)
|
||||
{
|
||||
}
|
||||
|
||||
public function catalog(Request $request): JsonResponse
|
||||
{
|
||||
return response()->json([
|
||||
'data' => [
|
||||
'items' => [],
|
||||
'meta' => ['source' => 'placeholder-market-catalog'],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function install(Request $request): JsonResponse
|
||||
{
|
||||
$tenantId = (string) $request->attributes->get('tenant_id', '');
|
||||
return response()->json(['data' => $this->workflow->install($tenantId, $request->all())], 202);
|
||||
}
|
||||
|
||||
public function update(Request $request): JsonResponse
|
||||
{
|
||||
$tenantId = (string) $request->attributes->get('tenant_id', '');
|
||||
return response()->json(['data' => $this->workflow->update($tenantId, $request->all())], 202);
|
||||
}
|
||||
|
||||
public function remove(Request $request): JsonResponse
|
||||
{
|
||||
$tenantId = (string) $request->attributes->get('tenant_id', '');
|
||||
return response()->json(['data' => $this->workflow->remove($tenantId, $request->all())], 202);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\Marketplace;
|
||||
|
||||
use App\Modules\Jobs\CommandOrchestrator;
|
||||
|
||||
class MarketplaceWorkflowService
|
||||
{
|
||||
public function __construct(
|
||||
private readonly CommandOrchestrator $orchestrator,
|
||||
private readonly MarketplaceCommandFactory $commands
|
||||
) {
|
||||
}
|
||||
|
||||
public function install(string $tenantId, array $input): array
|
||||
{
|
||||
return $this->orchestrator->dispatch($this->commands->installPlugin($tenantId, $input));
|
||||
}
|
||||
|
||||
public function update(string $tenantId, array $input): array
|
||||
{
|
||||
return $this->orchestrator->dispatch($this->commands->updatePlugin($tenantId, $input));
|
||||
}
|
||||
|
||||
public function remove(string $tenantId, array $input): array
|
||||
{
|
||||
return $this->orchestrator->dispatch($this->commands->removePlugin($tenantId, $input));
|
||||
}
|
||||
}
|
||||
20
panel-api/app/Modules/Monitoring/MetricsIngestController.php
Normal file
20
panel-api/app/Modules/Monitoring/MetricsIngestController.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\Monitoring;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller;
|
||||
|
||||
class MetricsIngestController extends Controller
|
||||
{
|
||||
public function ingest(Request $request): JsonResponse
|
||||
{
|
||||
return response()->json([
|
||||
'data' => [
|
||||
'accepted' => true,
|
||||
'points' => is_array($request->input('points')) ? count($request->input('points')) : 0,
|
||||
],
|
||||
], 202);
|
||||
}
|
||||
}
|
||||
43
panel-api/app/Modules/Monitoring/MonitoringController.php
Normal file
43
panel-api/app/Modules/Monitoring/MonitoringController.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\Monitoring;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller;
|
||||
|
||||
class MonitoringController extends Controller
|
||||
{
|
||||
public function liveServerMetrics(string $serverId): JsonResponse
|
||||
{
|
||||
return response()->json([
|
||||
'data' => [
|
||||
'server_id' => $serverId,
|
||||
'cpu_percent' => null,
|
||||
'memory_percent' => null,
|
||||
'disk_percent' => null,
|
||||
'network' => ['in' => null, 'out' => null],
|
||||
'status' => 'streaming',
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function createAlertRule(Request $request): JsonResponse
|
||||
{
|
||||
return response()->json([
|
||||
'data' => [
|
||||
'status' => 'created',
|
||||
'rule' => $request->all(),
|
||||
],
|
||||
], 201);
|
||||
}
|
||||
|
||||
public function listAlerts(Request $request): JsonResponse
|
||||
{
|
||||
return response()->json([
|
||||
'data' => [
|
||||
'items' => [],
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
||||
26
panel-api/app/Modules/Ops/BackupController.php
Normal file
26
panel-api/app/Modules/Ops/BackupController.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\Ops;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller;
|
||||
|
||||
class BackupController extends Controller
|
||||
{
|
||||
public function __construct(private readonly OpsWorkflowService $workflow)
|
||||
{
|
||||
}
|
||||
|
||||
public function run(Request $request): JsonResponse
|
||||
{
|
||||
$tenantId = (string) $request->attributes->get('tenant_id', '');
|
||||
return response()->json(['data' => $this->workflow->backupRun($tenantId, $request->all())], 202);
|
||||
}
|
||||
|
||||
public function restore(Request $request): JsonResponse
|
||||
{
|
||||
$tenantId = (string) $request->attributes->get('tenant_id', '');
|
||||
return response()->json(['data' => $this->workflow->backupRestore($tenantId, $request->all())], 202);
|
||||
}
|
||||
}
|
||||
32
panel-api/app/Modules/Ops/CronController.php
Normal file
32
panel-api/app/Modules/Ops/CronController.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\Ops;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller;
|
||||
|
||||
class CronController extends Controller
|
||||
{
|
||||
public function __construct(private readonly OpsWorkflowService $workflow)
|
||||
{
|
||||
}
|
||||
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
$tenantId = (string) $request->attributes->get('tenant_id', '');
|
||||
return response()->json(['data' => $this->workflow->cronList($tenantId, $request->all())], 202);
|
||||
}
|
||||
|
||||
public function store(Request $request): JsonResponse
|
||||
{
|
||||
$tenantId = (string) $request->attributes->get('tenant_id', '');
|
||||
return response()->json(['data' => $this->workflow->cronCreate($tenantId, $request->all())], 202);
|
||||
}
|
||||
|
||||
public function destroy(Request $request): JsonResponse
|
||||
{
|
||||
$tenantId = (string) $request->attributes->get('tenant_id', '');
|
||||
return response()->json(['data' => $this->workflow->cronDelete($tenantId, $request->all())], 202);
|
||||
}
|
||||
}
|
||||
32
panel-api/app/Modules/Ops/FileOpsController.php
Normal file
32
panel-api/app/Modules/Ops/FileOpsController.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\Ops;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller;
|
||||
|
||||
class FileOpsController extends Controller
|
||||
{
|
||||
public function __construct(private readonly OpsWorkflowService $workflow)
|
||||
{
|
||||
}
|
||||
|
||||
public function list(Request $request): JsonResponse
|
||||
{
|
||||
$tenantId = (string) $request->attributes->get('tenant_id', '');
|
||||
return response()->json(['data' => $this->workflow->fileList($tenantId, $request->all())], 202);
|
||||
}
|
||||
|
||||
public function read(Request $request): JsonResponse
|
||||
{
|
||||
$tenantId = (string) $request->attributes->get('tenant_id', '');
|
||||
return response()->json(['data' => $this->workflow->fileRead($tenantId, $request->all())], 202);
|
||||
}
|
||||
|
||||
public function write(Request $request): JsonResponse
|
||||
{
|
||||
$tenantId = (string) $request->attributes->get('tenant_id', '');
|
||||
return response()->json(['data' => $this->workflow->fileWrite($tenantId, $request->all())], 202);
|
||||
}
|
||||
}
|
||||
32
panel-api/app/Modules/Ops/FirewallController.php
Normal file
32
panel-api/app/Modules/Ops/FirewallController.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\Ops;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller;
|
||||
|
||||
class FirewallController extends Controller
|
||||
{
|
||||
public function __construct(private readonly OpsWorkflowService $workflow)
|
||||
{
|
||||
}
|
||||
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
$tenantId = (string) $request->attributes->get('tenant_id', '');
|
||||
return response()->json(['data' => $this->workflow->firewallList($tenantId, $request->all())], 202);
|
||||
}
|
||||
|
||||
public function store(Request $request): JsonResponse
|
||||
{
|
||||
$tenantId = (string) $request->attributes->get('tenant_id', '');
|
||||
return response()->json(['data' => $this->workflow->firewallAdd($tenantId, $request->all())], 202);
|
||||
}
|
||||
|
||||
public function destroy(Request $request): JsonResponse
|
||||
{
|
||||
$tenantId = (string) $request->attributes->get('tenant_id', '');
|
||||
return response()->json(['data' => $this->workflow->firewallDelete($tenantId, $request->all())], 202);
|
||||
}
|
||||
}
|
||||
71
panel-api/app/Modules/Ops/OpsCommandFactory.php
Normal file
71
panel-api/app/Modules/Ops/OpsCommandFactory.php
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\Ops;
|
||||
|
||||
class OpsCommandFactory
|
||||
{
|
||||
public function fileList(string $tenantId, array $input): array
|
||||
{
|
||||
return $this->cmd($tenantId, 'FILE_LIST', 'file_list_', $input);
|
||||
}
|
||||
|
||||
public function fileRead(string $tenantId, array $input): array
|
||||
{
|
||||
return $this->cmd($tenantId, 'FILE_READ', 'file_read_', $input);
|
||||
}
|
||||
|
||||
public function fileWrite(string $tenantId, array $input): array
|
||||
{
|
||||
return $this->cmd($tenantId, 'FILE_WRITE', 'file_write_', $input);
|
||||
}
|
||||
|
||||
public function cronList(string $tenantId, array $input): array
|
||||
{
|
||||
return $this->cmd($tenantId, 'CRON_LIST', 'cron_list_', $input);
|
||||
}
|
||||
|
||||
public function cronCreate(string $tenantId, array $input): array
|
||||
{
|
||||
return $this->cmd($tenantId, 'CRON_CREATE', 'cron_create_', $input);
|
||||
}
|
||||
|
||||
public function cronDelete(string $tenantId, array $input): array
|
||||
{
|
||||
return $this->cmd($tenantId, 'CRON_DELETE', 'cron_delete_', $input);
|
||||
}
|
||||
|
||||
public function firewallList(string $tenantId, array $input): array
|
||||
{
|
||||
return $this->cmd($tenantId, 'FIREWALL_RULE_LIST', 'fw_list_', $input);
|
||||
}
|
||||
|
||||
public function firewallAdd(string $tenantId, array $input): array
|
||||
{
|
||||
return $this->cmd($tenantId, 'FIREWALL_RULE_ADD', 'fw_add_', $input);
|
||||
}
|
||||
|
||||
public function firewallDelete(string $tenantId, array $input): array
|
||||
{
|
||||
return $this->cmd($tenantId, 'FIREWALL_RULE_DELETE', 'fw_delete_', $input);
|
||||
}
|
||||
|
||||
public function backupRun(string $tenantId, array $input): array
|
||||
{
|
||||
return $this->cmd($tenantId, 'BACKUP_RUN', 'backup_run_', $input);
|
||||
}
|
||||
|
||||
public function backupRestore(string $tenantId, array $input): array
|
||||
{
|
||||
return $this->cmd($tenantId, 'BACKUP_RESTORE', 'backup_restore_', $input);
|
||||
}
|
||||
|
||||
private function cmd(string $tenantId, string $type, string $prefix, array $input): array
|
||||
{
|
||||
return [
|
||||
'tenant_id' => $tenantId,
|
||||
'type' => $type,
|
||||
'idempotency_key' => $input['idempotency_key'] ?? uniqid($prefix, true),
|
||||
'args' => $input,
|
||||
];
|
||||
}
|
||||
}
|
||||
26
panel-api/app/Modules/Ops/OpsWorkflowService.php
Normal file
26
panel-api/app/Modules/Ops/OpsWorkflowService.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\Ops;
|
||||
|
||||
use App\Modules\Jobs\CommandOrchestrator;
|
||||
|
||||
class OpsWorkflowService
|
||||
{
|
||||
public function __construct(
|
||||
private readonly CommandOrchestrator $orchestrator,
|
||||
private readonly OpsCommandFactory $commands
|
||||
) {
|
||||
}
|
||||
|
||||
public function fileList(string $tenantId, array $input): array { return $this->orchestrator->dispatch($this->commands->fileList($tenantId, $input)); }
|
||||
public function fileRead(string $tenantId, array $input): array { return $this->orchestrator->dispatch($this->commands->fileRead($tenantId, $input)); }
|
||||
public function fileWrite(string $tenantId, array $input): array { return $this->orchestrator->dispatch($this->commands->fileWrite($tenantId, $input)); }
|
||||
public function cronList(string $tenantId, array $input): array { return $this->orchestrator->dispatch($this->commands->cronList($tenantId, $input)); }
|
||||
public function cronCreate(string $tenantId, array $input): array { return $this->orchestrator->dispatch($this->commands->cronCreate($tenantId, $input)); }
|
||||
public function cronDelete(string $tenantId, array $input): array { return $this->orchestrator->dispatch($this->commands->cronDelete($tenantId, $input)); }
|
||||
public function firewallList(string $tenantId, array $input): array { return $this->orchestrator->dispatch($this->commands->firewallList($tenantId, $input)); }
|
||||
public function firewallAdd(string $tenantId, array $input): array { return $this->orchestrator->dispatch($this->commands->firewallAdd($tenantId, $input)); }
|
||||
public function firewallDelete(string $tenantId, array $input): array { return $this->orchestrator->dispatch($this->commands->firewallDelete($tenantId, $input)); }
|
||||
public function backupRun(string $tenantId, array $input): array { return $this->orchestrator->dispatch($this->commands->backupRun($tenantId, $input)); }
|
||||
public function backupRestore(string $tenantId, array $input): array { return $this->orchestrator->dispatch($this->commands->backupRestore($tenantId, $input)); }
|
||||
}
|
||||
29
panel-api/app/Modules/PublicApi/PublicApiController.php
Normal file
29
panel-api/app/Modules/PublicApi/PublicApiController.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\PublicApi;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller;
|
||||
|
||||
class PublicApiController extends Controller
|
||||
{
|
||||
public function __construct(private readonly PublicTokenService $tokens)
|
||||
{
|
||||
}
|
||||
|
||||
public function issueToken(Request $request): JsonResponse
|
||||
{
|
||||
return response()->json([
|
||||
'data' => $this->tokens->issue($request->all()),
|
||||
], 201);
|
||||
}
|
||||
|
||||
public function introspect(Request $request): JsonResponse
|
||||
{
|
||||
$token = (string) $request->input('token', '');
|
||||
return response()->json([
|
||||
'data' => $this->tokens->introspect($token),
|
||||
]);
|
||||
}
|
||||
}
|
||||
23
panel-api/app/Modules/PublicApi/PublicTokenService.php
Normal file
23
panel-api/app/Modules/PublicApi/PublicTokenService.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\PublicApi;
|
||||
|
||||
class PublicTokenService
|
||||
{
|
||||
public function issue(array $input): array
|
||||
{
|
||||
return [
|
||||
'token' => 'public-token-placeholder',
|
||||
'scopes' => $input['scopes'] ?? [],
|
||||
'expires_in' => 3600,
|
||||
];
|
||||
}
|
||||
|
||||
public function introspect(string $token): array
|
||||
{
|
||||
return [
|
||||
'active' => $token !== '',
|
||||
'scopes' => [],
|
||||
];
|
||||
}
|
||||
}
|
||||
49
panel-api/app/Modules/Rbac/RbacController.php
Normal file
49
panel-api/app/Modules/Rbac/RbacController.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\Rbac;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller;
|
||||
|
||||
class RbacController extends Controller
|
||||
{
|
||||
public function __construct(private readonly ScopeEvaluator $evaluator)
|
||||
{
|
||||
}
|
||||
|
||||
public function roles(): JsonResponse
|
||||
{
|
||||
return response()->json(['data' => []]);
|
||||
}
|
||||
|
||||
public function createRole(Request $request): JsonResponse
|
||||
{
|
||||
return response()->json(['data' => ['status' => 'created']], 201);
|
||||
}
|
||||
|
||||
public function attachPermissions(Request $request, string $role): JsonResponse
|
||||
{
|
||||
return response()->json(['data' => ['role_id' => $role, 'status' => 'updated']]);
|
||||
}
|
||||
|
||||
public function assignRoles(Request $request, string $user): JsonResponse
|
||||
{
|
||||
return response()->json(['data' => ['user_id' => $user, 'status' => 'updated']]);
|
||||
}
|
||||
|
||||
public function checkAccess(Request $request): JsonResponse
|
||||
{
|
||||
$payload = $request->all();
|
||||
$allowed = $this->evaluator->isAllowed(
|
||||
$payload['grants'] ?? [],
|
||||
(string) ($payload['action'] ?? ''),
|
||||
(string) ($payload['resource_type'] ?? ''),
|
||||
isset($payload['resource_id']) ? (string) $payload['resource_id'] : null
|
||||
);
|
||||
|
||||
return response()->json([
|
||||
'data' => ['allowed' => $allowed],
|
||||
]);
|
||||
}
|
||||
}
|
||||
30
panel-api/app/Modules/Rbac/ScopeEvaluator.php
Normal file
30
panel-api/app/Modules/Rbac/ScopeEvaluator.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\Rbac;
|
||||
|
||||
class ScopeEvaluator
|
||||
{
|
||||
public function isAllowed(array $grants, string $action, string $resourceType, ?string $resourceId = null): bool
|
||||
{
|
||||
foreach ($grants as $grant) {
|
||||
$grantAction = $grant['action'] ?? null;
|
||||
$grantResourceType = $grant['resource_type'] ?? null;
|
||||
$grantResourceId = $grant['resource_id'] ?? null;
|
||||
$effect = $grant['effect'] ?? 'allow';
|
||||
|
||||
$matches = ($grantAction === '*' || $grantAction === $action)
|
||||
&& ($grantResourceType === '*' || $grantResourceType === $resourceType)
|
||||
&& ($grantResourceId === null || $grantResourceId === $resourceId);
|
||||
|
||||
if ($matches && $effect === 'deny') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($matches && $effect === 'allow') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
16
panel-api/app/Modules/SaaS/BillingHooksService.php
Normal file
16
panel-api/app/Modules/SaaS/BillingHooksService.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\SaaS;
|
||||
|
||||
class BillingHooksService
|
||||
{
|
||||
public function emitUsageEvent(string $tenantId, string $eventType, array $payload): array
|
||||
{
|
||||
return [
|
||||
'tenant_id' => $tenantId,
|
||||
'event_type' => $eventType,
|
||||
'status' => 'queued',
|
||||
'payload' => $payload,
|
||||
];
|
||||
}
|
||||
}
|
||||
18
panel-api/app/Modules/SaaS/QuotaService.php
Normal file
18
panel-api/app/Modules/SaaS/QuotaService.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\SaaS;
|
||||
|
||||
class QuotaService
|
||||
{
|
||||
public function check(string $tenantId, string $resource, int $requested = 1): array
|
||||
{
|
||||
return [
|
||||
'tenant_id' => $tenantId,
|
||||
'resource' => $resource,
|
||||
'requested' => $requested,
|
||||
'allowed' => true,
|
||||
'limit' => null,
|
||||
'current_usage' => null,
|
||||
];
|
||||
}
|
||||
}
|
||||
38
panel-api/app/Modules/SaaS/SaaSController.php
Normal file
38
panel-api/app/Modules/SaaS/SaaSController.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\SaaS;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller;
|
||||
|
||||
class SaaSController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
private readonly QuotaService $quota,
|
||||
private readonly BillingHooksService $billing
|
||||
) {
|
||||
}
|
||||
|
||||
public function checkQuota(Request $request): JsonResponse
|
||||
{
|
||||
$tenantId = (string) $request->attributes->get('tenant_id', '');
|
||||
$resource = (string) $request->input('resource', '');
|
||||
$requested = (int) $request->input('requested', 1);
|
||||
|
||||
return response()->json([
|
||||
'data' => $this->quota->check($tenantId, $resource, $requested),
|
||||
]);
|
||||
}
|
||||
|
||||
public function usageEvent(Request $request): JsonResponse
|
||||
{
|
||||
$tenantId = (string) $request->attributes->get('tenant_id', '');
|
||||
$eventType = (string) $request->input('event_type', 'generic');
|
||||
$payload = (array) $request->input('payload', []);
|
||||
|
||||
return response()->json([
|
||||
'data' => $this->billing->emitUsageEvent($tenantId, $eventType, $payload),
|
||||
], 202);
|
||||
}
|
||||
}
|
||||
56
panel-api/app/Modules/Server/ServerController.php
Normal file
56
panel-api/app/Modules/Server/ServerController.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\Server;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller;
|
||||
|
||||
class ServerController extends Controller
|
||||
{
|
||||
public function __construct(private readonly ServerRepository $servers)
|
||||
{
|
||||
}
|
||||
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
$tenantId = (string) $request->attributes->get('tenant_id', '');
|
||||
return response()->json([
|
||||
'data' => $this->servers->listByTenant($tenantId),
|
||||
'meta' => ['tenant_id' => $tenantId],
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(Request $request): JsonResponse
|
||||
{
|
||||
$tenantId = (string) $request->attributes->get('tenant_id', '');
|
||||
$server = $this->servers->create([
|
||||
'tenant_id' => $tenantId,
|
||||
'name' => (string) $request->input('name', ''),
|
||||
'id' => (string) $request->input('id', ''),
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'data' => $server,
|
||||
], 201);
|
||||
}
|
||||
|
||||
public function show(string $server): JsonResponse
|
||||
{
|
||||
return response()->json([
|
||||
'data' => ['id' => $server],
|
||||
]);
|
||||
}
|
||||
|
||||
public function update(Request $request, string $server): JsonResponse
|
||||
{
|
||||
return response()->json([
|
||||
'data' => ['id' => $server, 'status' => 'updated'],
|
||||
]);
|
||||
}
|
||||
|
||||
public function destroy(string $server): JsonResponse
|
||||
{
|
||||
return response()->json([], 204);
|
||||
}
|
||||
}
|
||||
25
panel-api/app/Modules/Server/ServerRepository.php
Normal file
25
panel-api/app/Modules/Server/ServerRepository.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\Server;
|
||||
|
||||
class ServerRepository
|
||||
{
|
||||
/**
|
||||
* Placeholder persistence adapter.
|
||||
* Replace with Eloquent model queries in full Laravel bootstrap.
|
||||
*/
|
||||
public function listByTenant(string $tenantId): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function create(array $attributes): array
|
||||
{
|
||||
return [
|
||||
'id' => $attributes['id'] ?? null,
|
||||
'tenant_id' => $attributes['tenant_id'] ?? null,
|
||||
'name' => $attributes['name'] ?? null,
|
||||
'status' => 'provisioning',
|
||||
];
|
||||
}
|
||||
}
|
||||
107
panel-api/app/Modules/Site/HostingCommandFactory.php
Normal file
107
panel-api/app/Modules/Site/HostingCommandFactory.php
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\Site;
|
||||
|
||||
class HostingCommandFactory
|
||||
{
|
||||
public function buildCreateSite(string $tenantId, array $input, string $webserver): array
|
||||
{
|
||||
return [
|
||||
'tenant_id' => $tenantId,
|
||||
'type' => 'SITE_CREATE',
|
||||
'idempotency_key' => $input['idempotency_key'] ?? uniqid('site_create_', true),
|
||||
'args' => [
|
||||
'server_id' => $input['server_id'] ?? null,
|
||||
'site_name' => $input['site_name'] ?? null,
|
||||
'domain' => $input['domain'] ?? null,
|
||||
'root_path' => $input['root_path'] ?? null,
|
||||
'webserver' => $webserver,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function buildUpdateSite(string $tenantId, string $siteId, array $input): array
|
||||
{
|
||||
return [
|
||||
'tenant_id' => $tenantId,
|
||||
'type' => 'SITE_UPDATE',
|
||||
'idempotency_key' => $input['idempotency_key'] ?? uniqid('site_update_', true),
|
||||
'args' => [
|
||||
'site_id' => $siteId,
|
||||
'server_id' => $input['server_id'] ?? null,
|
||||
'changes' => $input['changes'] ?? [],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function buildDeleteSite(string $tenantId, string $siteId, array $input): array
|
||||
{
|
||||
return [
|
||||
'tenant_id' => $tenantId,
|
||||
'type' => 'SITE_DELETE',
|
||||
'idempotency_key' => $input['idempotency_key'] ?? uniqid('site_delete_', true),
|
||||
'args' => [
|
||||
'site_id' => $siteId,
|
||||
'server_id' => $input['server_id'] ?? null,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function buildAddDomain(string $tenantId, string $siteId, array $input): array
|
||||
{
|
||||
return [
|
||||
'tenant_id' => $tenantId,
|
||||
'type' => 'DOMAIN_ADD',
|
||||
'idempotency_key' => $input['idempotency_key'] ?? uniqid('domain_add_', true),
|
||||
'args' => [
|
||||
'site_id' => $siteId,
|
||||
'server_id' => $input['server_id'] ?? null,
|
||||
'domain' => $input['domain'] ?? null,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function buildRemoveDomain(string $tenantId, string $siteId, string $domainId, array $input): array
|
||||
{
|
||||
return [
|
||||
'tenant_id' => $tenantId,
|
||||
'type' => 'DOMAIN_REMOVE',
|
||||
'idempotency_key' => $input['idempotency_key'] ?? uniqid('domain_remove_', true),
|
||||
'args' => [
|
||||
'site_id' => $siteId,
|
||||
'domain_id' => $domainId,
|
||||
'server_id' => $input['server_id'] ?? null,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function buildIssueSsl(string $tenantId, array $input): array
|
||||
{
|
||||
return [
|
||||
'tenant_id' => $tenantId,
|
||||
'type' => 'SSL_ISSUE',
|
||||
'idempotency_key' => $input['idempotency_key'] ?? uniqid('ssl_issue_', true),
|
||||
'args' => $input,
|
||||
];
|
||||
}
|
||||
|
||||
public function buildApplySsl(string $tenantId, array $input): array
|
||||
{
|
||||
return [
|
||||
'tenant_id' => $tenantId,
|
||||
'type' => 'SSL_APPLY',
|
||||
'idempotency_key' => $input['idempotency_key'] ?? uniqid('ssl_apply_', true),
|
||||
'args' => $input,
|
||||
];
|
||||
}
|
||||
|
||||
public function buildRenewSsl(string $tenantId, array $input): array
|
||||
{
|
||||
return [
|
||||
'tenant_id' => $tenantId,
|
||||
'type' => 'SSL_RENEW',
|
||||
'idempotency_key' => $input['idempotency_key'] ?? uniqid('ssl_renew_', true),
|
||||
'args' => $input,
|
||||
];
|
||||
}
|
||||
}
|
||||
53
panel-api/app/Modules/Site/SiteController.php
Normal file
53
panel-api/app/Modules/Site/SiteController.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\Site;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller;
|
||||
|
||||
class SiteController extends Controller
|
||||
{
|
||||
public function __construct(private readonly SiteWorkflowService $workflow)
|
||||
{
|
||||
}
|
||||
|
||||
public function index(): JsonResponse { return response()->json(['data' => []]); }
|
||||
|
||||
public function store(Request $request): JsonResponse
|
||||
{
|
||||
$tenantId = (string) $request->attributes->get('tenant_id', '');
|
||||
$result = $this->workflow->createSite($tenantId, $request->all());
|
||||
return response()->json(['data' => $result], 202);
|
||||
}
|
||||
|
||||
public function show(string $site): JsonResponse { return response()->json(['data' => ['id' => $site]]); }
|
||||
|
||||
public function update(Request $request, string $site): JsonResponse
|
||||
{
|
||||
$tenantId = (string) $request->attributes->get('tenant_id', '');
|
||||
$result = $this->workflow->updateSite($tenantId, $site, $request->all());
|
||||
return response()->json(['data' => $result], 202);
|
||||
}
|
||||
|
||||
public function destroy(Request $request, string $site): JsonResponse
|
||||
{
|
||||
$tenantId = (string) $request->attributes->get('tenant_id', '');
|
||||
$result = $this->workflow->deleteSite($tenantId, $site, $request->all());
|
||||
return response()->json(['data' => $result], 202);
|
||||
}
|
||||
|
||||
public function addDomain(Request $request, string $site): JsonResponse
|
||||
{
|
||||
$tenantId = (string) $request->attributes->get('tenant_id', '');
|
||||
$result = $this->workflow->addDomain($tenantId, $site, $request->all());
|
||||
return response()->json(['data' => $result], 202);
|
||||
}
|
||||
|
||||
public function removeDomain(Request $request, string $site, string $domain): JsonResponse
|
||||
{
|
||||
$tenantId = (string) $request->attributes->get('tenant_id', '');
|
||||
$result = $this->workflow->removeDomain($tenantId, $site, $domain, $request->all());
|
||||
return response()->json(['data' => $result], 202);
|
||||
}
|
||||
}
|
||||
69
panel-api/app/Modules/Site/SiteWorkflowService.php
Normal file
69
panel-api/app/Modules/Site/SiteWorkflowService.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\Site;
|
||||
|
||||
use App\Modules\Jobs\CommandOrchestrator;
|
||||
use InvalidArgumentException;
|
||||
|
||||
class SiteWorkflowService
|
||||
{
|
||||
public function __construct(
|
||||
private readonly CommandOrchestrator $orchestrator,
|
||||
private readonly HostingCommandFactory $commandFactory,
|
||||
private readonly WebserverProfileResolver $webserverResolver
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
public function createSite(string $tenantId, array $input): array
|
||||
{
|
||||
$webserver = $this->webserverResolver->normalize((string) ($input['webserver'] ?? 'nginx'));
|
||||
$command = $this->commandFactory->buildCreateSite($tenantId, $input, $webserver);
|
||||
return $this->orchestrator->dispatch($command);
|
||||
}
|
||||
|
||||
public function updateSite(string $tenantId, string $siteId, array $input): array
|
||||
{
|
||||
$command = $this->commandFactory->buildUpdateSite($tenantId, $siteId, $input);
|
||||
return $this->orchestrator->dispatch($command);
|
||||
}
|
||||
|
||||
public function deleteSite(string $tenantId, string $siteId, array $input = []): array
|
||||
{
|
||||
$command = $this->commandFactory->buildDeleteSite($tenantId, $siteId, $input);
|
||||
return $this->orchestrator->dispatch($command);
|
||||
}
|
||||
|
||||
public function addDomain(string $tenantId, string $siteId, array $input): array
|
||||
{
|
||||
if (empty($input['domain'])) {
|
||||
throw new InvalidArgumentException('Domain is required');
|
||||
}
|
||||
$command = $this->commandFactory->buildAddDomain($tenantId, $siteId, $input);
|
||||
return $this->orchestrator->dispatch($command);
|
||||
}
|
||||
|
||||
public function removeDomain(string $tenantId, string $siteId, string $domainId, array $input = []): array
|
||||
{
|
||||
$command = $this->commandFactory->buildRemoveDomain($tenantId, $siteId, $domainId, $input);
|
||||
return $this->orchestrator->dispatch($command);
|
||||
}
|
||||
|
||||
public function issueSsl(string $tenantId, array $input): array
|
||||
{
|
||||
$command = $this->commandFactory->buildIssueSsl($tenantId, $input);
|
||||
return $this->orchestrator->dispatch($command);
|
||||
}
|
||||
|
||||
public function applySsl(string $tenantId, array $input): array
|
||||
{
|
||||
$command = $this->commandFactory->buildApplySsl($tenantId, $input);
|
||||
return $this->orchestrator->dispatch($command);
|
||||
}
|
||||
|
||||
public function renewSsl(string $tenantId, array $input): array
|
||||
{
|
||||
$command = $this->commandFactory->buildRenewSsl($tenantId, $input);
|
||||
return $this->orchestrator->dispatch($command);
|
||||
}
|
||||
}
|
||||
23
panel-api/app/Modules/Site/WebserverProfileResolver.php
Normal file
23
panel-api/app/Modules/Site/WebserverProfileResolver.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\Site;
|
||||
|
||||
use InvalidArgumentException;
|
||||
|
||||
class WebserverProfileResolver
|
||||
{
|
||||
/**
|
||||
* Normalize webserver name to an allowed adapter key.
|
||||
*/
|
||||
public function normalize(string $webserver): string
|
||||
{
|
||||
$normalized = strtolower(trim($webserver));
|
||||
|
||||
return match ($normalized) {
|
||||
'nginx' => 'nginx',
|
||||
'apache', 'httpd' => 'apache',
|
||||
'openlitespeed', 'ols' => 'openlitespeed',
|
||||
default => throw new InvalidArgumentException('Unsupported webserver profile'),
|
||||
};
|
||||
}
|
||||
}
|
||||
36
panel-api/app/Modules/Ssl/SslController.php
Normal file
36
panel-api/app/Modules/Ssl/SslController.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\Ssl;
|
||||
|
||||
use App\Modules\Site\SiteWorkflowService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller;
|
||||
|
||||
class SslController extends Controller
|
||||
{
|
||||
public function __construct(private readonly SiteWorkflowService $workflow)
|
||||
{
|
||||
}
|
||||
|
||||
public function issue(Request $request): JsonResponse
|
||||
{
|
||||
$tenantId = (string) $request->attributes->get('tenant_id', '');
|
||||
$result = $this->workflow->issueSsl($tenantId, $request->all());
|
||||
return response()->json(['data' => $result], 202);
|
||||
}
|
||||
|
||||
public function apply(Request $request): JsonResponse
|
||||
{
|
||||
$tenantId = (string) $request->attributes->get('tenant_id', '');
|
||||
$result = $this->workflow->applySsl($tenantId, $request->all());
|
||||
return response()->json(['data' => $result], 202);
|
||||
}
|
||||
|
||||
public function renew(Request $request): JsonResponse
|
||||
{
|
||||
$tenantId = (string) $request->attributes->get('tenant_id', '');
|
||||
$result = $this->workflow->renewSsl($tenantId, $request->all());
|
||||
return response()->json(['data' => $result], 202);
|
||||
}
|
||||
}
|
||||
25
panel-api/app/Modules/Tenant/TenantController.php
Normal file
25
panel-api/app/Modules/Tenant/TenantController.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\Tenant;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller;
|
||||
|
||||
class TenantController extends Controller
|
||||
{
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
return response()->json(['data' => []]);
|
||||
}
|
||||
|
||||
public function store(Request $request): JsonResponse
|
||||
{
|
||||
return response()->json(['data' => ['status' => 'created']], 201);
|
||||
}
|
||||
|
||||
public function show(string $tenant): JsonResponse
|
||||
{
|
||||
return response()->json(['data' => ['id' => $tenant]]);
|
||||
}
|
||||
}
|
||||
35
panel-api/app/Modules/Webhook/WebhookController.php
Normal file
35
panel-api/app/Modules/Webhook/WebhookController.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\Webhook;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller;
|
||||
|
||||
class WebhookController extends Controller
|
||||
{
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
return response()->json(['data' => ['items' => []]]);
|
||||
}
|
||||
|
||||
public function store(Request $request): JsonResponse
|
||||
{
|
||||
return response()->json([
|
||||
'data' => [
|
||||
'status' => 'created',
|
||||
'endpoint' => $request->all(),
|
||||
],
|
||||
], 201);
|
||||
}
|
||||
|
||||
public function testDelivery(Request $request): JsonResponse
|
||||
{
|
||||
return response()->json([
|
||||
'data' => [
|
||||
'status' => 'queued',
|
||||
'target' => $request->input('url'),
|
||||
],
|
||||
], 202);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user