where('is_server', false) ->orderBy('domain') ->get() ->map(fn($d) => $this->format($d)); return response()->json(['data' => $domains]); } public function show(int $id): JsonResponse { $domain = Domain::where('is_system', false)->where('is_server', false)->findOrFail($id); return response()->json(['data' => $this->format($domain)]); } public function store(Request $request): JsonResponse { $request->tokenCan('domains:write') || abort(403, 'Scope domains:write required.'); if ($request->isSandbox ?? false) { return response()->json(['data' => array_merge(['id' => 9999], $request->only('domain')), 'sandbox' => true], 201); } $data = $request->validate([ 'domain' => 'required|string|max:253|unique:domains,domain', 'description' => 'nullable|string|max:255', 'max_aliases' => 'nullable|integer|min:0', 'max_mailboxes' => 'nullable|integer|min:0', 'default_quota_mb' => 'nullable|integer|min:0', ]); $domain = Domain::create($data); if (!($request->isSandbox ?? false)) { app(WebhookService::class)->dispatch('domain.created', $this->format($domain)); } return response()->json(['data' => $this->format($domain)], 201); } public function destroy(Request $request, int $id): JsonResponse { $request->tokenCan('domains:write') || abort(403, 'Scope domains:write required.'); $domain = Domain::where('is_system', false)->where('is_server', false)->findOrFail($id); if ($request->isSandbox ?? false) { return response()->json(['sandbox' => true], 204); } $formatted = $this->format($domain); $domain->delete(); app(WebhookService::class)->dispatch('domain.deleted', $formatted); return response()->json(null, 204); } private function format(Domain $d): array { return [ 'id' => $d->id, 'domain' => $d->domain, 'description' => $d->description, 'is_active' => $d->is_active, 'max_aliases' => $d->max_aliases, 'max_mailboxes' => $d->max_mailboxes, 'default_quota_mb' => $d->default_quota_mb, 'created_at' => $d->created_at->toIso8601String(), ]; } }